Make脚本的基本语法:
目标(target) : 条件(prerequest) (Tab键) 命令
- target ~任意一个字符串名称/具体文件的名称。
- prerequest ~其他目标的名称/具体文件的名称。
执行Make脚本时,Make解释器会检查target和prerequest中包含的文件时间戳是否相同,如果不同的话,解释器就会执行Tab键后面的“命令”,命令可以是任意可执行程序。
一个简单的Makefile文件
#Filename Makefile
#this file is used for show how to use makefile
$(info start working)
hello: hello.c
echo hello.c -o hello.bin
hello.bin: hello.c
@echo "now make hello.bin"
gcc hello.c -o hello.bin
.PHONY:he
he: hello.c
@echo "now make he"
gcc hello.c -o hello.bin
-
#
~ 注释符 -
$
~ 函数调用符号,info是一个函数名称,作用是输出一段信息。 - 目标定义前不能加任何空格,而命令行前必须以
Tab键
开始。 -
.PHONY
~ 声明一个目标,将总是执行其指定的命令。 -
@
~ 不显示被执行的命令。 - 对于hello.bin目标,该目标本身就是一个文件,其依赖的文件是hello.c文件。
运行:
$make -f Makefile hello
-
-f
~ 指定要执行的脚本文件的名称
变量的定义与赋值
-
:=
~ 简单展开型 -
=
~ 递归展开型 -
?=
~ 条件赋值 -
+=
~附加赋值
Make解释器执行脚本的过程:
- 装载Makefile及Makefile中include的其他Makefile。
- 根据用户指定的target找出该target的全部依赖关系,并判断依赖条件中的时间戳。
条件控制语句
- 在解析器解析脚本文件时处理
- 在执行脚本文件时处理
语法模型1:
if-condition
text if the condition is true
endif
语法模型2:
if-condition
text if the condition is true
else
text if the condition is false
endif
if-condition只能进行两种判断:
- 判断表达式是否相等
ifeq test
/ifneq test
- 判断表达式是否被定义
ifdef var
/ifndef var
宏(函数)定义
Make脚本中函数,按被调用的方式可分为三类:
内置函数 ~ Make解释器内部定义好的函数
调用:$(fname, param...)
用户定义的、带参数的函数,使用define关键字进行调用
调用:$(call fname, param)
-
用户定义的、不带参数的函数(宏)
调用:$ (fname)
用户函数的定义方式:
define fname
各种具体的命令
endef
举例:
define showFirstName
@echo $(1)
endef.PHONY: name name: $(call showFirstName, Nancymi, Yang)
执行结果:
$ make name
Nancymi
内置符号和变量
内置符号
-
$@
~ target的名称 -
$*
~ 不包含target后缀的target名称 -
$^
~所有的先决条件的名称,不包含重复的 -
$?
~ 有更新的先决条件列表 -
$+
~ 所有的先决条件,包含了重复的 -
$<
~ 第一个先决条件的名称
内置变量 -
MAKE_VERSION
~ make版本 -
CURDIR
~ 执行make的目录 -
MAKEFILE_LIST
~ 本次make命令执行时,所有被包含的makefile列表 -
VARIABLE
~ 所有的变量列表 -
CC
~ C编译器(默认gcc) -
CXX
~ C++ 编译器(默认g++) -
CXXFLAGS
~ C++的编译选项 -
CPPFLAGS
~ 仅为.cpp文件的编译选项 -
TARGET_ARCH
~ 目标主机架构 -
LDLIBS
~ 连接器库选项
模板目标(Pattern target)
使用一种“模板”来定义目标。
源脚本文件:
.PHONY: test
test: f21.o f2.o main.o
gcc -o main.bin f1.o f2.o main.o
f1.o: f1.c
gcc f1.c f1.o
f2.o: f2.c
gcc f2.c f2.o
main.o: main.c
gcc main.c -c main.o
使用模板目标后:
OBJ = f1.o f2.o main.o
.PHONY: test
test: $(OBJ)
gcc $(OBJ) -o main.bin
%.o: %.c
gcc -c -o $@ $<
-
%.o
~ 模板目标 -
%
~ 模板通配符,所有.o文件
目标特定的变量赋值(Target-specific variable)
CFLAGS = -c
.PHONY: tar1
tar1:
gcc $(CFLAGS) main.c
在以上脚本文件中,CFLAGS被赋为"-c",且对整个脚本文件有效。所以在执行Makefile tar1
时,会执行gcc -c main.c
.
如果在该脚本文件中另一目标想用自己特定的CFLAGS变量,可进行局部变量赋值:
tar2:CFLAGS = -c
tar2:
gcc $(CFLAGS) main.c
如果用户想在命令行中对变量进行赋值:$ make tar2 0e CFLAGS="-c -g"
.
如果Makefile文件不允许用户自己进行赋值,也就是必须强制使用Makefile文件中的赋值:
tar2: override CFLAGS = -c
tar2:
gcc $(CFLAGS) main.c
常用选项
不多说了,直接man make查看。