type
status
date
slug
summary
tags
category
icon
password
前言:
这是一篇我学习Makefile时记录的学习笔记
一、语法规则
一个 Makefile 由一组规则组成,规则通常如下所示:
- 目标
target是文件名(或伪目标),以空格分隔。通常每条规则只有一条。
- 命令
command是生成目标的一系列步骤。以制表符开头,不能用空格开头
- 先决条件(依赖)
prerequisites是文件名(或伪目标),以空格分隔。这些文件需要在执行命令之前存在
上述其实是描述了一个文件依赖关系,即生成一个或多个
target 依赖于 prerequisites ,生成规则定义在 command中。示例:
# 开头的为注释执行:
再次执行:
二、all
如果 Makefile 中定义了多个目标,通常定义一个 all 目标来生成所有目标, 而且通常我们还习惯将 all 目标放在 Makefile 文件的第一个目标,或者设置 .DEFAULT_GOAL, 这样我们使用 make 就会默认执行 all 目标。
Makefile 中第一个目标会作为其默认目标,直接使用 make 即可,无需制定target。当然你也可以通过 .DEFAULT_GOAL 指定某个 target 为默认的 target
2.1 伪目标
上述的 clean 并不会真的生成一个 clean 文件,如果恰巧你的目录下面刚好有一个 clean 文件,make 就会提示:
为了避免和文件重名的情况,我们可以使用一个特殊的标记
.PHONY 来显式指明一个目标是“伪目标”,向 make 说明,不管是否有这个文件,这个目标都是“伪目标”。目标可以成为依赖,伪目标同样可以成为依赖
2.2 多行
当命令太长,反斜杆
\ 字符使我们能够使用多行(和shell类似)三、变量
变量是把一个名字和任意长的字符串关联起来。基本语法如下:
使用
${}或 $()来引用变量示例:
3.1 变量定义
=仅在使用命名时解析变量值
:=在定义时立即解析变量值
示例:
B 最后的值为 c b,而不是 a b。也就是说,在用变量给变量赋值时,右边变量的取值,取的是最终的变量值。
?=如果该变量没有被赋值,则赋值等号后面的值
B 最后的值为 a b。通过 := 的赋值方式,可以避免 = 赋值带来的潜在的不一致。
追加:
+=表示将等号后面的值添加到前面的变量上。
Makefile 还支持多行变量。可以通过 define 关键字设置多行变量,变量中允许换行。定义方式为:
3.2 环境变量
Makefile 还支持环境变量。在 Makefile 中,有两种环境变量,分别是 Makefile 预定义的环境变量和自定义的环境变量。
其中,自定义的环境变量可以覆盖 Makefile 预定义的环境变量。默认情况下,Makefile 中定义的环境变量只在当前 Makefile 有效,如果想向下层传递(Makefile 中调用另一个 Makefile),需要使用
export 关键字来声明。3.3 空格
行尾的空格不会被删除,但开头的空格会被删除
示例:
未定义的变量时机上是一个空字符串
3.4 自动变量
makefile定义了一些自动变量,用于自动获取一些值,比如:
$@规则目标的文件名
$<第一个先决条件的名称
$?比目标新的所有先决条件的名称,它们之间有空格
$^所有先决条件的名称,它们之间有空格
示例:
四、通配符
- 成为通配符
- 可以在目标、先决条件或
wildcard函数(查找指定目录下指定类型的文件)中使用
- 不能在变量定义中直接使用
- 当没有匹配到文件时,就会直接输出(保持原样),所以我们一般都是配合
wildcard函数使用
示例:
五、静态模式规则
静态模式规则可以更容易地定义多目标的规则,可以让我们的规则变得更加有弹性和灵活。
静态模式规则的语法:
匹配
target-pattern 生成 target, 匹配 prereq-patterns 生成 target-pattern示例:
使用静态规则后:
5.1 filter
filter函数可用于静态模式规则匹配正确的文件%匹配任何非空字符串
六、双冒号
双冒号规则很少使用,它允许为同一个目标定义多个规则
示例:
如果这些是单冒号,则会打印一条警告,并且只会运行第二条命令
七、命令
7.1 显示与隐藏
在命令之前添加
@ 以阻止它被打印也可以运行
make 时使用 -s参数,这会为每一行命令添加一个 @7.2 执行
每个命令都在一个新的 shell 中执行(至少效果是这样的)
比如:
7.3 默认 shell
默认 shell 是
/bin/sh,也可以通过更改变量 SHELL 来改变它:7.4 递归使用make
要递归调用makefile, 需要使用
$(MAKE)变量代替 make它会为你传递 make 标志并本身不会受到它们的影响
7.5 创建多个目标
make clean run test运行clean目标,然后run,然后test7.6 define
define实际上就是一个命令列表示例:
7.7 局部变量
八、条件
8.1 ifelse
值相等:
值不相等:
判空:
判断变量是否被定义:
九、函数
函数主要用于文本处理。使用
$(fn, argument)调用函数9.1 subst
用法是
$(subst FROM, TO, TEXT), 将TEXT中的内容由FROM变味TO示例:
打印:I am totally superman
打印: a,b,c
9.2 pathsubst
模式字符串替换函数
格式:
$(pathsubst <pattern>,<replacement>,<text>)查找
<text>中的单词是否符合模式<pattern>, 如果匹配的话,则以<replacement>替换。替换引用
$(test:pattern=replacement)是对此的简写示例:
输出:echoecho a.c b.c 1.a c.c a.c b.c 1.a c.c echo a.c b.c 1.a c.c a.c b.c 1.a c.c
9.3 foreach
$(foreach var,list,text): 将一个单词列表(由空格分隔)转换为另一单词列表。list代表单词列表,var设置列表中的每个单词,text针对每个单词进行扩展示例:
输出:who! are! you!
9.4 if
if检测第一个参数是否为空,如果是,则运行第二个参数,否则运行第三个。输出:then! else!
9.5 call
有点相当于我们自定义函数,
$(call variable, param, param, ...): 在执行时,将它的参数 param 依次赋给 variable 中的临时变量 ${1}, ${2}等${0}可以获取variable变量名称示例:
输出:variable name: sweet_new_fn first: go second: git empty variable:
9.6 shell
shell 函数就是调用 shell
十、包含
include 指令告诉 make 读取一个或多个其他 makefile
十一、vpath
使用 vpath 指定某些先决条件存在的位置
格式:
vpath <pattern> <directories, spcase/colon separated><pattern>可以有一个%,用于匹配零个或多个字符比如:
代表要求 make 在
../headers目录下搜索所有以.h结尾的文件,前提是当前目录没有找到示例:
- 作者:Venture
- 链接:https://jintao123.top//article/makefile
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。



