GNU Make: список значений всех переменных (или "макросов") в конкретном прогоне - PullRequest
37 голосов
/ 19 августа 2011

Как мне вывести текущее значение всех переменных (также называемых макросами) в Makefile при запуске make?

например. если это в 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

Ответы [ 5 ]

36 голосов
/ 19 августа 2011

GNU make предоставляет .VARIABLES , который содержит имена всех глобальных переменных.Однако сюда входят встроенные переменные (например, MAKEFLAGS).Если вам необходимо исключить встроенные переменные, может потребоваться некоторая фильтрация, например, следующая.Следующий make-файл печатает пользовательские переменные (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 кажется встроеннымв моей системе)

26 голосов
/ 22 августа 2011

В итоге я сделал это так:

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
22 голосов
/ 24 сентября 2015

Благодаря @Ise Wisteria, в сжатой форме, отображаются все переменные, полезные для больших проектов с несколькими make-файлами (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))))
0 голосов
/ 08 мая 2019

Спасибо @kevinf за решение foreach - если кто-то захочет экспортировать этот список в виде файла, который можно прочитать на компьютере, он будет испытывать трудности с неравными кавычками или переводами строки при использовании 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 символом новой строки сразу после каждой запятой внутри $(file >> NAME,TEXT))

Установите для MAKEFILE_ENV_FILE какое-либо имя файла, например ::

MAKEFILE_ENV_FILE := $(abspath $(lastword $(MAKEFILE_LIST))).env
0 голосов
/ 05 апреля 2019

Спасибо @kevinf за отличную идею. Я бы предложил небольшое изменение, чтобы предотвратить вывод самой переменной .VARIABLE в список переменных:

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

...