GNU Makefile--命令行参数的传递

make的命令行变量参数

在Makefile脚本中,可以通过$(MAKE)递归执行其他的Makefile。make的一些命令行选项(例如禁止输出当前目录的选项--no-print-directory等),会对其行为产生一些影响,而递归调用的make也应当继承这一类选项。此外,在编译u-boot或Linux内核等工程时,常用的命令为:

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- ...

命令中的ARCHCROSS_COMPILE两个变量参数也应当在由$(MAKE)递归生成的新的make进程中生效;亦即在sub-make的执行中,也应当默认定义了这两人个变量。而通过查看u-boot/Linux工程中的Makefile脚本,并没有显式传递这两个变量参数的代码。本文记录了笔者探究其实现原理的调试过程。

origin函数查看变量定义源

Makefile的变量有多种定义的方式,例如默认变量、环境变量、文件显式定义、自动变量等。获取某个变量的定义方式,可以增强编译构建的鲁棒性。GNU Make提供了origin函数,可获取某个变量的定义源;从此入手,可以编写以下两个Makefile脚本,探究命令行变量是如何传递给递归执行的make。文件名为Makefile的脚本内容为:

MAKEFLAGS += -r -R
# get the definition origin of `MAKEVAL
MV_ORIG   := $(origin MAKEVAL)
ifeq ($(MAKEVAL),)
MAKEVAL   := defined in makefile
endif

.PHONY: all
all:
	phell -s -p MAKEFLAGS -p MAKEVAL
	@echo "Origin: $(MV_ORIG); invoking sub-make..."
	@echo "------------------------------------------------"
	$(MAKE) --no-print-directory -f dump-env.mk $@

脚本中使用到了phell调试工具,该工具可在笔者的下载区域获得,它的-p选项可以查看某个环境变量的值。不过,不使用phell工具也是可行的,通过echo命令直接输出环境变量值。该脚本通过$(MAKE)调用了一个sub-make,脚本文件dump-env.mk的内容如下:

.PHONY: all
all:
	phell -s -p MAKEFLAGS -p MAKEVAL

下面就要根据这两个Makefile文件来调试分析了。以make -f Makefile命令执行,其结果为:

# make -f Makefile
phell -s -p MAKEFLAGS -p MAKEVAL
****** $ENV{MAKEFLAGS} => rR
****** $ENV{MAKEVAL} has not been defined
Origin: undefined; invoking sub-make...
------------------------------------------------
make --no-print-directory -f dump-env.mk all
phell -s -p MAKEFLAGS -p MAKEVAL
****** $ENV{MAKEFLAGS} => rR --no-print-directory
****** $ENV{MAKEVAL} has not been defined

两个Makefile脚本的结果大致由-----------分隔。$(origin MAKEVAL)的结果为undefined,表明变量未定义,这是正确的结果。Makefile创建的子进程(实际上是/bin/sh的子进程)phell的环境变量MAKEFLAGS的值为rR,而dump-env.mk创建的子进程phell的环境变量MAKEFLAGS的值为rR --no-print-directory,这样就可以解答本文中提到的问题:

GNU Make通过环境变量MAKEFLAGS向递归调用的$(MAKE)传递选项参数(变量参数另议);在sub-make启动时,它会根据命令行选项以及环境变量MAKEFLAGS的值,重新设定MAKEFLAGS

设定环境变量MAKEVAL

设置MAKEVAL环境变量(而非以make的变量参数)并执行make,相应的命令为:

MAKEVAL='Hello World' make -f Makefile

由结果可知,origin可以正确地判定MAKEVAL变量的定义源为environment

phell -s -p MAKEFLAGS -p MAKEVAL
****** $ENV{MAKEFLAGS} => rR
****** $ENV{MAKEVAL} => Hello World
Origin: environment; invoking sub-make...
------------------------------------------------
make --no-print-directory -f dump-env.mk all
phell -s -p MAKEFLAGS -p MAKEVAL
****** $ENV{MAKEFLAGS} => rR --no-print-directory
****** $ENV{MAKEVAL} => Hello World

