贡献者: addis
Makefile
的语法虽然类似 bash,但并不是 bash。例如给变量赋值时,bash 不允许等号两边有空格,但 Makefile 可以。
make
命令是可以选择使用多线程,例如 make -j4
使用 4 线程。也可以 make -j`getconf _NPROCESSORS_ONLN`
自动设置为 cpu 的数量。
make -f 文件
make --debug=v
:
后面的文件会按照顺序更新,而且只会更新一次,若以如果更新第二个文件的时候第一个文件被删掉也不会出错。
:
后面可以有 phony target,比如说 make clean
中的 clean
$(var)
和 ${var}
是完全等效的,在双引号内也可以替换。在 rule 的命令中也可以替换。
var1 = $(...)
可以延迟展开,也就是说使用每次 $(var1)
时会重新求一次 $(...)
。如果用 var1 := $(...)
,那么会马上对此时的 $(...)
展开,何时使用 $(var1)
都不受其他因素影响。如果等号右边没有变量,那么两种赋值等效。
$
escape 成 $$
。如 echo $${var}
,此时传给 bash 的命令就是 echo ${var}
。
ifeq ($(var1), true)
var2 = false
else ifneq($(var2), abc)
...
endif
$(info 显示 一些 文字)
会在 make 的时候显示文字到命令行。
Makefile
包含的所有 target,直接在命令行用 make
,空格,然后按两次 tab 自动补全即可。
rm
命令后面记得加 -f
选项,否则如果文件不存在就会出错导致 make 就会失败
goal: file1 file2 ...
command1
command2
MAKEFLAGS = -r
大概是用来取消默认 implicit rules,包括所有后缀名识别
.f90.o:
gfortran -c $<
其中 $<
是 auto variable 中的一个(见 10.5.3 Automatic Variables),在执行的时候被替换成 :
右边的第一个 dependency。现在如果有
file1.o: file1.f90 file2.o file3.o
那么应该会执行 gfortran -c file1.f90
。另外,如果 “file2.o” 或 “file3.o” 被更新了,这条命令应该也会再执行一次。
$^
列出所有的 prerequisites (“:” 右边的内容)
$(shell ...)
可以执行 shell 命令并把命令行输出替换到当前未知,如 $(shell echo *.f90)
可以在当前位置列出所有 “.f90” 文件。如果命令太长可以用 \
换行。注意输出中的换行符会替换为空格。
没用的变量 := $(shell 命令)
。 如果要把结果也输出到命令行,再用 $(info 变量)
即可。赋值一定要有,要不然就相当于把输出的内容直接插入到 Makefile 中造成语法错误。另外赋值一定要用 :=
千万不能用 =
,前者立即展开 $(...)
,后者只有在 没用的变量
被使用时才展开。
$@
大概就是 target file(如果 “:” 左边只有一个文件的话)
source 脚本
会出错,因为默认 shell 是 /bin/sh
。可以用 . 脚本
等效替代。也可以用 SHELL := /bin/bash
。
: 要显示的内容
可以在命令行显示内容。其中 : 命令
不做任何事情。
make VAR1=... VAR2=...
可以设置参数(等号两边不能有空格!),相当于在 Makefile
里面使用 VAR1=... VAR2=...
,如果 Makefile
里面已经设置了这些参数(默认值),那么则会覆盖。
@
就可以不在 std 输出命令的内容。例如 @printf "一些信息"
或者 @echo '一些信息'
Makefile
的 recipe 中可以再次调用 make 目标
,这样可以保证目标按顺序运行,或者 cd ... && make 目标
这样可以更改当前目录。
MAKELEVEL
的值是 0。如果再次使用 make
命令,MAKELEVEL
会递增。
ifeq ($(var), val)
目标1:
命令1
else
目标1:
命令2
endif
$(error 一些 错误 信息)
放在 命令2
里面可以提示错误。
\
换行,缩进可以用多个 tab 或者空格都行。
false
命令会主动返回非 0。
--no-builtin-variables
关闭。
CC
是 C 编译器,CXX
是 C++ 编译器
CFLAGS
是 C 编译器的选项,CXXFLAGS
是 C++ 编译器的选项,FFLAGS
是 Fortran 编译器选项。
$(subst 旧词, 新词, 字符串)
字符串替换
$(addsuffix 后缀, 列表)
把列表中每一个元素后面都加上 后缀
$(addprefix 后缀, 列表)
同理
$(notdir 列表)
把列表中的 目录/文件
变为 文件
。
$(sort 列表)
可以排序并移除列表中重复的元素
$(filter-out 列表, 列表1)
把 列表1
中的元素从 列表
中移除。
include 文件
可以把某个文件的内容插入当前地方,如果文件不存在则会警告,且如果该文件是一个 target,每次用 make
会先检查是否需要更新。若不想要警告,也不想更新,可以用 -include 文件
。
g++
的 -MM
选项可以生成某个 cpp 文件或者 h 文件的所有依赖(包括依赖的依赖)。-MM -nostdinc++
则可以在依赖中去掉标准库中的头文件。用 -include xxx
还可以在依赖中加上 xxx
。
g++
的 -M
选项也一样,但会生成多条依赖关系,每个依赖关系只包含直接依赖。
file: file1 file2
,然后又 file: file3 file4
。但是 recipe 只能有一个,可以写在任意一个依赖关系下面,也可以另外添加一个 file:
然后写在下面。