Makefile gnu make:列出特定运行中所有变量(或“宏”)的值

Makefile gnu make:列出特定运行中所有变量(或“宏”)的值,makefile,gnu-make,Makefile,Gnu Make,运行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制造提供 它保存所有全局变量的名称。 但是,这包括内置变量(如MAKEFLAGS)。 如果必须排除

运行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制造提供 它保存所有全局变量的名称。 但是,这包括内置变量(如
MAKEFLAGS
)。 如果必须排除内置变量,请执行如下筛选 可能需要。 以下生成文件打印用户定义的变量(
CUR-DIR
LOG-DIR
) 使用
info

VARS_OLD := $(.VARIABLES)
CUR-DIR := $(shell pwd)
LOG-DIR := $(CUR-DIR)/make-logs
$(foreach v,                                        \
  $(filter-out $(VARS_OLD) VARS_OLD,$(.VARIABLES)), \
  $(info $(v) = $($(v))))
(我将
CURDIR
重命名为
CUR-DIR
,因为
CURDIR
似乎是内置的
(我的系统中的变量)

我最后是这样做的:

gmake -pn | grep -A1 "^# makefile"| grep -v "^#\|^--" | sort | uniq > makevars.txt
# environment
GNOME2_PATH = /usr/local:/opt/gnome:/usr:/usr/local:/opt/gnome:/usr
# automatic
@F = $(notdir $@)
# makefile
SHELL = /bin/sh
# default
RM = rm -f
其中:

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
非常冗长,看起来有点像这样:

gmake -pn | grep -A1 "^# makefile"| grep -v "^#\|^--" | sort | uniq > makevars.txt
# environment
GNOME2_PATH = /usr/local:/opt/gnome:/usr:/usr/local:/opt/gnome:/usr
# automatic
@F = $(notdir $@)
# makefile
SHELL = /bin/sh
# default
RM = rm -f

感谢@Ise Wisteria的浓缩,它显示了所有变量,对于具有多个makefile(Buildroot)的大型项目非常有用

输出:
BR2\u GCC\u TARGET\u TUNE=“cortex-a8”

如果出现如下错误:
函数“addprefix”的参数数量不足(1)
此项目有一些已损坏的变量。。。我修剪了变量列表以显示,只添加了前缀
BR2\uu

$(foreach v, $(filter BR2_%,$(.VARIABLES)), $(info $(v) = $($(v))))

感谢@kevinf的伟大创意。我建议进行一个小的更改,以防止变量本身在变量列表中打印出来:


$(foreach v,$(filter out.VARIABLES,$(.VARIABLES)),$(info$(v)=$($(v)))

多亏了foreach解决方案的@kevinf——如果要将此列表导出为某种机器可读的文件,使用echo或printf时将很难使用不均匀的引号或换行符,由于Make无法正确引用数据,因此需要使用$(file…)函数来写入数据,以避免sh/bash抱怨语法无效。例如,在规则中使用它--它打印变量名、定义和扩展值:

$(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),) \
)
(这仍然不允许总是将带有双换行符的恶意变量与两个变量区分开来,因为现在在
$(文件>>名称,文本)
中的每个逗号之后,在生成的每个Makefile换行符前面添加一个足够唯一的分隔符)

将MAKEFILE_ENV_FILE设置为某个文件名,例如:

MAKEFILE_ENV_FILE := $(abspath $(lastword $(MAKEFILE_LIST))).env

它也可以在不保存所有
变量
并过滤掉它们的情况下实现

此外,如果在makefile中修改了原始的
.VARIABLES
中的一个,那么投票最多的两个答案将无法捕捉到它

签出功能。此目标过滤并打印生成文件中定义的所有变量:

print_file_vars:
    $(foreach v, $(.VARIABLES), $(if $(filter file,$(origin $(v))), $(info $(v)=$($(v)))))
通过这种方式,我只得到几个多余的变量:
CURDIR SHELL MAKEFILE\u LIST.DEFAULT\u GOAL MAKEFLAGS


可以用
环境
命令行
替换
文件
,以打印相应类型的变量。

如何运行它?将其放入
Makefile
并运行“
make
”我只得到了“
make:**没有目标。停止。
”对不起,我忘了提到,如果你的GNU make版本是3.80或更低,这个答案不起作用。啊,是的,我使用了3.80。在3.81中,它起了作用。另外,我在问题中改为CUR-DIR。如何将其写入文件而不仅仅是打印?@JasonS,让您的shell处理它
make>variables.txt
并非所有系统都有
gmake
。谢谢!这正是我一直在寻求的答案:)太棒了!天才!