第2章 GCC编译器的使用
源文件需要经过编译才能生成可执行文件。在Windows下进行开发时,只需要点几个按钮即可编译,集成开发环境(比如Visual studio)已经将各种编译工具的使用封装好了。Linux下也有很优秀的集成开发工具,但是更多的时候是直接使用编译工具;即使使用集成开发工具,也需要掌握一些编译选项。
PC机上的编译工具链为gcc、ld、objcopy、objdump等,它们编译出来的程序在x86平台上运行。要编译出能在ARM平台上运行的程序,必须使用交叉编译工具xxx-gcc、xxx-ld等(不同版本的编译器的前缀不一样,比如arm-linux-gcc),下面分别介绍。
2.1 GCC编译过程(精简版)
一个C/C++文件要经过预处理(preprocessing)、编译(compilation)、汇编(assembly)和链接(linking)等4步才能变成可执行文件。

通过不同的gcc选项可以控制这些过程:

在日常交流中通常使用“编译”统称这4个步骤,如果不是特指这4个步骤中的某一个,本教程也依惯例使用“编译”这个统称。
gcc使用示例:
gcc hello.c // 输出一个名为a.out的可执行程序,然后可以执行./a.out
gcc -o hello hello.c // 输出名为hello的可执行程序,然后可以执行./hello
gcc -o hello hello.c -static // 静态链接
gcc -c -o hello.o hello.c // 先编译(不链接)
gcc -o hello hello.o // 再链接
执行“gcc -o hello hello.c -v”时,可以查看到这些步骤:
cc1 main.c -o /tmp/ccXCx1YG.s
as -o /tmp/ccZfdaDo.o /tmp/ccXCx1YG.s
cc1 sub.c -o /tmp/ccXCx1YG.s
as -o /tmp/ccn8Cjq6.o /tmp/ccXCx1YG.s
collect2 -o test /tmp/ccZfdaDo.o /tmp/ccn8Cjq6.o ....
可以手工执行以下命令体验一下:
gcc -E -o hello.i hello.c
gcc -S -o hello.s hello.i
gcc -c -o hello.o hello.s
gcc -o hello hello.o
2.1.1 常用编译选项
在学习时,我们暂时只需要了解表 2‑1中的选项:
| 常用选项 | 描述 |
|---|---|
| -E | 预处理,开发过程中想快速确定某个宏可以使用“-E -dM” |
| -c | 把预处理、编译、汇编都做了,但是不链接 |
| -o | 指定输出文件 |
| -I | 指定头文件目录 |
| -L | 指定链接时库文件目录 |
| -l | 指定链接哪一个库文件 |
2.1.2 怎么编译多个文件
- 一起编译、链接:
gcc -o test main.c sub.c
- 分开编译,统一链接:
gcc -c -o main.o main.c
gcc -c -o sub.o sub.c
gcc -o test main.o sub.o
2.1.3 制作、使用动态库
- 制作、编译:
gcc -c -o main.o main.c
gcc -c -o sub.o sub.c
gcc -shared -o libsub.so sub.o sub2.o sub3.o(可以使用多个.o生成动态库)
gcc -o test main.o -lsub -L /libsub.so/所在目录/