【Linux初阶】Linux编译器-gcc/g++使用 | gcc/g++入门 | 动静态库&动静态链接 | Linux下的C/C++静态库安装

【Linux初阶】Linux编译器-gcc/g++使用 | gcc/g++入门 | 动静态库&动静态链接 | Linux下的C/C++静态库安装_第1张图片

hello,各位读者大大们你们好呀

系列专栏:【Linux初阶】

✒️✒️本篇内容:gcc/g++背景知识、编译的主要过程、简述动静态库和编译链接

作者简介:计算机海洋的新进船长一枚,请多多指教( •̀֊•́ ) ̖́-

同期Linux工具文章:【Linux初阶】vim工具的使用 | vim配置 | sudo提权指令配置

目录

一、背景知识

二、gcc编译过程

1.预处理(头文件展开、去注释、宏替换、条件编译)

2.编译(生成汇编)

3.汇编(生成机器可识别代码 - 把汇编变成二进制目标文件)

4.连接(生成可执行文件或库文件) 

三、函数库 & 链接方式

静态库和动态库

静态链接和动态链接

静态库安装

C语言静态库安装

C++静态库安装

Linux和windows链接原理

在Linux下

在windows下


一、背景知识

我们先来回顾一下程序的翻译过程:

  1. 预处理(头文件展开、去注释、宏替换、条件编译)
  2. 编译(生成汇编)
  3. 汇编(生成机器可识别代码 - 把汇编变成二进制目标文件)
  4. 连接(生成可执行文件或库文件) 

Linux下程序的执行

在Linux中,文件经过gcc编译会生成一个执行文件(默认生成a.out,可使用 gcc 编译文件 -o + 目标文件名生成),我们可以用以下方法运行可执行文件

./文件名
./文件的绝对路径

示例:

【Linux初阶】Linux编译器-gcc/g++使用 | gcc/g++入门 | 动静态库&动静态链接 | Linux下的C/C++静态库安装_第2张图片

Linux下程序的删除

删除可执行程序 a.out

rm ./a.out


二、gcc编译过程

格式 gcc [选项] 要编译的文件 [选项] [目标文件]

1.预处理(头文件展开、去注释、宏替换、条件编译)

预处理功能:主要包括宏定义,文件包含,条件编译,去注释等。

预处理指令是以#号开头的代码行。即生成预处理文件后,以#号开头的指令是预处理指令。

生成预处理文件:

  • 实例: gcc –E test.c –o test.i
  • 选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。
  • 选项“-o”是指目标文件(后接临时文件名称),“.i”文件为已经过预处理的C原始程序

2.编译(生成汇编)

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

用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。

  • 实例: gcc –S test.i –o test.s
  • 选项“-S”,该选项的作用是让 gcc 在程序翻译成汇编语言后,停止编译过程。
  • “.s为编译目标文件

3.汇编(生成机器可识别代码 - 把汇编变成二进制目标文件)

汇编阶段是把编译阶段生成的“.s”文件转成目标文件

读者在此可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了

  • 实例: gcc –c test.s –o test.o
  • “.o为汇编目标文件

4.连接(生成可执行文件或库文件) 

在成功编译之后,就进入了链接阶段。

  • 实例: gcc test.o –o test
  • test为链接完成后生成的可执行程序


三、函数库 & 链接方式

函数库

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

动态库:libXXXXX.so

静态库:libYYYYY.a

去掉前缀 lib,去掉后缀.so/a,剩下的就是库名称,所以上述的 libc.so.6 C语言标准库

【注意】函数库分为静态库和动态库

静态库和动态库

静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”。

动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库。

gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件,如下所示。

gcc test.o –o test gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证

  

静态链接和动态链接

静态链接:在程序内部,拷贝一份运行需要的库函数(形成静态库),直接使用;

优点:不受库升级和库删除的影响

缺点:形成的可执行程序体积大,可能会导致同一库函数多次拷贝使用,造成不必要的空间消耗

动态链接:通过编译器、链接器对库进行连接,间接使用库运行程序(调用动态库);

优点:形成的可执行程序体积小,节省磁盘内存空间,便于下载使用

静态库安装

C语言静态库安装

sudo yum install glibc-static

验证 :形成静态库可执行程序

gcc test.c -o mytest -static

 我们可以看到,statically linked - 静态链接 出现

C++静态库安装

sudo yum install -y libstdc++-static

验证方法同上 

g++ test.c -o mytest.cpp -static

Linux和windows链接原理

在Linux下

系统为了支持我们编程,为我们提供了 标准库.h ,标准的动静态库 .so/.a

我们的程序通过使用包含头文件、使用动静态库,实现将代码转化为可执行程序

在windows下

链接原理和Linux差不多,系统为了为我们提供了 动态库 .dll静态库 .lib


gcc/g++工具的知识大概就讲到这里啦,博主后续会继续更新更多Linux操作系统的相关知识,干货满满,如果觉得博主写的还不错的话,希望各位小伙伴不要吝啬手中的三连哦!你们的支持是博主坚持创作的动力! 

你可能感兴趣的:(Linux初阶,linux,运维,服务器,c++,c语言)