从零开始:Linux 环境下的 C/C++ 编译教程
个人主页:chian-ocean
文章专栏
前言:
GCC(GNU Compiler Collection)是一个功能强大的编译器集合,支持多种语言,包括 C 和 C++。其中 gcc 用于 C 语言编译,g++ 专用于 C++ 编译。
Linux GCC or G++的安装
安装 GCC
运行以下命令安装 GCC:
sudo yum install -r gcc
安装完成后,可以再次检查版本:
gcc --version
安装G++
运行以下命令安装 GCC:
sudo yum install -r g++
安装完成后,可以再次检查版本:
g++ --version
Linux的代码编译
预处理(Preprocessing)
预处理的工作
- 去掉注释
- 展开头文件
- 条件编译
- 宏替换
C++代码执行
g++ -E code.cpp -o code.i
# 可以生成与处理文件,生成.i文件
编译(Compilation)
编译器将预处理后的源代码转换为汇编代码(文本形式的机器指令)。
- 生成汇编代码(通常是
.s
文件)。 - 编译器会进行语法分析和语义检查。
g++ -S code.i -o code.s
# 可以生成与处理文件,生成.s文件
汇编(Assembly)
汇编器将汇编代码(.s
文件)转换为二进制的目标代码(.o
文件)。
- 汇编代码被转换为机器能够理解的指令。
- 生成目标文件(通常是
.o
或.obj
文件)。
g++ -E code.s -o code.0
# 可以生成与处理文件,生成.0文件
od filename # 可以进行查看
链接(Linking)
函数库(Library)简介
在编程中,函数库是指封装了一组可重用函数、类或其他代码模块的集合,目的是简化开发、提高代码复用性。函数库通常以静态库(*.a
或 *.lib
)或动态库(*.so
、*.dll
或 *.dylib
)的形式存在。
类型 | 描述 |
---|---|
静态库 | 在编译时将库的代码嵌入到可执行文件中,生成的文件独立运行,不依赖外部库。 |
动态库 | 在运行时加载库文件,节省空间和内存,可以被多个程序共享。 |
动态链接
动态库(Dynamic Library)是一种在运行时加载的库,可以被多个程序共享,以节省存储空间和内存。动态库的文件扩展名在不同操作系统中有所不同:
- Linux:
.so
(Shared Object) - Windows:
.dll
(Dynamic Link Library) - macOS:
.dylib
ldd #可以查看可执行程序所依赖的动态库
下面是code可执行文件所以来的动态库
静态链接
静态库是一种将一组目标文件(.o
文件)打包成单个文件(通常扩展名为 .a
或 .lib
)的技术,便于代码复用。静态库在编译时链接到可执行文件中,因此运行时不需要额外的库支持。
- Linux:
.a
- Windows:
.lib
g++ code.cpp -static -o code-static # 可以生成静态链接
动态VS静态
定义
链接方式 | 定义 |
---|---|
静态链接 | 在编译阶段,将所需库的代码嵌入到可执行文件中,生成一个独立的可执行文件。 |
动态链接 | 在运行时加载所需的库(动态库),可执行文件只包含对库的符号引用,库本身存储在外部文件中(如 .so )。 |
操作系统命名
操作系统 | 静态库扩展名 | 动态库扩展名 |
---|---|---|
Linux | .a | .so |
Windows | .lib | .dll |
macOS | .a | .dylib |
对比表
特性 | 静态链接 | 动态链接 |
---|---|---|
生成的可执行文件大小 | 较大(嵌入所有库代码) | 较小(仅包含对动态库的引用) |
运行时依赖 | 无需外部库,独立运行 | 需要动态库文件 |
运行效率 | 高(无需加载外部库,直接执行) | 稍低(运行时加载动态库) |
内存使用 | 每个程序独立占用库的代码和数据 | 多个程序共享同一动态库 |
更新维护 | 更新库后需重新编译程序 | 更新库后程序无需重新编译 |
部署和兼容性 | 部署简单,无需额外的动态库 | 部署复杂,需要确保动态库存在并与程序兼容 |
符号冲突 | 不易出现,因为库代码独立嵌入到每个可执行文件中 | 可能出现多个库之间的符号冲突 |
和兼容性** | 部署简单,无需额外的动态库 | 部署复杂,需要确保动态库存在并与程序兼容 |
符号冲突 | 不易出现,因为库代码独立嵌入到每个可执行文件中 | 可能出现多个库之间的符号冲突 |
适用场景 | 嵌入式系统、小型独立工具、运行环境固定的场景 | 大型系统、需要频繁更新库或共享库的场景 |