【Linux】 gcc 、动态库和静态库,程序是如何链接的
创始人
2024-05-10 19:51:49
0

文章目录

  • 前言
  • 一、gcc 是什么?
  • 二、使用步骤
    • 1.预编译
    • 2.编译
    • 3.汇编
    • 4.链接
  • 三、动静态库
    • 1.概念
    • 2.区别


前言

  在Linux环境下,除了学好编辑器 vim 的使用,还需要学会C语言的编译器 gcc 的功能,否则代码无法翻译成可执行程序。本文将介绍 gcc 的常规使用方法,以及一个C语言程序,在链接的时候发生了什么。


提示:以下是本篇文章正文内容

一、gcc 是什么?

  GCC原名为GNU C语言编译器(GNU C Compiler),只能处理C语言。但其很快扩展,变得可处理C++,后来又扩展为能够支持更多编程语言,如Java、Go等等。其作用就是,将一个C语言文件,执行翻译的过程,从 .c 文件变成 .exe 文件,这样就可以执行( .c 文件只存放代码,相当于记事本)。可以看这篇文章,了解翻译的过程:你知道.c文件是如何变成.exe文件的吗。

  翻译过程可以大致分为:预编译、编译、汇编、链接。在链接期间,涉及到链接器的一些小知识,本文也会讲解。


二、使用步骤

1.预编译

  在 Linux 中输入指令如下,其作用主要包括:宏定义,文件包含,条件编译,去注释等

gcc -E test.c -o test.i

  • 选项“-E”,该选项的作用是让 gcc 在预编译结束后停止翻译过程。
  • 选项“-o”是指目标文件(所以它后面跟的是想要生成的文件名), “.i” 文件为已经过预处理的C原始程序。

  如下图:
请添加图片描述

2.编译

  在 Linux 中输入指令如下,在这个阶段中:gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言

gcc -S test.i -o test.s

  • 选项“-S”,该选项只进行编译而不进行汇编,生成汇编代码

  如下图:
请添加图片描述

3.汇编

  在 Linux 中输入指令如下,其作用是:把编译阶段生成的“.s”文件转成目标文件

gcc -c test.s -o test.o

  • 选项“-c”,该选项将汇编代码已转化为“.o”的二进制目标代码。

  如下图:
请添加图片描述

4.链接

  在 Linux 中输入指令如下,其作用是:合并符号表、合并段表等等

gcc test.o -o test

  如下图,可以很明显地看到,生成了一个可执行文件test。

请添加图片描述
  当然了,上面只是为了理解翻译过程,但是其实可以一步到位生成可执行文件,那就是 gcc test.c -o test 可以将 test.c 文件生成 可执行文件 test。 当然,最简单的做法是 gcc test.c 但是这样无法控制生成的文件名,其默认目标文件名是 a.out 。


三、动静态库

1.概念

  在上文内容其实涉及到一个重要概念:函数库。
  库分为两种:静态库和动态库。其命名规则是:前缀+文件名+后缀。如下图,静态库后缀是.a ,动态库后缀是 .so,其前缀都是 lib 。

静态库:libXXXXX.a
动态库:libXXXXX.so

  我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实现“printf”函数的呢?
  实际上是:Linux系统把这些函数实现都被做到名为 libc.so.6 (Linux默认使用动态库)的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用。

2.区别

  我们先看到动态库:他是专门让编译器,对用户的程序进行动态链接的。
  动态链接:链接的时候,找到动态库,拷贝动态库中的我所需要的代码的地址到我自己的可执行程序中相关的位置。
  动态链接成功:我们的程序,还是依赖动态库,一旦动态库缺失,我们的程序便无法运行!
  我们根据上面使用 gcc 的示例文件test,如下,先执行 ldd test,查看其依赖库,是 libc.so.6 此时就可以看出是依赖动态库了;再执行 file test,查看其信息可得,确实Linux 默认使用动态库。
在这里插入图片描述


  静态库是专门让编译器,对用户的程序进行静态链接的。
  静态链接:链接的时候,找到静态库,拷贝静态库中的我所需要的代码到我自己的可执行程序中。
  静态链接成功:我们的程序,不依赖任何库,自己就可以独立运行
  如下,我们使用静态链接的方法生成 test-static 文件,从两个箭头指向的地方,可以明显看出,test-static 比 test 大了百倍,其仅仅是一个打印 Hello World 的程序生成,区别如此之大。再用 ldd 指令查看,不是动态的,file 指令查看详细信息,静态链接。(注意,编译此程序需要用到libc库文件,而系统中无法找到libc的静态库文件,需要下载安装:sudo yum install -y glibc-static)
