target ... : prerequisites ...
command
...
...
make 的参数有很多, 可以通过 make -h 去查看, 下面只介绍几个我认为比较有用的。
参数 | 含义 |
---|---|
--debug[=<options>] | 输出make的调试信息, options 可以是 a, b, v |
-j --jobs | 同时运行的命令的个数, 也就是多线程执行 Makefile |
-r --no-builtin-rules | 禁止使用任何隐含规则 |
-R --no-builtin-variabes | 禁止使用任何作用于变量上的隐含规则 |
-B --always-make | 假设所有目标都有更新, 即强制重编译 |
OBJS = programA.o programB.o
OBJS-ADD = $(OBJS) programC.o
# 或者
OBJS := programA.o programB.o
OBJS-ADD := $(OBJS) programC.o
SRCS := programA.c programB.c programC.c
SRCS += programD.c
作用是使变量的作用域仅限于这个目标(target), 而不像之前例子中定义的变量, 对整个Makefile都有效.
语法:
<target ...> :: <variable-assignment>
<target ...> :: override <variable-assignment>
(override作用参见 变量覆盖的介绍)# Makefile 内容
SRCS := programA.c programB.c programC.c
target1: TARGET1-SRCS := programD.c
target1:
@echo "SRCS: " $(SRCS)
@echo "SRCS: " $(TARGET1-SRCS)
target2:
@echo "SRCS: " $(SRCS)
@echo "SRCS: " $(TARGET1-SRCS)
# bash中执行make
$ make target1
SRCS: programA.c programB.c programC.c
SRCS: programD.c
$ make target2 <-- target2中显示不了 $(TARGET1-SRCS)
SRCS: programA.c programB.c programC.c
SRCS:
Makefile 中书写shell命令时可以加2种前缀 @ 和 -, 或者不用前缀.
伪目标并不是一个"目标(target)", 不像真正的目标那样会生成一个目标文件.
典型的伪目标是 Makefile 中用来清理编译过程中中间文件的 clean 伪目标, 一般格式如下:
.PHONY: clean <-- 这句没有也行, 但是最好加上
clean:
-rm -f *.o
语法: include <filename> (filename 可以包含通配符和路径)
# Makefile 内容
all:
@echo "主 Makefile begin"
@make other-all
@echo "主 Makefile end"
include ./other/Makefile
# ./other/Makefile 内容
other-all:
@echo "other makefile begin"
@echo "other makefile end"
# bash中执行 make
$ ll
total 20K
-rw-r--r-- 1 wangyubin wangyubin 125 Sep 23 16:13 Makefile
-rw-r--r-- 1 wangyubin wangyubin 11K Sep 23 16:15 makefile.org <-- 这个文件不用管
drwxr-xr-x 2 wangyubin wangyubin 4.0K Sep 23 16:11 other
$ ll other/
total 4.0K
-rw-r--r-- 1 wangyubin wangyubin 71 Sep 23 16:11 Makefile
$ make
主 Makefile begin
make[1]: Entering directory `/path/to/test/makefile'
other makefile begin
other makefile end
make[1]: Leaving directory `/path/to/test/makefile'
主 Makefile end
这里只列一个和编译C相关的.
编译C时,<n>.o 的目标会自动推导为 <n>.c
# Makefile 中
main : main.o
gcc -o main main.o
#会自动变为:
main : main.o
gcc -o main main.o
main.o: main.c <-- main.o 这个目标是隐含生成的
gcc -c main.c
自动变量 | 含义 |
---|---|
$@ | 目标集合 |
$% | 当目标是函数库文件时, 表示其中的目标文件名 |
$< | 第一个依赖目标. 如果依赖目标是多个, 逐个表示依赖目标 |
$? | 比目标新的依赖目标的集合 |
$^ | 所有依赖目标的集合, 会去除重复的依赖目标 |
$+ | 所有依赖目标的集合, 不会去除重复的依赖目标 |
$* | 这个是GNU make特有的, 其它的make不一定支持 |
一种简写,可以让多个目标操作顺次执行
all: server.out client.out
objects = server.cpp
server.out : $(objects)
g++ -o server.out $(objects)
client.out : client.cpp
g++ -o client.out client.cpp
直接 make 或 make all 的话会执行 server.out 和client.out 的编译命令,后面不加参数的话,会把第一个目标作为默认的。