时间:2018-02-26
作者:魏文应
Makefile 的变量
下面是定义makefile:
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
然后引用变量:
$(objects)
makefile中的变量只是简单引用替换,和C语言的宏很像,比如:
# 定义了一个变量
srcdir = ../../../src
# 引用变量
cd $(srcdir)
# 这里就是简单替换,等价于
cd ../../../src
不要在变量定义同一行中使用 # 号来注释:
# 如何表示一个值为空格的变量呢?
# 定义了一个空变量nullstring,space的值就以nullstring变量为起点,以 # 结束
nullstring :=
space := $(nullstring) #
# 下面的定义,dir的值是 **/usr/bin 加上 $(srcdir)和#之间的那4个空格**,显然不是我们想要的
srcdir := /usr/bin
dir := $(srcdir) #
Makefile 中的 := 符号
符号 := 说明,不能引用后面定义的变量:
# 引用前面定义
# 那么展开y就等价于 y := foo bar
x := foo
y := $(x) bar
# 不引用后面的
# 那么展开y就等价于 y := bar
y := $(x) bar
x := foo
Makefile 中的 ?= 符号
表示如果之前FOO没有定义过,就给它赋值为bar,如果已经定义过,就不重新赋值了,保持原来的。
FOO ?= bar
Makefile 的自动推导
GNU make 功能比较强大,它会做一些推导。假设有一个 main.c 源代码文件,内容如下:
# include <stdio.h>
void main(void)
{
print("hello world!!!")
}
那么编译这个 main.c 文件时,要生成 main.o,这main.o文件要依赖 main.c和stdio.h 这两个文件来生成,正常我们这么写:
main.o : main.c stdio.h
有了自动推导功能以后,make 工具可以自动认为 main.o 文件有一个默认的依赖,那就是main.c文件,所以等价的写法如下:
main.o : stdio.h
Makefile 中的伪目标
makefile中的伪目标其实是标签,比如:
prepare:
@echo \#############
.PHONY clean
clean:
rm -rf output/
上面 prepare 就是伪目标,比如我们执行 make prepare
命令,那么就只执行prepare的内容,而下一个伪目标clean的内容不会得到执行。.PHONY 明确地告诉make工具,这是个伪目标(标签)。如果没有 .PHONY 关键字,make 工具会自动判断。
Makefile 中的 rm 指令前加 ‘-’
比如,有时我们会看到这样的
-rm -rf main.o hello.o
我们在linux的bash命令中,一般是这样执行 rm -rf main.o hello.o
来删除main.o 和hello.o这两个文件的。rm 前加上 “-” ,是告诉make工具,这个指令可能有问题(比如main.o这个文件不存在),但不要管它,继续执行后面的操作。
Makefile 中的注释
makefile使用 # 号来注释,注释里你写什么都行(你开心就好):
# 在这里写注释
.PHONY clean
clean:
-rm -rf output
如果你要引用 ‘#’ 这字符,就使用 转义符加#号:\# 。
Makefile 中的命令
makefile中的命令要以 Tab 键开始(其实很多脚本对缩进是敏感的):
.PHONY clean
clean:
-rm -rf output
你看,这里 -rm -rf output 这个命令前要加 Tab 键进行缩进。
Makefile 的文件名
创建一个makefile,它的文件名一般用 Makefile 、makefile、GNUmakefile 来命名,我们一般用 Makefile 这个名词。当我们用make工具编译链接源代码时,这样 make
这个指令就默认使用当前目录下的这个Makefile脚本了:
# 执行
make
# 相当于
make Makefile
如果你不这么命名,如命名为wifi-makefile,你就需要显式地指定了:
make -f wifi-makefile
Makefile 的模式规则
模式规则就是你定义一个规则,比如:
# 当前目录下的所有.c文件编译生成.o文件
%.o : %.c
# CC是编译器,CFLAGS是C语言编译器参数,
# CPPFLAGS是C预处理器参数,$< 在这里就是挨个的.o文件,
# $@ 在这里就是挨个的.c文件,下面就是生成规则
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
Makefile 的自动化变量
符号 | 描述 |
---|---|
$@ | 所有目标的挨个值 |
$< | 所有依赖的挨个值 |
$(@F) | 取 $@ 中的文件部分,比如$@的值是src/main.c,$(@F) 的值就等于 main.c |
网友评论