gcc ------->默认编译c文件(gcc xxx -lstdc++连接到c++库编译c++,g++默认编译c++)mysql
一.CC编译程序过程分四个阶段
◆ 预处理(Pre-Processing)
◆ 编译(Compiling)
◆ 汇编(Assembling)
◆ 连接(Linking)c++
1.1 预处理(Pre-Processing)程序员
gcc -E test.c -o test.i 或 gcc -E test.c
能够输出test.i文件中存放着test.c经预处理以后的代码。打开test.i文件,看一看,就明白了。后面那条指令,是直接在命令行窗口中输出预处理后的代码.sql
gcc的-E选项,可让编译器在预处理后中止,并输出预处理结果。预处理结果就是将#include等相似的文件中的内容插入到当前文件中。ide
1.2 编译(Compiling)函数
预处理以后,可直接对生成的test.i文件编译,生成汇编代码:工具
gcc -S test.i -o test.s
gcc的-S选项,表示在程序编译期间,在生成汇编代码后,中止,-o输出汇编代码文件。ui
1.3 汇编(Assembling)spa
对于生成的汇编代码文件test.s,gas汇编器负责将其编译为目标文件,以下:操作系统
gcc -c test.s -o test.o
1.4 连接(Linking)
gcc链接器是gas提供的,负责将程序的目标文件与所需的全部附加的目标文件链接起来,最终生成可执行文件。附加的目标文件包括静态链接库和动态链接库。
对于上一小节中生成的test.o,将其与C标准输入输出库进行链接,最终生成程序test
gcc test.o -o test
这个程序,一步到位的编译指令是:
gcc test.c -o test
二:库文件连接
开发软件时,彻底不使用第三方函数库的状况是比较少见的,一般来说都须要借助许多函数库的支持才可以完成相应的功能。从程序员的角度看,函数库实际上就是一些头文件(.h)和库文件(so、或lib、dll)的集合。。虽然Linux下的大多数函数都默认将头文件放到/usr/include/目录下,而库文件则放到/usr/lib/目录下;Windows所使用的库文件主要放在Visual Stido的目录下的include和lib,以及系统文件夹下。但也有的时候,咱们要用的库再也不这些目录下,因此GCC在编译时必须用本身的办法来查找所须要的头文件和库文件。(头文件的路径用-I,库文件路径用-L,好比说-I/usr/myinclude -L/usr/mylib)
-l参数就是用来指定程序要连接的库,-l参数紧接着就是库名,那么库名跟真正的库文件名有什么关系呢?就拿数学库来讲,他的库名是m,他的库文件名是libm.so,很容易看出,把库文件名的头lib和尾.so去掉就是库名了(把函数库命名为“lib“是UNIX的惯例,“.so”是共享文件库的标准扩展名)
2.1 编译成可执行文件
首先咱们要进行编译test.c为目标文件,这个时候须要执行
gcc –c –I /usr/dev/mysql/include test.c –o test.o
2.2 连接
最后咱们把全部目标文件连接成可执行文件:
gcc –L /usr/dev/mysql/lib –lmysqlclient test.o –o test
Linux下的库文件分为两大类分别是动态连接库(一般以.so结尾)和静态连接库(一般以.a结尾),两者的区别仅在于程序执行时所需的代码是在运行时动态加载的,仍是在编译时静态加载的。
2.3 强制连接时使用静态连接库
默认状况下, GCC在连接时优先使用动态连接库,只有当动态连接库不存在时才考虑使用静态连接库,若是须要的话能够在编译时加上-static选项,强制使用静态连接库。
在/usr/dev/mysql/lib目录下有连接时所须要的库文件libmysqlclient.so和libmysqlclient.a,为了让GCC在连接时只用到静态连接库,能够使用下面的命令:
gcc –L /usr/dev/mysql/lib –static –lmysqlclient test.o –o test
静态库连接时搜索路径顺序:
1. ld会去找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环境变量:指定程序动态连接库文件搜索路径
总结:源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译器只检测程序语法,和函数、变量是否被声明。若是函数未被声明,编译器会给出一个警告,但能够生成Object File。而在连接程序时,连接器会在全部的Object File中找寻函数的实现,若是找不到,那到就会报连接错误码
三:makefile工具
make是一个命令工具,是一个解释makefile中指令的命令工具,make会在当前目录下找名字叫“Makefile”或“makefile”的文件。make会一层又一层地去找文件的依赖关系(若是该过程文件比生成的目标文件新,需从新编译),直到最终编译出第一个目标文件。
Makefile的规则
target ... : prerequisites ...
command
...
...
target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中若是有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。
3.1 基础makefile
target : prerequisites1.o prerequisites2.o prerequisites3.o /cc-o target prerequisites1.o prerequisites2.o prerequisites3.o display.o
prerequisites1.o : prerequisites1.c prerequisites1.h
cc-c main.c
prerequisites2.o : prerequisites1.c prerequisites2.h
cc-c prerequisites2.c
prerequisites3.o : prerequisites3.c prerequisites3.h
cc-c prerequisites3.c
clean :
rm target prerequisites1.o prerequisites2.o prerequisites3.o
View Code
反斜杠(/)是换行符的意思。在这个makefile中,目标文件(target)包含:中间目标文件(*.o),依赖文件(prerequisites)就是冒号后面的那些 .c 文件和 .h文件。每个 .o 文件都有一组依赖文件,而这些 .o 文件又是执行文件 target 的依赖文件。依赖关系的实质上就是说明了目标文件是由哪些文件生成的。
在定义好依赖关系后,后续的那一行定义了如何生成目标文件的操做系统命令,必定要以一个Tab键做为开头。make并无论命令是怎么工做的,他只管执行所定义的命令。make会比较targets文件和prerequisites文件的修改日期,若是prerequisites文件的日期要比targets文件的日期要新,或者target不存在的话,那么,make就会执行后续定义的命令。
3.2 变量makefile
上例看到编译目标文件时[.o]文件的字符串被重复了两次,若是咱们的工程须要加入一个新的[.o]文件,那么咱们须要在两个地方加(应该是三个地方,还有一个地方在clean中)。咱们声明一个变量OBJ等于依赖的[.o]文件,而后在咱们的makefile中以“$(objects)”的方式来使用这个变量
3.3 make自动推导
GNU的make很强大,它能够自动推导文件以及文件依赖关系后面的命令,因而咱们就不必去在每个[.o]文件后都写上相似的命令。make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,若是make找到一个prerequisite1.o,那么prerequisite1.c,就会是prerequisite1.o的依赖文件。而且 cc -c prerequisite1.c 也会被推导出来。以下代码:
OBJ =prerequisites1.o prerequisites2.o prerequisites3.o
target : $(OBJ)/cc-o target $(OBJ)
prerequisites1.o : prerequisites1.h
prerequisites2.o : prerequisites2.h
prerequisites3.o : prerequisites3.h
.PHONY : clean
clean :
rm target $(OBJ)
View Code
这种方法,也就是make的“隐晦规则”。上面文件内容中,“.PHONY”表示,clean是个伪目标文件。