GNU make
在使用GNU的编译工具进行开发时,经常要用到GNU make工具。使用make工具,可以将大型的开发项目分解称为多个更易于管理的模块。make是一个解释Makefile文件中指令的命令工具,最基本的功能是通过Makefile文件来描述源程序之间的相互依赖关系并自动维护编译工作,能够告知系统以何种方式编译和链接程序。一旦完成了Makefile文件,剩下的工作就只是在Linux终端下输入make就可以自动完成所有便宜任务,生成目标程序。
GNU make工作流程:
1、查找当前目录下的Makefile文件
2、初始化文件中的变量
3、分析Makefile中的所有规则
4、为所有的目标文件创建依赖关系
5、根据依赖关系,决定那些目标文件要重新生成
6、执行生成命令
make命令本省可带一些参数:
make [选项] [目标文件]
make命令的一些常用选项及其含义如下:
-f file:表示指定Makefile的文件名
-n:表示打印出所有执行命令,但是事实上并不执行这些命令
-s:表示在执行时不打印命令名
-w:表示如果在make执行时要改变目录,则打印当前的执行目录
-d:表示打印调试信息
-I<dirname>:表示指定所有Makefile所在目录
-h:help文档,显示Makefile的help信息
例如:利用-f指定Makefile文件:
# make -f Makefilename
参数[目标文件]对于make命令来说也是一个可选项。如果在执行make命令时带有该参数:
# make target
Makefile规则语法
Make的作用就是让编译器知道要编译一个文件需要依赖哪些文件,同时当那些依赖文件有了改变,编译器会自动地发现最终的生成文件已经过时,重新编译相应的模块。Makefile规定了整个工程的编译规则。一个工程中的许多源文件按其类型、功能、模块可能被放在不同的目录中。
Makefile编写格式:
#注释 目标文件:依赖文件列表 …… <Tab>命令列表 ……
格式说明:
注释:和Shell脚本一样,Makefile语句行的注释采用“#”符号
目标:表示目标文件的列表,通常是指程序编译过程中生成的目标文件(.o文件)或最终的可执行程序,有时也可以是要执行的动作,如“clean”这样的目标
依赖文件:表示文件所依赖的文件,一个目标文件可以依赖一个或多个文件。
“:”符号:分隔符,介于目标文件和依赖文件之间
命令列表:make程序执行的动过,也是创建目标文件的命令。一个规则可以有多条命令,每一行只能有一条命令。
每一个命令行必须以<Tab>键开始,<Tab>键告诉make程序该行是一个命令行,make按照命令完成相应的动作。
Makefile文件的规则主要有两个方面:一个是说明文件之间的依赖关系;另一个是告诉make工具如何生成目标文件的命令。
#Makefile Example test: main.o test1.o test2.o gcc -o test main.o test1.o test2.o main.o: main.c head1.h head2.h gcc -c main.c test1.o: test1.c head2.h gcc -c test1.c test2.o: test2.c head3.h gcc -c test2.c install: cp test /home/tmp clean: rm -f *.o
Makefile 文件中变量的使用
Makefile文件中除了一些列的规则,对于变量的使用是一个非常重要的内容。Linux下的Makefile文件中可能会使用很多的变量,定义一个变量(也常称为宏定义),只要在一行的开始定义这个变量(一般使用大写,而且放在Makefile文件的顶部来定义),后面更一个“=”号,“=”号后面即为设定的变量值。如果要引用该变量,用一个“$”符号来引用变量,变量名需要放在“$”符号后的括号里。
make工具内部变量:
$@:指代当前规则下的目标文件列表
$<:指代依赖文件列表中的第一个依赖文件
$^:指代依赖文件列表中所有依赖文件
$?:指代依赖文件列表中新于对应目标文件的文件列表
变量的定义可以简化Makefile的书写,方便对程序的维护。
#Makefile Example OBJ=main.o test1.o test2.o CC=gcc test: $(OBJ) $(CC) -o test $(OBJ) main.o: main.c head1.h head2.h $(CC) -c main.c test1.o: test1.c head2.h $(CC) -c test1.c test2.o: test2.c head3.h $(CC) -c test2.c install: cp test /home/tmp clean: rm -f *.o
一般说来,Makefile文件中变量的应用主要有一下几个方面:
1、代表一个文件列表
Makefile文件中的变量常常存储一些目标文件,甚至是目标文件的依赖文件,引用这些文件的时候引用存储这些文件的变量即可,这给Makefile的编写者和维护者带来了很大的方便。
2、表示编译命令选项
当所有编译命令都带有相同编译选项时(比如-Wall、-O2等),可以将该编译选项付给一个变量,这样方便引用。同时如果想改变编译选项的时候,只需要改变该变量值即可,而不必在每处用到编译选项的地方都做改动。