Makefile 变量

= 赋值
name=miss you
build:
	@echo $(name)

image.png

make 的输出结果是 miss you, name只取最后设置的值
使用 = 赋值,只取最后设置的值

name=see
content=$(name) you
name=miss
build:
   @echo $(content)

image.png

:= 赋值

使用 := 赋值,最右边的只取当前值,即为最终值
所以 content 取的值为 see you,而非 miss you

name=see
content:=$(name) you
name=miss
build:
	@echo $(content)
+= 追加
content = how
content += are
content += you
all:
	@echo $(content)

image.png

?= 赋值

=:= 赋值在重新赋值时,都会覆盖原有的值
?= 会判断是否设置过,没设置过才赋值,设置过就使用原来的值

example1

第二次覆盖第一次,输出 miss

name=see
name=miss
build:
	@echo $(name)

image.png

example2

第二次覆盖第一次,输出 miss_2

name:=see
name:=miss_2
build:
	@echo $(name)

image.png

example3

?= 赋值,由于已经设置过name:= see, 所以 name?=miss_2 会使用原来的值 see

name:=see
name?=miss_2
build:
	@echo $(name)
+= 追加
content = how
content += are
content += you
all:
	@echo $(content)

image.png多行变量

使用 define+ endef 定义,格式如下:

define 变量名
变量内容......
endef

注意事项,define 定义作为变量,则不能在 makefile 中 使用,需要导出作为环境变量使用
wrong:

define options
options:
	6666666666
endef

all:
	@echo $(options)

image.png
rigth:

define options
options:
	6666666666
endef
# 导出作为环境变量
export options
all:
	@echo "$$options"

image.png

环境变量

$$<环境变量名>

all:
	@echo "$$WORKSPACE"

image.png
Makefile中变量名和外部环境变量名相同时,会临时覆盖环境变量,临时是指 Makefile 执行完后,外部的环境变量并不会改变(这是由于makefile 是 fork 出子进程去执行 command )

# 和外部的环境变量 WORKSPACE 相同 临时覆盖
WORKSPACE = "/xyz/workspace"
WORKSPACE2 = "/abc/workspace"
all:
	@echo "$$WORKSPACE"
next:
# 外部没有 WORKSPACE2 环境变量,用 $$ 无效
	@echo "$$WORKSPACE2"
after:
# right 使用普通变量的输出方式
	@echo $(WORKSPACE2)

image.png

导入变量

当外部未定义环境变量 A , 但是又需要环境变量 A 时,可以通过 export A 为 A 临时设置值
echo.sh:

# 未定义环境变量 WORKSPACE3
echo $WORKSPACE3

Makefile:

WORKSPACE3 = 222
export WORKSPACE3
target:
	./echo.sh

image.png

特殊变量

Makefile中为我们定义好的变量,拿来使用即可

变量含义
MAKE当前make解释器的文件名
MAKECMDGOALSmake 命令行参数
CURDIRmake 解释器工作目录
MAKE_VERSIONmake 解释器版本
MAKEFILE_LISTmake 解释器需要处理的 makefile 文件列表
.DEFAULT_GOAL未命中指定 target 时,默认执行的 target
.VARIABLES已定义变量名列表
.FEATURES列出版本支持功能
.INCLUDE_DIRSinclude 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:
image.png
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 $*

image.png

$%

target 要 满足 a(b)这种格式
Makefile:

f(c):
	@echo $%
kk:
	@echo $%

image.png

$?
  1. main 依赖 main.go yzt.go
  2. 在 T1 时刻进行构建,生成 main
  3. 在 T2 时刻再执行构建,并不会生成 main,即不会执行
  4. 在 T3 时刻再修改 yzt.go 再构建,会执行

再 T3 时刻 输出 $? 即为 yzt.go
Makefile:
image.png

结束语

Makefile 基础知识请参考
Makefile 基础知识

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值