gnu make: list the values of all variables (or “macros”) in a particular run

白昼怎懂夜的黑 提交于 2019-11-28 16:15:55

问题


How can I list the current value of all variables (also called macros) in a Makefile when running make?

E.g. if this is in the Makefile:

CUR-DIR := $(shell /bin/pwd)
LOG-DIR := $(CUR-DIR)/make-logs

Then I would like it to tell me:

CUR-DIR = /home/johv/src/test
LOG-DIR = /home/johv/src/test/make-logs

回答1:


GNU make provides .VARIABLES which holds all global variables' names. However, this includes built-in variables(like MAKEFLAGS). If you have to exclude built-in variables, some filtering like the following might be needed. The following makefile prints user-defined variables(CUR-DIR, LOG-DIR) using 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))))

(I renamed CURDIR to CUR-DIR because CURDIR seems to be a built-in variable in my system)




回答2:


I ended up doing it like this:

gmake -pn | grep -A1 "^# makefile"| grep -v "^#\|^--" | sort | uniq > makevars.txt

which gives:

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 is really verbose and looks kinda like this:

# environment
GNOME2_PATH = /usr/local:/opt/gnome:/usr:/usr/local:/opt/gnome:/usr
# automatic
@F = $(notdir $@)
# makefile
SHELL = /bin/sh
# default
RM = rm -f



回答3:


Thanks to @Ise Wisteria, condensed down, this shows all variables, useful for large projects with multiple makefiles (Buildroot).

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

output: BR2_GCC_TARGET_TUNE = "cortex-a8" ...

If you get an error like: insufficient number of arguments (1) to function 'addprefix' this project had some broken variables... I trimmed the list of variables to show, only with a prefix BR2_

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



回答4:


Thanks to @kevinf for the great idea. I would suggest a minor change to prevent .VARIABLE itself from printing out in the variable list:

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




回答5:


Thanks to @kevinf for the foreach solution -- if one wants to export this list as a somewhat machine-readable file, one will have a hard time with uneven quotes or newlines when using echo or printf, since Make isn't able to quote the data correctly -- one needs to use the $(file ...) function to write the data to avoid sh/bash complaining about invalid syntax. For example, use this in your rule -- it prints variable name, definition and expanded value:

$(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),) \
)

(This will still not allow to always distinguish malicious variables with double newlines from two variables, for this one now add a sufficiently unique separator infront of each Makefile-generated newline just after each comma inside $(file >> NAME,TEXT))

Set MAKEFILE_ENV_FILE to some filename, e.g.:

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


来源:https://stackoverflow.com/questions/7117978/gnu-make-list-the-values-of-all-variables-or-macros-in-a-particular-run

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!