Linux 基础开发工具(中)
本文介绍 Linux 环境下两大基础开发工具 GCC/G++ 和 Make/Makefile,涵盖编译原理、链接机制及自动化构建方法。
1. GCC/G++
程序从源代码到可执行文件需经过编译和链接两个大过程。编译可细分为预处理、编译、汇编三个阶段。以下在 Linux 中验证各阶段的具体实现。
1.1 编译链接流程
预处理
预处理主要进行去注释、宏替换、条件编译、头文件展开等工作。使用 -E 选项仅执行预处理:
gcc -E [原文件名] -o [生成.i 的文件]
示例:将 test1.c 预处理为 test1.i。
执行后打开 test1.i,可见头文件已展开,宏已替换,注释已去除。
编译
编译将预处理后的代码转换为汇编指令。使用 -S 选项仅执行编译:
gcc -S [源文件] -o [目标生成的.s 文件]
示例:将 test1.i 编译为 test1.s。
查看 test1.s,内容为汇编代码。
汇编
汇编将汇编代码转换为机器码(二进制)。使用 -c 选项仅执行汇编:
gcc -c [源文件] -o [生成的目标.o 文件]
示例:将 test1.s 汇编为 test1.o。
.o 文件为二进制文件,直接打开显示乱码。
链接
链接将 .o 文件和库文件合并生成可执行程序。默认指令如下:
gcc [源文件名] -o [目标文件]
示例:将 test1.o 链接为 test.out 并运行。
注:链接过程涉及进程和文件系统知识,动静态库及链接细节将在后续章节详细讲解。
1.2 常见问题解析
为什么需要编译后再链接? 大型工程通常包含多个模块,通过条件编译可在同一份底层代码中区分不同版本(如免费版与专业版),减少维护成本。
什么是编译器自举? 编译器本身也是软件。早期由机器语言编写汇编编译器,再由汇编编写 C 编译器,最后用 C 编写 C 编译器。这种用自身语言编写自身编译器的过程称为自举。
为何 C/C++ 先转为汇编再转机器码? 为提高转化效率。C/C++ 诞生前已有完善的汇编转机器码体系,建立 C/C++ 与汇编的映射关系比直接建立与机器码的关系更简单高效。
1.3 动静态库和动静态链接
- 静态库:编译时库代码加入可执行文件,后缀通常为
.a。运行时无需库文件,但文件体积较大。 - 动态库:编译时不加入库代码,运行时加载,后缀通常为
.so(Linux)或.dll(Windows)。节省系统开销。
查看链接方式:
使用 ldd [文件名] 可查看动态链接情况;使用 file [文件名] 可判断链接类型。
静态链接设置: 安装静态库支持:
yum install glibc-static libstdc++ -static -y


