[Linux] gcc/g++简单使用+动静态库

一、 gcc/g++的安装使用

gcc/g++的区别和联系 前面已经单独讲过了,那它的实际使用又是怎么样的呢?
首先我们需要安装一下gcc和g++:

sudo yum install -y gcc
sudo yum install -y gcc-c++ libstdc+±devel

这里还有一些gcc和g++常用的选项(常用的也就那么几个):

-E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
-S 编译到汇编语言不进行汇编和链接
-c 编译到目标代码
-o 文件输出到 文件
-static 此选项对生成的文件采用静态链接
-g 生成调试信息。GNU 调试器可利用该信息。
-shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.
-O0
-O1
-O2
-O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
-w 不生成任何警告信息。
-Wall 生成所有警告信息

二、程序的从无到有

我们都知道一个程序从无到有再到成功运行是需要经过编辑、编译、链接再运行的。这里我们将对编译、链接进行讲解。(编译又可以细分为预处理、编译、汇编

预处理

预处理功能主要包括宏定义,文件包含,条件编译,去注释等。
实例: gcc –E test.c –o test.i

在这里插入图片描述

选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。
选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序。

编译(生成汇编)

在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。该选项只进行编译而不进行汇编,生成汇编代码。我们可以直接使用在预处理后生成的.i文件来进行操作。
实例: gcc –S test.i –o test.s

在这里插入图片描述

汇编(生成机器可识别代码)

汇编阶段是把编译阶段生成的“.s”文件转成.o的目标文件(二进制)。
实例: gcc –c test.s –o test.o
在这里插入图片描述

链接 (生成可执行文件或库文件)

在成功编译之后,就进入了链接阶段,将.o的目标文件变成可执行文件(默认生成的文件名叫a.out,我们可以自己指定文件名)
实例: gcc test.o –o test(将生成的可执行文件名指定为test)
在这里插入图片描述

我们平常都是直接gcc xxx.c 就可以生成名为xxx.c的c程序的可执行文件,可以用-o来指定文件名。

再运行可执行程序,就可以看到预期的效果了。

在这里插入图片描述

三、动静态库

我们学习c语言时第一个最简单c程序就是用 printf 输出 hello world ,而我们并没有实现这个printf函数,那它是怎么输出内容的呢?

其实是因为这些不用我们自己实现而又能直接被我们调用的函数都已经被实现并封装到名为libc.so.6的库文件中去了,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用。其实链接的本质就是如何将调用的库函数和标准的库关联起来。

动态库和动态链接
gcc/g++默认是动态链接

要注意动态库在动态链接时并没有把库文件的代码加载到到可执行文件中,而是将动态库中需要用到的代码的地址加载到了符号表中,在连接的时候再去符号表中取出地址,通过地址找到动态库中的相应代码,从而链接成功,这样可以节省系统的开销。但这样程序是依赖于动态库的,如果动态库缺失,那程序将无法被执行。 动态库一般后缀名为“so”,如前面所述的libc.so.6 就是动态库。gcc 在编译时默认会链接动态库。完成了链接之后,gcc 就可以生成可执行文件。

在这里插入图片描述
上图显示该文件采用的链接方式是动态链接,使用的是共享库,如果我们想要查看这个文件依赖的是哪个库的话就可以使用下面的这个指令:ldd mytest

在这里插入图片描述查看结果显示,依赖的是 libc.so.6 ,那这又是什么?
在这里插入图片描述libc.so.6是一个链接文件,链接了libc-22.17.so,我们可以简单的理解链接文件可以快速找到被链接的文件。

在这里插入图片描述

这里我们要知道的一点就是动态库的形式为:libXXXXX.so,静态库的形式为libXXXXXX.a,我们去掉形式的前缀和后缀剩下的就是这个库的名称,那么这里库的形式为libc.so.6,我们去掉前缀lib再去掉后缀.so.6那么剩下的就是c,所以这里库的名字就是c,所以这个可执行程序所依赖的库就是c标准库,我们平时使用的头文件stdio和一些printf scanf函数都会调用这个c标准库。

静态库和静态链接

静态库不像动态库那样只会将库中代码的地址加载到符号表中,而是直接将所需的库中的代码拷贝到程序中,这样比较浪费空间。但这样程序是不依赖于静态库的,即使静态库缺失,程序还是能被执行。

静态链接是需要安装静态链接库的。
在这里插入图片描述通过静态链接生成可执行文件。

在这里插入图片描述查看是否是静态链接
在这里插入图片描述
查看静态库
在这里插入图片描述

这个就是c语言的静态库,一般而言系统都会自动携带动态库因为系统的运行得需要动态库支持,但是静态库有些机器上是没有的,如果没有的话大家得自行下载。

猜你喜欢

转载自blog.csdn.net/m0_52347974/article/details/129834592