GCC
- GCC 是一个强大且广泛使用的编译器套件,支持多种编程语言,包括 C、C++、Fortran、Ada 和 Go。
一、基础用法
- 编译简单程序
gcc -o my_program main.cgcc:调用 GCC 编译器。-o my_program:指定输出的可执行文件名为 my_program。如果不加 -o,默认生成 a.out。main.c:源文件名。
执行成功后,可以运行程序
./my_program
- 仅编译不链接
- GCC 分为多个阶段,包括预处理、编译、汇编和链接。有时你只需要生成目标文件(.o 文件),而不是完整的可执行文件。可以通过 -c 选项仅编译不链接
gcc -c main.c
# 生成的 main.o 是一个编译过的目标文件,可以在稍后与其他文件进行链接。
- 链接多个源文件
- 编译项目时,通常有多个源文件。可以编译并链接它们
- 链接多个文件时,整个程序只能有 一个 main 函数
gcc -o my_program file1.c file2.c file3.c
二、预处理、编译和汇编
- 预处理阶段(-E 选项)
预处理阶段处理 #include、#define 等宏和头文件操作。你可以让 GCC 仅执行预处理
gcc -E main.c -o main.i
# main.i 是预处理后的 C 代码,其中已经展开了所有的宏和包含的头文件。
- 生成汇编代码(-S 选项)
GCC 也可以生成汇编代码,而不是编译为机器码。使用 -S 选项
gcc -S main.c
- 生成目标文件(-c 选项)
-c 选项用于仅生成目标文件(.o 文件)而不进行链接
三、GCC 的优化选项和警告调试信息
- 优化可以显著提高程序的性能。GCC 提供了多个优化级别,使用 -O 开头的选项来控制优化程度。
- 常用优化级别
- O0:关闭优化(默认)。
- O1:启用一些基本的优化。
- O2:启用更多优化,通常是一个较好的折衷选择。
- O3:启用所有可以启用的优化,包括耗时较长的优化。
- Os:优化代码大小,适用于嵌入式或对二进制大小敏感的环境。
- GCC 警告和调试信息
- Wall:启用大部分常见的警告。
- Wextra:启用更多警告。
- Werror:将警告视为错误,阻止编译成功。这可以确保警告问题不会被忽略。
gcc -Wall -Wextra -Werror -o my_program main.c
- 生成调试信息
为了调试程序,你可以在编译时加入 -g 选项生成调试信息gcc -g -o my_program main.c
四、交叉编译
-
交叉编译指在一个平台上编译生成可以在另一个平台上运行的程序。GCC 可以进行交叉编译,尤其在嵌入式开发中非常常用
-
安装交叉编译器
sudo apt install gcc-arm-linux-gnueabi
-
使用交叉编译器
arm-linux-gnueabi-gcc -o my_program main.c # 生成的 my_program 可在 ARM 平台上运行
五、静态链接与动态链接
- 静态链接
静态链接将所有库代码打包到可执行文件中。这使得程序在没有共享库的情况下也能运行。使用 -static 选项
gcc -static -o my_program main.c
- 动态链接
动态链接(默认行为)只包含库的引用,程序运行时需要共享库。动态链接的程序通常体积较小,但依赖于库的正确安装。
六、处理静态库
- 使用静态库
可以将代码编译成静态库(.a 文件),然后在其他项目中使用-
- 创建静态库
gcc -c file1.c file2.c ar rcs libmylib.a file1.o file2.o
-
- 在项目中使用静态库
gcc -o my_program main.c -L. -lmylib # -L.: -L 选项用于指定库文件的搜索路径 # . 表示当前目录,因此 -L. 表示让编译器在当前目录下查找库文件。
-
- 使用动态库
动态库(.so 文件)在运行时加载,适合大型项目。-
- 创建动态库
gcc -shared -fPIC -o libmylib.so file1.c file2.c
-
- 编译时链接动态库
gcc -o my_program main.c -L. -lmylib # 运行时需要确保动态库在系统的库路径中,或者设置 LD_LIBRARY_PATH
-
七、多线程编译
在编译大型项目时,可以使用 -j 选项来加速编译过程。该选项指定并行编译时使用的线程数。
make -j4
# 允许 make 使用4个线程同时编译多个源文件,从而加快编译速度。