设定变量参数MAKEVAL

与环境变量的区另是,make的变量参数在其之后指定:

make MAKEVAL='Hello World' -f Makefile

其结果如下:

phell -s -p MAKEFLAGS -p MAKEVAL
****** $ENV{MAKEFLAGS} => rR -- MAKEVAL=Hello\ World
****** $ENV{MAKEVAL} => Hello World
Origin: command line; invoking sub-make...
------------------------------------------------
make --no-print-directory -f dump-env.mk all
phell -s -p MAKEFLAGS -p MAKEVAL
****** $ENV{MAKEFLAGS} => rR --no-print-directory -- MAKEVAL=Hello\ World
****** $ENV{MAKEVAL} => Hello World

与之前的结果对比可知,源于命令行(command line)的变量参数,会在make启动时添加到MAKFFLAGS变量的尾部,并通过环境变量导出。MAKEFLAGS变量默认会被make导出到环境变量中。至此,我们就全完解答了本文提出的问题。

make-n命令行参数

GNU Make工具的-n参数可以在不执行具体操作的情况下,将操作命令输出。根据官方文档的说明,带有$(MAKE)的操作是例外:

$ make -n -f Makefile
phell -s -p MAKEFLAGS -p MAKEVAL
echo "Origin: undefined; invoking sub-make..."
echo "------------------------------------------------"
make --no-print-directory -f dump-env.mk all
phell -s -p MAKEFLAGS -p MAKEVAL

最后一行phell -s -p MAKEFLAGS -p MAKEVAL源于第二个Makefile脚本dump-env.mk。虽然输出了该操作,但没有被执行。可以给相应的操作之前添加+字符,在带有-n命令行参数的情况下,依然执行操作。相应的修改为:

--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,7 @@ endif
 .PHONY: all
 
 all:
-       phell -s -p MAKEFLAGS -p MAKEVAL
+       +phell -s -p MAKEFLAGS -p MAKEVAL
        @echo "Origin: $(MV_ORIG); invoking sub-make..."
        @echo "------------------------------------------------"
        $(MAKE) --no-print-directory -f dump-env.mk $@

--- a/dump-env.mk
+++ b/dump-env.mk
@@ -3,4 +3,4 @@
 .PHONY: all
 
 all:
-       phell -s -p MAKEFLAGS -p MAKEVAL
+       +phell -s -p MAKEFLAGS -p MAKEVAL

再次执行make -n -f Makefile,其结果如下:

phell -s -p MAKEFLAGS -p MAKEVAL
****** $ENV{MAKEFLAGS} => nrR
****** $ENV{MAKEVAL} has not been defined
echo "Origin: undefined; invoking sub-make..."
echo "------------------------------------------------"
make --no-print-directory -f dump-env.mk all
phell -s -p MAKEFLAGS -p MAKEVAL
****** $ENV{MAKEFLAGS} => nrR --no-print-directory
****** $ENV{MAKEVAL} has not been defined

