一, Makefile 简介
一个工程中的源文件不计其数, 其按类型, 功能, 模块分别放在若干个目录中, makefile 定义了一系列的规则来指定, 哪些文件需要先编译, 哪些文件需要后编译, 哪些文件需要重新编译, 甚至于进行更复杂的功能操作, 因为 makefile 就像一个 Shell 脚本一样, 其中也可以执行操作系统的命令. Linux 内核的编译同样也遵循这些规则, 具体说明可见 kernel/Documentation/kbuild/makefiles.txt
二, 简单编写一个 Makefile 模板
当编译少量的源文件时, 可以用以下两种方法编译
1, 直接用一条命令编译
gcc -o test 1.c 2.c
编译过程说明:
执行 gcc -o test 1.c 2.c 时,
对于 1.c: 预编译, 编译, 汇编, 链接
对于 1.c: 预编译, 编译, 汇编, 链接
优点: 命令简单, 易操作
缺点: 如果文件很多, 即使修改了一个文件, 但是所有的文件都要重新 "预处理, 编译, 汇编", 效率很低
2, 通过 Makefile 建立编译规则
一个的 Makefile 文件包含一系列的规则(想了解更多规则可参考《GNU make 手册》), 其格式如下:
目标 : 依赖 1 依赖 2 ... 依赖 n
命令
注意: 命令的前边必须是一个 Tab
命令执行的条件:
(1)"依赖" 文件比 "目标" 的时间新
(2)没有 "目标" 这个文件
三, 代码实践
功能说明: 当任何一个文件发生改变时, 其所有依赖文件和自己都会被重新编译, 而其他与此没有关联的文件则不会被编译
源文件如下:
- <1 > 文件 1.c
- #include <stdio.h>
- #include "1.h"
- int main(char argc, char *argv[])
- {
- printf("This is 1.c\n");
- func();
- printf("AA = %d\n", AA);
- return 0;
- }
- <2 > 文件 2.c
- #include <stdio.h>
- void func(void)
- {
- printf("This is 2.c\n");
- }
- <3 > 文件 1.h
- #define AA 2
1, 第 1 个 Makefile
- target:1.c 2.c 1.h
- gcc -o target 1.c 2.c
解析:
第一次编译 (没有目标生成) 或依赖发生变化 (依赖比目标新) 就执行下面的命令这样的缺点就是, 只要其中的一个依赖发生变化, 所有的文件都要重新被编译一遍, 这样效率极低
2, 第 2 个 Makefile
- target:1.o 2.o
- gcc -o target 1.o 2.o
- #-c 表示只编译不链接(只进行预编译, 编译, 汇编)
- 1.o : 1.c
- gcc -c -o 1.o 1.c
- 2.o : 2.c
- gcc -c -o 2.o 2.c
解析:
解析: 当执行 make 命令时, 想要生成第一个目标 target, 而 target 依赖于 1.o,2.o, 但是当前目录下并没有 1.o,2.o, 它会用 1.o 往下查找到 1.o 依赖于 1.c, 同时判断 (1.c 是否比 1.o 新或 1.o 是否存在) 是否执行 gcc -c -o .1.o 1.c, 我们这里满足第二个条件所以此命令会
来源: http://www.bubuko.com/infodetail-2911666.html