解释如下:
(1)Makefile中的自动化变量 $@, $^, $<,$? 的意思:
$@ 表示目标文件
$^ 表示所有的依赖文件
$< 表示第一个依赖文件
$? 表示比目标还要新的依赖文件列表
(2)wildcard、notdir、patsubst均是makefile内置函数,各个意思如下:
wildcard : 扩展通配符;
notdir : 去除路径;
patsubst :替换通配符。
(3)上面的makefile模板一点需要注意的是,并未给每一个obj目标文件的添加头文件依赖,只也就是说这样做的后果是修改了某个头文件之后,并不会重新编译使用了该头文件的源文件,请大家注意。
那么如果解决这个遗憾呢?其实可以让编译器自动推导源文件使用了哪些头文件,这样我们就可以将源文件使用的头文件添加到目标obj文件的依赖项中,读者可参考网上的资料,自行给出实现。
(4)其实,上面的makefile模板可以写的更优雅一点,改进地方有两点。
(4.1)将多个源文件目录写到一个变量,然后再利用makefile的shell函数将所有源文件目录下源文件取出。参考如下代码:
DIR_SRC=./src0 ./src1
SRC=$(shell for dir in ${CPPDIRS};do echo $${dir}/*.cpp;done)
这个也是下面一个知识点讲解的内容。
(4.2)不必为多个源文件目录添加多个生成目标文件的编译语句,可以使用一条语句搞定,但需要修改makefile的环境变量VPATH让make自动寻找依赖项所在路径。这里需要满足一点要求是不同目录下的源文件不能重名。
VPATH+=dir1:dir2:...
${DIR_O}/%.o:%.cpp
$(CC) $(CFLAGS) -c $< -o $@ ${INCDIR}
此外,要想通过g++编译生成动态链接库或静态链接库,可以参考linux: 几个常用makefile模板。大家也可以举一反三,给出自己的makefile模板。
makefile可以内嵌shell脚本,但是在内嵌的shell脚本只能读取makefile的变量,如何给makefile变量赋值呢?我目前还不知道,知道的网友请留言告知,万分感谢。记录下面不可行的操作:
#makefile
CPPDIRS=mysql src
CPPS=
assign:
for dir in ${CPPDIRS};do CPPS+=$${dir};done;echo ${CPPS}
make assign之后,输出为空,说明这种方式不行。
其实可以使用makefile的shell函数来执行shell脚本,因为shell函数把执行shell脚本后的输出作为函数返回,因此我们可以使用shell函数来为makefile的变量赋值。参考如下代码:
CPPDIRS=mysql src
CPPS=$(shell for dir in ${CPPDIRS};do echo $${dir}/*.cpp;done)
上面的代码就可以将指定的代码源文件目录下的所有源文件连同路径赋给CPPS。
makefile的旧式写法中,可能会出现如下的写法:
.cpp.o:
$(CC) $(INCLUDE) $(CFLAGS) -c $<
.c.o:
$(CC) $(INCLUDE) $(CFLAGS) -c $<
一眼望去,这不合常理啊。为什么目makefile中目标文件没有依赖项。原来这种是老式的“后缀规则”,编译器会自动将makefile所在目录的.cpp识别为源文件后缀,而.o识别为输出文件后缀。特别需要注意的是,后缀规则不允许任何依赖文件,但也不能没有命令。
这种旧式的写法虽然简洁,但是有个两个缺点,一时不能指定源文件所在的目录,二是不能指定目标文件生成后的目录。不太方便,建议还是忍痛割爱放弃这种旧式写法吧。
[1] Makefile经典教程(掌握这些足够)[转].
[2] makefile百度百科
[3]
[4]shell语句中需要分号分隔吗.?url=RzR1wT_CbFT67YEPS-DYAgunOw9NCZl9_cZWVWp3k9sT4KGkRT7ihAuHT43lstEr422WEVFB7hDtLI4zW_Vxt_
[5]makefile中的shell语法.
[6]多个文件目录下Makefile的写法.
[7]makefile里PHONY的相关介绍
[8]makefile中关于all和.PHONY .cpp.o
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-40643-6.html
自始至终都是日舰比北洋多
海军建设还需加油啊
好棒啊