由以上可知,GNU Make的-n命令行参数也由MAKEFLAGS通过环境变量传递给递归调用的sub-make。操作命令之前的+字符不仅影响-n参数的作用,还会影响-t/-q等参数的作用,这一特性增加了make工具的灵活性;具体的说明请参考GNU Make的官方文档

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
GUN make 中文手册 译者:徐海兵 2004-09-11 3.5.6 库文件和搜索目录 .................................................................................................... 36 3.6 Makefile伪目标.............................................................................................................. 37 3.7 强制目标(没有命令或依赖的规则) ............................................................................. 40 3.8 空目标文件..................................................................................................................... 41 3.9 Makefile的特殊目标....................................................................................................... 41 3.10 多目标............................................................................................................................ 44 3.11 多规则目标..................................................................................................................... 44 3.12 静态模式 ........................................................................................................................ 45 3.12.1 静态模式规则的语法 ....................................................................................... 45 3.12.2 静态模式和隐含规则 ....................................................................................... 47 3.13 双冒号规则..................................................................................................................... 48 3.14 自动产生依赖 ................................................................................................................. 49 第四章:规则的命令 .................................................................................................................. 51 4 规则中书写命令 ................................................................................................................... 51 4.1 命令回显 ........................................................................................................................ 51 4.2 命令的执行..................................................................................................................... 52 4.3 并发执行命令 ................................................................................................................. 53 4.4 命令执行的错误.............................................................................................................. 54 4.5 中断make的执行............................................................................................................ 56 4.6 make的递归执行............................................................................................................ 56 4.6.1 变量MAKE ............................................................................................................... 57 4.6.2 变量和递归 ............................................................................................................... 58 4.6.3 命令行选项和递归 .................................................................................................... 61 4.6.4 -w选项...................................................................................................................... 63 4.7 定义命令包..................................................................................................................... 63 4.8 空命令............................................................................................................................ 65 第五章:Makefile中的变量......................................................................................................... 65 5 使用变量 .............................................................................................................................. 65 5.1 变量的引用..................................................................................................................... 66 5.2 两种变量定义(赋值)................................................................................................... 68 5.2.1 递归展开式变量........................................................................................................ 68 5.2.2 直接展开式变量........................................................................................................ 69 5.2.3 如何定义一个空格 .................................................................................................... 70 5.2.4 “?=”操作符 ............................................................................................................. 71 5.3 变量的高级用法.............................................................................................................. 71 5.3.1 变量的替换引用........................................................................................................ 72 5.3.2 变量的套嵌引用........................................................................................................ 72 5.4 变量取值 ........................................................................................................................ 76 5.5 如何设置变量 ................................................................................................................. 76 5.6 追加变量值..................................................................................................................... 77 5.7 override 指示符 ............................................................................................................. 79 5.8 多行定义 ........................................................................................................................ 80 5.9 系统环境变量 ................................................................................................................. 81 5.10 目标指定变量 ................................................................................................................. 83 5.11 模式指定变量 ................................................................................................................. 84 第六章:Makefile的条件执行 ..................................................................................................... 85 6 Makefile的条件判断 ............................................................................................................. 85 6.1 一个例子 ........................................................................................................................ 85 6.2 条件判断的基本语法 ...................................................................................................... 86 2004年9月11日 3GUN make 中文手册 6.3 标记测试的条件语句 ...................................................................................................... 89 第七章:make的内嵌函数.......................................................................................................... 89 7 make的函数 ......................................................................................................................... 89 7.1 函数的调用语法.............................................................................................................. 90 7.2 文本处理函数 ................................................................................................................. 91 7.2.1 $(subst FROM,TO,TEXT) ....................................................................................... 91 7.2.2 $(patsubst PATTERN,REPLACEMENT,TEXT) ..................................................... 91 7.2.3 $(strip STRINT)....................................................................................................... 92 7.2.4 $(findstring FIND,IN) .............................................................................................. 92 7.2.5 $(filter PATTERN...,TEXT) ..................................................................................... 93 7.2.6 $(filter-out PATTERN...,TEXT) ............................................................................... 93 7.2.7 $(sort LIST) ............................................................................................................. 94 7.2.8 $(word N,TEXT) ...................................................................................................... 94 7.2.9 $(wordlist S,E,TEXT).............................................................................................. 94 7.2.10 $(words TEXT) .............................................................................................. 94 7.2.11 $(firstword NAMES...) .................................................................................. 95 7.3 文件名处理函数.............................................................................................................. 95 7.3.1 $(dir NAMES...) ...................................................................................................... 95 7.3.2 $(notdir NAMES...)................................................................................................. 96 7.3.3 $(suffix NAMES...) ................................................................................................. 96 7.3.4 $(basename NAMES...) ......................................................................................... 96 7.3.5 $(addsuffix SUFFIX,NAMES...) ............................................................................. 97 7.3.6 $(addprefix PREFIX,NAMES...) ............................................................................. 97 7.3.7 $(join LIST1,LIST2)................................................................................................. 98 7.3.8 $(wildcard PATTERN) ............................................................................................ 98 7.4 foreach 函数................................................................................................................. 98 7.5 if 函数 ......................................................................................................................... 100 7.6 call函数 ....................................................................................................................... 100 7.7 value函数 .................................................................................................................... 102 7.8 eval函数 ...................................................................................................................... 103 7.9 origin函数 ................................................................................................................... 104 7.10 shell函数 ..................................................................................................................... 106 7.11 make的控制函数.......................................................................................................... 106 7.11.1 $(error TEXT...) ........................................................................................... 107 7.11.2 $(warning TEXT...)...................................................................................... 107 第八章:执行make .................................................................................................................. 108 8 执行make .......................................................................................................................... 108 8.1 指定makefile文件 ........................................................................................................ 108 8.2 指定终极目标 ............................................................................................................... 109 8.3 替代命令的执行............................................................................................................ 111 8.4 防止特定文件重建 ........................................................................................................ 112 8.5 替换变量定义 ............................................................................................................... 113 8.6 使用make进行编译测试............................................................................................... 114 8.7 make的命令行选项 ...................................................................................................... 115 第九章:make的隐含规则........................................................................................................ 119 9 使用隐含规则 ..................................................................................................................... 119 9.1 隐含规则的使用............................................................................................................ 119 9.2 make的隐含规则一览 .................................................................................................. 121 9.3 隐含变量 ...................................................................................................................... 124 9.3.1 代表命令的变量...................................................................................................... 124 9.3.2 命令参数的变量...................................................................................................... 125 9.4 make隐含规则链.......................................................................................................... 126 2004年9月11日 4GUN make 中文手册 9.5 模式规则 ...................................................................................................................... 128 9.5.1 模式规则介绍 ......................................................................................................... 128 9.5.2 模式规则示例 ......................................................................................................... 129 9.5.3 自动化变量 ............................................................................................................. 130 9.5.4 模式的匹配 ............................................................................................................. 133 9.5.5 万用规则 ................................................................................................................ 133 9.5.6 重建内嵌隐含规则 .................................................................................................. 134 9.6 缺省规则 ...................................................................................................................... 135 9.7 后缀规则 ...................................................................................................................... 135 9.8 隐含规则搜索算法 ........................................................................................................ 137 第十章:使用make更新静态库文件 ......................................................................................... 138 10 更新静态库文件............................................................................................................ 138 10.1 库成员作为目标............................................................................................................ 138 ARCHIVE(MEMBER) .............................................................................................................. 138 10.2 静态库的更新 ............................................................................................................... 139 10.2.1 更新静态库的符号索引表 .............................................................................. 140 10.3 make静态库的注意事项............................................................................................... 141 10.4 静态库的后缀规则 ........................................................................................................ 141 第十一章 : GNU make的特点............................................................................................... 142 11 GNU make的一些特点 ................................................................................................. 142 11.1 源自System v的特点 ................................................................................................... 142 11.2 源自其他版本的特点 .................................................................................................... 143 11.3 GNU make自身的特点 ................................................................................................. 143 第十二章 和其它版本的兼容 .................................................................................................... 144 12 不兼容性 ...................................................................................................................... 144 第十三章 Makefile的约定 ........................................................................................................ 146 13 书写约定 ...................................................................................................................... 146 13.1 基本的约定................................................................................................................... 146 13.2 规则命令行的约定 ........................................................................................................ 147 13.3 代表命令变量 ............................................................................................................... 149 13.4 安装目录变量 ............................................................................................................... 150 13.5 Makefile的标准目标名 ................................................................................................. 154 13.6 安装命令分类 ............................................................................................................... 159 第十四章 make的常见错误信息............................................................................................... 161 14 make产生的错误信息 .......................................................................................................... 161 附录1:关键字索引................................................................................................................. 163 GNU make可识别的指示符:.............................................................................................. 163 GNU make函数: ............................................................................................................... 164 GNU make的自动化变量..................................................................................................... 165 GNU make环境变量 ............................................................................................................ 166 后序 ......................................................................................................................................... 166

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值