..

Makefile相关知识点

开源项目中非常流行使用Makefile来处理构建的问题,我比较喜欢使用Makefile来给命令行分组。Makefile文件前面的缩进不是空格,这个写Makefile前一定要明确的问题。

[jukay@mac-pro]~/Desktop$ cat Makefile
test:
	echo Hello World
[jukay@mac-pro]~/Desktop$ make
echo Hello World
Hello World
[jukay@mac-pro]~/Desktop$

make命令会自动寻找当前目录下面的名字叫做Makefile的文件,可能使用make -f filename来指定其他文件,找到了文件以后构建你指定的产物,如果没有指定产物,那么会默认构建第一个产物,如果产物已经存在了,那么不会执行构建流水了。例如,当前目录下面已经存在了一个名字为 test 文件,那么执行 make test 是不会执行构建的。

[infra@dev ~]$ ls
Makefile  test
[infra@dev ~]$ make test
make: “test”是最新的。
[infra@dev ~]$ make
make: “test”是最新的。
[infra@dev ~]$

这里在shell命令前面加上@符号,是表示在指定当前命令的会后,不要打印这条命令的指定过程。如果当前的目标产物存在了,但是构建目标产物还需要其他依赖,那么还是会重新构建当前目标产物的

[infra@dev ~]$ ls
Makefile  test
[infra@dev ~]$ cat Makefile
test: dev
	@echo Hello World
dev:
	@echo dev
[infra@dev ~]$ make test
dev
Hello World
[infra@dev ~]$

make也是可以一次构建两个产物的

[infra@dev ~]$ cat Makefile
test:
	@echo Hello World
dev:
	@echo dev
[infra@dev ~]$ make test dev
Hello World
dev
[infra@dev ~]$

Makefile执行shell的过程中,如果当前的命令返回了非0值,那么当前的整个构建就会报错终止,但是也有忽略报错的方法:在命令行的前面加上-符号。

[infra@dev ~]$ cat Makefile
test:
	@echo begin
	-exit 1
	@echo end

[infra@dev ~]$ make test
begin
exit 1
make: [test] 错误 1 (忽略)
end
[infra@dev ~]$

同时加上-@符号,既不会打印当前命令,也不会因为报错终止构建,并且两个符号没有顺序要求。

[infra@dev ~]$ cat Makefile
test:
	@echo begin
	@-exit 1
	@echo end

[infra@dev ~]$

Makefile中支持使用变量

[infra@dev ~]$ cat Makefile
test:
	@echo $(name)
[infra@dev ~]$ make name=jukay
jukay
[infra@dev ~]$

也能预先定义这个变量,给变量附一个默认值

[infra@dev ~]$ cat Makefile
name := hello
test:
	@echo $(name)
[infra@dev ~]$ make
hello
[infra@dev ~]$ make name=jukay
jukay
[infra@dev ~]$

Makfile支持在一个文件中使用include导入另外一个文件,并且可以直接构建被导入的文件的中目标

[infra@dev ~]$ cat Makefile
include common
name := hello
test:
	@echo $(name)
[infra@dev ~]$