编译流程
- GCC编译器的编译流程:预处理、编译、汇编和链接
- 预处理:展开所有的头文件、替换程序中的宏、解析条件编译并添加到文件中;
- 编译:将经过预编译处理的代码编译成汇编代码,也就是我们常说的程序编译;
- 汇编:将汇编语言文件编译成二进制目标文件;
- 链接:将汇编出来的多个二进制目标文件链接在一起,形成最终的可执行文件,链接的时候还会涉及到静态库和动态库等问题。
Makefile基础
make:解决大工程编译的工具,make命令可完成整个工程的自动编译
makefile: 描述哪些文件需要编译、哪些需要重新编译的文件,makefile就跟脚本文件一样,还可以执行系统命令。
* 核心思想:先将工程中的文件都编译一遍,然后修改哪个文件就编译哪个文件。
gcc -c main.c
gcc -c input.c
gcc -c calcu.c
gcc main.o input.o calcu.o -o main
上述命令前三行分别是将 main.c、 input.c 和 calcu.c 编译成对应的.o 文件,所以使用了“-c”选项,“-c”选项我们上面说了,是只编译不链接。
最后一行命令是将编译出来的所有.o 文件链接成可执行文件 main。
如果现在修改了calcu.c文件,只需要将 caclue.c 这一个文件重新编译成.o 文件,只需要下面两条命令:
gcc -c calcu.c
gcc main.o input.o calcu.o -o main
makefile使用特点:
- 如果工程没有编译过,那么工程中的所有.c 文件都要被编译并且链接成可执行程序。
- 如果工程中只有个别 C 文件被修改了,那么只编译这些被修改的 C 文件即可。
- 如果工程的头文件被修改了,那么我们需要编译所有引用这个头文件的 C 文件,并且
链接成可执行文件。
Makefile语法
Makefile规则
Makefile里面是由一系列的规则组成的,这些规则格式如下:
目标···...: 依赖文件集合······
命令1
命令2
···
比如下面这条规则:
main: main.o input.o calcu.o
gcc -o main main.o input.o calcu.o
这条规则的目标是main, main.o, input.o, calcu.o是生成的依赖文件,如果要更新目标main,就必须先更新它的所有依赖文件,如果依赖文件中的任何一个有更新,那么目标也必须更新。
make命令会为Makefile中的每个以TAB开始的命令创建一个Shell进程去执行。
再回到上面的例子,在Makefile中的代码如下:
main: main.o input.o calcu.o
gcc -o main main.o input.o calcu.o
main.o: main.c
gcc -c main.c
input.o: input.c
gcc -c input.c
calcu.o: calcu.c
gcc -c calcu.c
clean:
rm *.o
rm main
注意最后一个规则目标是clean,它没有依赖文件,因此会默认为依赖文件都是最新的,所以其对应的命令不会执行,只有在使用“make clean”命令时才会使用,会将编译出来的.o和main可执行文件删除。
Make执行过程
- make 命令会在当前目录下查找以 Makefile(makefile 其实也可以)命名的文件。
- 当找到 Makefile 文件以后就会按照 Makefile 中定义的规则去编译生成最终的目标文件。
- 当发现目标文件不存在,或者目标所依赖的文件比目标文件新(也就是最后修改时间比目标文件晚)的话就会执行后面的命令来更新目标。