= 赋值
name=miss you
build:
@echo $(name)
make 的输出结果是 miss you
, name只取最后设置的值
使用 =
赋值,只取最后设置的值
name=see
content=$(name) you
name=miss
build:
@echo $(content)
:= 赋值
使用 :=
赋值,最右边的只取当前值,即为最终值
所以 content
取的值为 see you
,而非 miss you
name=see
content:=$(name) you
name=miss
build:
@echo $(content)
+= 追加
content = how
content += are
content += you
all:
@echo $(content)
?= 赋值
=
和 :=
赋值在重新赋值时,都会覆盖原有的值
?=
会判断是否设置过,没设置过才赋值,设置过就使用原来的值
example1
第二次覆盖第一次,输出 miss
name=see
name=miss
build:
@echo $(name)
example2
第二次覆盖第一次,输出 miss_2
name:=see
name:=miss_2
build:
@echo $(name)
example3
?=
赋值,由于已经设置过name:= see
, 所以 name?=miss_2
会使用原来的值 see
name:=see
name?=miss_2
build:
@echo $(name)
+= 追加
content = how
content += are
content += you
all:
@echo $(content)
多行变量
使用 define
+ endef
定义,格式如下:
define 变量名
变量内容......
endef
注意事项,define 定义作为变量,则不能在 makefile 中 使用,需要导出作为环境变量使用
wrong:
define options
options:
6666666666
endef
all:
@echo $(options)
rigth:
define options
options:
6666666666
endef
# 导出作为环境变量
export options
all:
@echo "$$options"
环境变量
$$<环境变量名>
all:
@echo "$$WORKSPACE"
Makefile中变量名和外部环境变量名相同时,会临时覆盖环境变量,临时
是指 Makefile 执行完后,外部的环境变量并不会改变(这是由于makefile 是 fork 出子进程去执行 command )
# 和外部的环境变量 WORKSPACE 相同 临时覆盖
WORKSPACE = "/xyz/workspace"
WORKSPACE2 = "/abc/workspace"
all:
@echo "$$WORKSPACE"
next:
# 外部没有 WORKSPACE2 环境变量,用 $$ 无效
@echo "$$WORKSPACE2"
after:
# right 使用普通变量的输出方式
@echo $(WORKSPACE2)
导入变量
当外部未定义环境变量 A
, 但是又需要环境变量 A
时,可以通过 export A
为 A 临时设置值
echo.sh:
# 未定义环境变量 WORKSPACE3
echo $WORKSPACE3
Makefile:
WORKSPACE3 = 222
export WORKSPACE3
target:
./echo.sh
特殊变量
Makefile中为我们定义好的变量,拿来使用即可
变量 | 含义 |
---|---|
MAKE | 当前make解释器的文件名 |
MAKECMDGOALS | make 命令行参数 |
CURDIR | make 解释器工作目录 |
MAKE_VERSION | make 解释器版本 |
MAKEFILE_LIST | make 解释器需要处理的 makefile 文件列表 |
.DEFAULT_GOAL | 未命中指定 target 时,默认执行的 target |
.VARIABLES | 已定义变量名列表 |
.FEATURES | 列出版本支持功能 |
.INCLUDE_DIRS | include makefile 的查找路径 |
Makefile(/root/study):
include B.mk
all:
@echo "MAKE is $(MAKE)" # make
@echo "MAKECMDGOALS is $(MAKECMDGOALS)" # all
@echo "CURDIR is $(CURDIR)" # /root/study
@echo "MAKE_VERSION is $(MAKE_VERSION)" # 3.82
@echo "MAKEFILE_LIST is $(MAKEFILE_LIST)" # Makefile /usr/include/B.mk
@echo ".INCLUDE_DIRS is $(.INCLUDE_DIRS)" # /usr/include /usr/local/include /usr/include
@echo ".DEFAULT_GOAL is $(.DEFAULT_GOAL)" # build
@echo ".FEATURES is $(.FEATURES)" # target-specific order-only second-expansion else-if shortest-stem undefine oneshell archives jobserver check-symlink
@echo ".VARIABLES is $(.VARIABLES)" # <D ?F .SHELLFLAGS CWEAVE ?D @D @F MAKE_VERSION CURDIR SHELL RM CO COMPILE.mod _ PREPROCESS.F LINK.m LINK.o OUTPUT_OPTION GOVERSION COMPILE.cpp MAKEFILE_LIST HISTCONTROL GO111MODULE LINK.p CC CHECKOUT,v LESSOPEN CPP GOPROXY LINK.cc SSH_CONNECTION PATH LD TEXI2DVI YACC SSH_TTY XDG_RUNTIME_DIR ARFLAGS LINK.r LINT COMPILE.f LINT.c YACC.m GOPATH YACC.y AR .FEATURES TANGLE LS_COLORS ST %F COMPILE.F CTANGLE .LIBPATTERNS GO_INSTALL_DIR LINK.C PWD LINK.S PREPROCESS.r *D LINK.c LINK.s HOME LOGNAME ^D HOSTNAME MAKELEVEL COMPILE.m MAKE SHLVL AS PREPROCESS.S COMPILE.p XDG_SESSION_ID USER FC .DEFAULT_GOAL GOROOT %D GOSRC WEAVE MAKE_COMMAND LINK.cpp F77 OLDPWD .VARIABLES PC *F COMPILE.def LEX MAKEFLAGS MFLAGS SSH_CLIENT MAIL LEX.l LEX.m +D COMPILE.r GOSUMDB +F M2C GET WORKSPACE MAKEFILES COMPILE.cc <F IAM_ROOT CXX COFLAGS COMPILE.C ^F COMPILE.S LINK.F SUFFIXES HISTSIZE COMPILE.c COMPILE.s .INCLUDE_DIRS .RECIPEPREFIX MAKEINFO OBJC TEX LANG TERM F77FLAGS LINK.f
B.mk(/usr/include/B.mk):
build:
@echo ok
result:
B.mk 和 Makefile 不在一个目录,且 /root/study 下 没有 B.mk, 然后会去 .INCLUDE_DIRS 提供的目录中去查找
自动化变量
表示 target 或 依赖中的值(全部或部分)
变量 | 含义 |
---|---|
$@ | 代表 target |
$< | 第一个依赖项 |
$^ | 所有依赖项(去重) |
$+ | 所有依赖项(不去重) |
$* | % 所匹配值 |
$% | a(b) 这种格式中的 b |
$| | order-only 依赖项 |
$? | 比目标还新的依赖项目 |
main: main.go yzt.go
# go build -o main main.go
go build -o $@ $<
echo: main.go yzt.go
# output: main.go yzt.go
@echo $^
only: main.go | yzt.go
# output: 输出 order-only 依赖项
@echo $|
fn(c) : main.go
# output: c
@echo $%
repeat: main.go main.go
# output: main.go main.go
@echo $+
yzt: yzt.go main.go
@echo $?
go build yzt.go
a.%.b:
@echo $*
$%
target 要 满足 a(b)
这种格式
Makefile:
f(c):
@echo $%
kk:
@echo $%
$?
- main 依赖 main.go yzt.go
- 在 T1 时刻进行构建,生成 main
- 在 T2 时刻再执行构建,并不会生成 main,即不会执行
- 在 T3 时刻再修改 yzt.go 再构建,会执行
再 T3 时刻 输出 $?
即为 yzt.go
Makefile:
结束语
Makefile 基础知识请参考
Makefile 基础知识