make 工具用于自动完成编译。自动编译的规则由makefile文件来规定。
使用make命令时,该工具默认在当前目录下依次搜索名为 GNUmakefile、makefile、Makefile 的文件来作为makefile。UNIX/Linux中常使用后两种。
也可以指定上述三种文件以外的其它文件作为makefile,须添加 -f 选项:make -f Makefile.debug
makefile的结构与语法
#开头的行为注释行。“\”为续行符。
基本格式为:
target: dependency1 dependency2 ...
<command>
即:
目标文件: 依赖文件(一个或多个)列表 #目标文件:要创建的二进制文件;依赖文件之间以空格隔开;
<命令行> #即make要执行什么动作来创建“目标”文件。必须TAB字符开头,独占一行。
目标-依赖-命令格式的一种特例:
clean:
rm -f *.o
这个特殊目标--clean的功能是删除所有的目标模块。
makefile中常见的一个C编译的命令是这样的:
$ {CC} $ {CFLAGS} $ {CPPFLAGS} $ {TARGET_ARCH} –c $< -o $@
makefile 中的变量
大小写敏感,一般在makefile的头部定义。包括用户自定义的变量、环境变量、自动变量和预定义变量。
自定义变量:
VARNAME=string #定义
${VARNAME} # 使用
预定义变量
常见的有:
$* #不包含扩展名的目标文件名称。
$+ #所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件。
$^ #所有的依赖文件,以空格分开,不包含重复的依赖文件。
$< #第一个依赖文件的名称。
$@ #目标的完整名称。
$% #如果目标是归档成员,则该变量表示目标的归档成员名称。例如,如果目标名称 为 mytarget.so(image.o),则 $@ 为 mytarget.so,而 $% 为 image.o。
CC #C 编译器的名称,默认值为 cc。
CFLAGS #C 编译器的选项。
CPP #C 预编译器的名称,默认值为 $(CC) -E。
CPPFLAGS #C 预编译的选项。 CXX C++ 编译器的名称,默认值为 g++。
CXXFLAGS #C++ 编译器的选项。
按makefile的描述编译
可用:
$ make target
它将生成makefile中定义的名为target的目标;
$ make
缺省情况,则make将自动生成makefile中的第一个目标,同时也是make的最终目标,其后面的所有目标都为生成最终目标所必经的中间过渡。
示例
了解以上内容后,你也可以理解并写出如下示例中的makefile文件了:
OBJS=prog.o code.o
CC=gcc
test:${ OBJS }
${ CC } –o test ${ OBJS }
prog.o:prog.c prog.h code.h
${ CC } –c prog.c –o prog.o
code.o:code.c code.h
${ CC } –c code.c –o code.o
clean:
rm –f *.o
Makefile还有一些隐含规则,在用户没有指定完整的某些命令时,make工具会自动地执行隐含规则所规定的动作。例如,target下一行没有command行,make会自动使用变量CC所指的编译器来编译依赖文件,以生成目标文件。可见,熟悉这些隐含规则可以简化我们的Makefile。例如上面的示例考虑隐含规则后可简化为:
OBJS=prog.o code.o
CC=gcc
test:${ OBJS }
${ CC } –o $@ $^
prog.o:prog.c prog.h code.h
code.o:code.c code.h
clean:
rm –f *.o
make 的命令行选项
另外,make时还可以添加一些命令行选项,前面提到的-f就是其中之一,更多的选项如下:
-C DIR #在读取 makefile 之前改变到指定的目录 DIR。
-f FILE #以指定的 FILE 文件作为 makefile。
-h #显示所有的 make 选项。
-i #忽略所有的命令执行错误。
-I DIR #当包含其他 makefile 文件时,可利用该选项指定搜索目录。
-n #只打印要执行的命令,但不执行这些命令。
-p #显示 make 变量数据库和隐含规则。
-s #在执行命令时不显示命令。
-w #在处理 makefile 之前和之后,显示工作目录。
-W FILE #假定文件 FILE 已经被修改。