当运行make时,如何列出Makefile中所有变量(也称为宏)的当前值?
例如,如果Makefile中有以下内容:
CUR-DIR := $(shell /bin/pwd)
LOG-DIR := $(CUR-DIR)/make-logs
那么我想让它告诉我:
CUR-DIR = /home/johv/src/test
LOG-DIR = /home/johv/src/test/make-logs
GNU make提供了.VARIABLES变量,其中包含所有全局变量的名称。但是,这也包括内置变量(如MAKEFLAGS
)。如果您需要排除内置变量,则可能需要进行一些过滤,例如以下示例中所示。
以下makefile使用info
命令打印用户定义的变量(CUR-DIR
、LOG-DIR
):
# Place this line at the top of your Makefile
VARS_OLD := $(.VARIABLES)
# Define your variables
CUR-DIR := $(shell pwd)
LOG-DIR := $(CUR-DIR)/make-logs
# Put this at the point where you want to see the variable values
$(foreach v, \
$(filter-out $(VARS_OLD) VARS_OLD,$(.VARIABLES)), \
$(info $(v) = $($(v))))
感谢 @Ise Wisteria,这个内容被压缩了,适用于具有多个makefile(Buildroot)的大型项目中的所有变量。
$(foreach v, $(.VARIABLES), $(info $(v) = $($(v))))
输出: BR2_GCC_TARGET_TUNE = "cortex-a8"
...
如果您遇到如下错误: insufficient number of arguments (1) to function 'addprefix'
,这个项目可能存在一些损坏的变量... 我已经修剪了变量列表,并只显示一个前缀为BR2_
的部分。
$(foreach v, $(filter BR2_%,$(.VARIABLES)), $(info $(v) = $($(v))))
最终我是这样实现的:
gmake -pn | grep -A1 "^# makefile"| grep -v "^#\|^--" | sort | uniq > makevars.txt
它给出:
CUR-DIR := /home/johv/src/test
LOG-DIR := /home/johv/src/test/make-logs
MAKEFILE_LIST := Makefile
MAKEFLAGS = pn
SHELL = /bin/sh
VARS_OLD := [...]
gmake -pn
非常冗长,看起来有点像这样:
# environment
GNOME2_PATH = /usr/local:/opt/gnome:/usr:/usr/local:/opt/gnome:/usr
# automatic
@F = $(notdir $@)
# makefile
SHELL = /bin/sh
# default
RM = rm -f
gmake
。 - Fredrick Gaussgmake
是 make
的符号链接。您可以删除 g
,脚本将正常工作。 - Alex Khonko不保存所有.VARIABLES
并过滤它们也可以实现。
此外,如果您的makefile中修改了其中一个原始.VARIABLES
,那么两个最受欢迎的答案都无法捕获它。
查看$(origin)函数。该目标过滤并打印在makefile中定义的所有变量:
print_file_vars:
$(foreach v, $(.VARIABLES), $(if $(filter file,$(origin $(v))), $(info $(v)=$($(v)))))
这样我只会得到几个额外的变量:CURDIR SHELL MAKEFILE_LIST .DEFAULT_GOAL MAKEFLAGS
。
可以将file
替换为environment
或command line
,以打印相应类型的变量。
这里有很多好的答案,但是如果您的某些变量是递归flavor,使用$($(v))
可能会出现问题。这就是为什么应该使用$(value $(v))
。
这个变体稍微改进了一下,按名称对变量进行排序,并使输出更易读。
dump:
$(foreach v, \
$(shell echo "$(filter-out .VARIABLES,$(.VARIABLES))" | tr ' ' '\n' | sort), \
$(info $(shell printf "%-20s" "$(v)")= $(value $(v))) \
)
$(file > $(MAKEFILE_ENV_FILE),)
$(foreach v, $(.VARIABLES), \
$(file >> $(MAKEFILE_ENV_FILE),$(v)) \
$(file >> $(MAKEFILE_ENV_FILE), := $(value $(v))) \
$(file >> $(MAKEFILE_ENV_FILE), == $($(v))) \
$(file >> $(MAKEFILE_ENV_FILE),) \
)
这仍然不能始终区分带有双换行符的恶意变量和两个变量,为此,现在需要在$(file >> NAME,TEXT)
内的每个逗号后面添加足够唯一的分隔符,以便始终区分它们。
将MAKEFILE_ENV_FILE设置为某个文件名,例如:
MAKEFILE_ENV_FILE := $(abspath $(lastword $(MAKEFILE_LIST))).env
这个方案是 Ise Wisterias Solution 的改进:
./Makefile
:
ARG_VARS_0 := $(.VARIABLES)
#############################
# Documented Arguments START
#############################
EXAMPLE_ARG_0 :=
EXAMPLE_ARG_1 := ./some/path
#############################
# Documented Arguments END
#############################
ARG_VARS_1 := $(.VARIABLES)
# filter out any words starting with '%':
ARG_VARS_0_FIXED := $(filter-out \%%,$(ARG_VARS_0))
ARG_VARS_1_FIXED := $(filter-out \%%,$(ARG_VARS_1))
ARG_VARS := $(filter-out $(ARG_VARS_0_FIXED) ARG_VARS_0,$(ARG_VARS_1_FIXED))
.PHONY: list_vars print_vars # ...
list_vars:
$(foreach v,$(ARG_VARS),$(info $(v)))
print_vars:
$(foreach v,$(ARG_VARS),$(info $(v) = $($(v))))
$ make list_vars
> EXAMPLE_ARG_0
> EXAMPLE_ARG_1
在终端上打印 Makefile 参数的默认值:
$ make print_vars
> EXAMPLE_ARG_0 =
> EXAMPLE_ARG_1 = ./some/path
.VARIABLES
有时包含奇怪的内容,比如%D %F *D *F +D +F ...
。以%
开头的单词可能会导致问题(例如,某些变量可能无法打印)。
make > variables.txt
- JSBձոգչ