https://blog.csdn.net/weixin_38391755/article/details/80380786 Makefile教程
%.o : %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
其中,"
@
"
表
示
所
有
的
目
标
的
挨
个
值
,
"
@"表示所有的目标的挨个值,"
@"表示所有的目标的挨个值,"<“表示了所有依赖目标的挨个值。这些奇怪的变
量我们叫"自动化变量”,后面会详细讲述。
CPP C程序的预处理器(输出是标准输出设备)。默认命令是“$(CC) –E”。
CFLAGS C语言编译器参数。
CPPFLAGS C预处理器参数。( C 和 Fortran 编译器也会用到)。
LDFLAGS 链接器参数。(如:“ld”)
( @ D ) 表 示 " (@D) 表示" (@D)表示"@“的目录部分(不以斜杠作为结尾),如果” @ " 值 是 " d i r / f o o . o " , 那 么 " @"值是"dir/foo.o",那么" @"值是"dir/foo.o",那么"(@D)“就是"dir”,而如果"$@“中没有包含斜杠的话,其值就是”."(当前目录)。
( @ F ) 表 示 " (@F) 表示" (@F)表示"@“的文件部分,如果” @ " 值 是 " d i r / f o o . o " , 那 么 " @"值是"dir/foo.o",那么" @"值是"dir/foo.o",那么"(@F)“就是"foo.o”," ( @ F ) " 相 当 于 函 数 " (@F)"相当于函数" (@F)"相当于函数"(notdir $@)"。
@ 表 示 规 则 中 的 目 标 文 件 集 。 在 模 式 规 则 中 , 如 果 有 多 个 目 标 , 那 么 , " @ 表示规则中的目标文件集。在模式规则中,如果有多个目标,那么," @表示规则中的目标文件集。在模式规则中,如果有多个目标,那么,"@"就是匹配于目标中模式定义的集合。
< 依 赖 目 标 中 的 第 一 个 目 标 名 字 。 如 果 依 赖 目 标 是 以 模 式 ( 即 " < 依赖目标中的第一个目标名字。如果依赖目标是以模式(即"%")定义的,那么" <依赖目标中的第一个目标名字。如果依赖目标是以模式(即"<"将是符合模式的一系列的文件集。注意,其是一个一个取出来的。
仅
当
目
标
是
函
数
库
文
件
中
,
表
示
规
则
中
的
目
标
成
员
名
。
例
如
,
如
果
一
个
目
标
是
"
f
o
o
.
a
(
b
a
r
.
o
)
"
,
那
么
,
"
% 仅当目标是函数库文件中,表示规则中的目标成员名。例如,如果一个目标是"foo.a(bar.o)",那么,"
仅当目标是函数库文件中,表示规则中的目标成员名。例如,如果一个目标是"foo.a(bar.o)",那么,"%“就是"bar.o”,"$@“就是"foo.a”。如果目标不是函数库文件(Unix下是
[.a],Windows下是[.lib]),那么,其值为空。
$?
所有比目标新的依赖目标的集合。以空格分隔。
$^
所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。
+ 这 个 变 量 很 像 " + 这个变量很像" +这个变量很像"^",也是所有依赖目标的集合。只是它不去除重复的依赖目标。
AR 函数库打包程序。默认命令是“ar”。
AS 汇编语言编译程序。默认命令是“as”。
CC C语言编译程序。默认命令是“cc”。
CXX C++语言编译程序。默认命令是“g++”。
CO 从 RCS文件中扩展文件程序。默认命令是“co”。
CPP C程序的预处理器(输出是标准输出设备)。默认命令是“$(CC) –E”。
FC Fortran 和 Ratfor 的编译器和预处理程序。默认命令是“f77”。
GET 从SCCS文件中扩展文件的程序。默认命令是“get”。
LEX Lex方法分析器程序(针对于C或Ratfor)。默认命令是“lex”。
PC Pascal语言编译程序。默认命令是“pc”。
YACC Yacc文法分析器(针对于C程序)。默认命令是“yacc”。
YACCRYacc文法分析器(针对于Ratfor程序)。默认命令是“yacc –r”。
MAKEINFO 转换Texinfo源文件(.texi)到Info文件程序。默认命令是“makeinfo”。
TEX 从TeX源文件创建TeX DVI文件的程序。默认命令是“tex”。
TEXI2DVI 从Texinfo源文件创建军TeX DVI 文件的程序。默认命令是“texi2dvi”。
WEAVE 转换Web到TeX的程序。默认命令是“weave”。
CWEAVE 转换C Web 到 TeX的程序。默认命令是“cweave”。
TANGLE 转换Web到Pascal语言的程序。默认命令是“tangle”。
CTANGLE 转换C Web 到 C。默认命令是“ctangle”。
RM 删除文件命令。默认命令是“rm –f”。
一、make的退出码
make命令执行后有三个退出码:
0 —— 表示成功执行。
1 —— 如果make运行时出现任何错误,其返回1。
2 —— 如果你使用了make的“-q”选项,并且make使得一些目标不需要更新,那么返回2。
GNU make找寻默认的Makefile的规则是在当前目录下依次找三个文件——“GNUmakefile”、“makefile”和“Makefile”。其按顺序找这三个文件,一旦找到,就
开始读取这个文件并执行。
发布时,特别是GNU这种开源软件的发布时,其 makefile都包含了编译、安装、打包等功能。我们可以参照这种规则来书写我们的makefile中的目标。
“all” 这个伪目标是所有目标的目标,其功能一般是编译所有的目标。
“clean” 这个伪目标功能是删除所有被make创建的文件。
“install” 这个伪目标功能是安装已编译好的程序,其实就是把目标执行文件拷贝到指定的目标中去。
“print” 这个伪目标的功能是例出改变过的源文件。
“tar” 这个伪目标功能是把源程序打包备份。也就是一个tar文件。
“dist” 这个伪目标功能是创建一个压缩文件,一般是把tar文件压成Z文件。或是gz文件。
“TAGS” 这个伪目标功能是更新所有的目标,以备完整地重编译使用。
“check”和“test” 这两个伪目标一般用来测试makefile的流程。
有时候,我们不想让我们的makefile中的规则执行起来,我们只想检查一下我们的命令,或是执行的序列。于是我们可以使用make命令的下述参数:
“-n”
“–just-print”
“–dry-run”
“–recon”
不执行参数,这些参数只是打印命令,不管目标是否更新,把规则和连带规则下的命令打印出来,但不执行,这些参数对于我们调试makefile很有用处。
“-t”
“–touch”
这个参数的意思就是把目标文件的时间更新,但不更改目标文件。也就是说,make假装编译目标,但不是真正的编译目标,只是把目标变成已编译过的状态。
“-q”
“–question”
这个参数的行为是找目标的意思,也就是说,如果目标存在,那么其什么也不会输出,当然也不会执行编译,如果目标不存在,其会打印出一条出错信息。
“-W ”
“–what-if=”
“–assume-new=”
“–new-file=”
这个参数需要指定一个文件。一般是是源文件(或依赖文件),Make会根据规则推导来运行依赖于这个文件的命令,一般来说,可以和“-n”参数一同使用,来查看这个依赖文件
所发生的规则命令。
另外一个很有意思的用法是结合“-p”和“-v”来输出makefile被执行时的信息(这个将在后面讲述)。
五、make的参数
下面列举了所有GNU make 3.80版的参数定义。其它版本和产商的make大同小异,不过其它产商的make的具体参数还是请参考各自的产品文档。
“-b”
“-m”
这两个参数的作用是忽略和其它版本make的兼容性。
“-B”
“–always-make”
认为所有的目标都需要更新(重编译)。
“-C
“–directory=
指定读取makefile的目录。如果有多个“-C”参数,make的解释是后面的路径以前面的作为相对路径,并以最后的目录作为被指定目录。如:“make –C ~hchen/test –C prog”
等价于“make –C ~hchen/test/prog”。
例如,把[.c]文件编译成[.o]文件这一规则,你根本就
不用写出来,make会自动推导出这种规则,并生成我们需要的[.o]文件。