在这里插入图片描述

  根据以上内容,可以得出结论:

静态库:因为自身拷贝的问题,比较浪费空间。
动态库:因为可以做到被大家共享方法,所以真正的实现永远都是在库中,程序内部只有地址,比较节省空间。

   Linux默认使用的是动态链接和动态库!如果进行大型项目开发,其文件非常巨大,如果使用静态库,其所消耗空间资源比动态库要多上接近一百倍,所以使用动态库更好一些。


相关内容

热门资讯

捷豹安卓系统车载,捷豹安卓系统... 哇,你有没有想过,当你的手机和汽车融为一体,会是怎样的体验呢?想象你正驾驶着你的捷豹,车窗外的风景如...
安卓1到10系统,安卓1.0至... 你有没有想过,手机里的安卓系统就像是我们生活中的好朋友,从青涩的少年成长为稳重的青年呢?从安卓1.0...
安卓8.0停用系统应用,提升使... 你知道吗?最近安卓系统又来了一次大动作,那就是安卓8.0系统开始停用一些系统应用了。这可真是让人有点...
安卓系统修改mtu值,轻松提升... 你有没有想过,你的安卓手机其实是个小小的电脑呢?它里面藏着许多可以自定义的秘密功能,就像修改MTU值...
安卓平板改window系统,探... 你有没有想过,你的安卓平板其实可以摇身一变,变成一个Windows系统的电脑呢?没错,就是那种可以运...
时空猎人安卓苹果系统,探索无尽... 你知道吗?最近在手机游戏圈里,有一款叫做《时空猎人》的游戏可是火得一塌糊涂呢!不管是安卓用户还是苹果...
安卓9.0系统的电视,新一代电... 亲爱的读者们,你是否也像我一样,对科技新玩意儿充满好奇?今天,我要和你聊聊一个让人眼前一亮的话题——...
小pc安装安卓系统,轻松安装安... 你有没有想过,你的小PC也能变身成为安卓系统的超级玩家呢?没错,就是那个平时默默无闻的小家伙,现在也...
高通备份安卓系统,全方位数据安... 你知道吗?在这个科技飞速发展的时代,手机备份可是个不得不提的话题。尤其是对于安卓用户来说,选择一个靠...
谷歌安卓系统有多少,从诞生到全... 你有没有想过,那个无处不在的谷歌安卓系统,究竟在全球有多少用户呢?它就像一个神秘的数字,每天都在悄悄...
fc黄金传说安卓系统,畅享复古... 你有没有听说最近安卓系统上的一款超酷的游戏——《FC黄金传说》?这款游戏可是让不少玩家都沉迷其中,今...
变小的我安卓系统,安卓系统演变... 你有没有发现,最近你的手机好像变轻了?没错,说的就是你,那个陪伴你多年的安卓系统。它悄无声息地进行了...
vivo安卓系统小彩蛋,体验科... 你知道吗?在vivo的安卓系统中,竟然隐藏着一些超有趣的小彩蛋!这些小彩蛋就像是在手机里埋下的宝藏,...
安卓系统如何强制重启,安卓系统... 手机突然卡壳了,是不是又该给它来个“大保健”了?没错,今天就来聊聊安卓系统如何强制重启。别小看这个看...
全民飞行团安卓系统,体验指尖上... 你知道吗?最近在手机游戏圈里,有个叫做“全民飞行团”的新星正在闪耀!这款游戏不仅吸引了无数玩家的目光...
安卓鸿蒙系统壁纸软件,壁纸软件... 亲爱的手机控们,你是否厌倦了单调的壁纸?想要给你的安卓手机换上充满科技感的鸿蒙系统风格壁纸?那就跟我...
安卓系统ram重新分区,提升系... 你有没有发现,你的安卓手机最近有点儿卡呢?别急,别急,今天就来给你揭秘如何给安卓系统的RAM来个重新...
迷你退出安卓系统了吗,转型新篇... 最近有没有发现你的手机上那个可爱的迷你退出图标突然不见了?别急,让我来给你揭秘迷你退出安卓系统了吗的...
华为优先使用安卓系统,打造自主... 你知道吗?最近科技圈里有个大动作,那就是华为宣布优先使用安卓系统。这可不是一个简单的决定,它背后可是...
安卓系统隐藏了设置,隐藏设置功... 你知道吗?安卓系统这个大宝藏里,竟然隐藏着一些不为人知的设置!是不是听起来就有点小激动呢?别急,今天...