- 1、简单编译
- 1.1 预处理(Preprocessing)
- 1.2 编译(Compilation)
- 1.3 汇编(Assembly)
- 1.4 连接(linking)
- 2、多个程序文件的编译
- 3、检错
- 4、库文件的连接
- 4.1 编译成可执行文件
- 4.2 链接
- 4.3 强制链接时使用静态链接库
- 5、参考资料
- 6、总结
编译示例如下:
一步到位编译指令:
1.1 预处理(Preprocessing)事实上,编译过程分四个阶段,即预处理(Preprocessing)、编译(Compilation)、汇编(Assembly)和连接(linking)。
1.2 编译(Compilation)1、可以输出test.i文件中存放着test.c经预处理之后的代码。
2、gcc -E test.c这条指令,是直接在命令行窗口输出预处理后的代码。
3、-E:可以让编译器在预处理后停止,并输出预处理结果。本例中,预处理结果就是将stdio.h文件中的内容插入到test.c中。
预处理后,直接对生成的test.i文件编译,生成汇编代码。
1.3 汇编(Assembly)-S:表示在程序编译期间,生成汇编代码后,停止,-o输出汇编代码文件。
1.4 连接(linking)对上一过程生成的汇编代码文件test.s,gas汇编器负责将其编译为目标文件,具体操作如下:
2、多个程序文件的编译1、gcc连接器是gas提供,负责将程序的目标文件与所需的所有附加的目标文件连接起来,最终生成可执行文件。
2、附加的目标文件包括静态连接库和动态连接库
3、对上一步生成的test.o,将其与C标准输入输出进行连接,最终生成程序test。
4、在命令行窗口中,执行./test,让其显示Hello World!。
一般情况下,整个程序由多个源文件组成,自然地,形成了多个编译单元,使用gcc便能很好地管理这些单元。
1)gcc源文件1 源文件2 源文件3 -o 生成可执行文件
2)多个文件同时处理时,上面那条指令相当于依次执行如下四条指令:
gcc -c 源文件1 -o 生成.o文件1
gcc -c 源文件2 -o 生成.o文件2
gcc -c 源文件3 -o 生成.o文件3
gcc 生成 .o 文件1 生成 .o文件2 生成 .o 文件3 -o 生成可执行文件
$ gcc -pedantic main.c -o main $ gcc -pedantic sub1.c -o sub1 $ gcc -pedantid sub2.c -o sub2
-pedantic:能够帮助程序员发现一些不符合ANSI/ISO C标准的代码。
$ gcc -Wall main.c -o main
-Wall:它能使gcc产生尽可能多的警告信息
$ gcc -Werror main.c -o main
4、库文件的连接1、gcc给出的警告信息严格来说不能算作错误,但却很有可能成为错误的栖息之地。
2、但优秀的Linux程序员应该尽可能避免警告信息,使自己的代码保持健壮,所以将警告当做错误对待,是一种可嘉的行为!
3、因此,在编译程序是带上-Werror选项,gcc在所有产生警告的地方停止编译,迫使程序员修改代码。
4.1 编译成可执行文件1、软件开发过程中,我们会经常使用第三方函数库,需要借助许多函数库的支持完成许多相应的功能。
2、程序员角度,函数库就是一些头文件(.h)和库文件(so或lib、dill)的集合。
3、Linux系统下大多数函数将头文件(.h)放到/usr/include/目录下,库文件则放到/usr/lib/目录下。
4、Windows系统下库文件主要放到Visual S
tdio 的目录下的include和lib以及系统文件夹下。
5、但有些情况,我们需要的库不在这些目录下,所以gcc在编译时需要用自己的方法找到需要的头文件和库文件。
首先 我们要将main.c编译为目标文件,执行如下:
$ gcc -c -I /usr/dev/mysql/include main.c -o main.o4.2 链接
最后 我们把所有目标文件链接成可执行文件
$ gcc -L /usr/dev/mysql/lib -lmysqlclient main.o -o main
错误原因:我们应提前在mysql官网上下载MySQL Connectors 的C库,下载下来解压后,有一个include文件夹,里面包含mysql connectors的头文件,还有一个lib文件夹,里面包含二进制so文件libmysqlclient.so。
4.3 强制链接时使用静态链接库linux系统下的库文件包含动态库(.so),编译时动态加载,和静态库(.a),编译时静态加载。
一般情况下,gcc在链接时优先使用动态链接库,只有动态没了才使用静态链接库,但如果情况需要,编译时可以加上-static,强制使用静态链接。
例如,在/usr/dev/mysql/lib目录下链接时需要用到库文件libmysqlclient.so和libmysqlclient.a,为了让链接时只用静态链接库,可以执行以下命令:
$ gcc -L /usr/dev/mysql/lib -static -lmysqlclient main.o -o main
静态库链接时搜索路径顺序:
1、Id会找gcc命令中的参数-L
2、再找gcc的环境变量LIBRARY_PATH
3、再找内定目录 /lib /usr/lib /usr/local/lib 这是当初compile gcc是写在程序内的
动态链接时、执行时搜索路径顺序:
1、编译目标代码时指定的动态库搜索路径
2、环境变量LD_LIBRARY_PATH指定的动态库搜索路径
3、配置文件/etc/ld.so.conf 中指定的动态库搜索路径
4、默认的动态库搜索路径/lib
5、默认的动态库搜索路径/usr/lib
有关环境变量:
LIBRARY_PATH 环境变量:指定程序静态库文件搜索路径
LD_LIBRARY_PATH 环境变量:指定程序动态链接库文件搜索路径
使用gcc和gcc的伙伴
6、总结gcc是一个非常强大的编译工具集,能够编译多种语言,能很好地将编译过程的四个阶段:预处理,编译、汇编和链接进行下去。



