Подтвердить что ты не робот

Gnu make: перечислить значения всех переменных (или "макросов" ) в конкретном прогоне

Как я могу перечислить текущее значение всех переменных (также называемых макросами) в 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
4b9b3361

Ответ 1

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

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 [email protected])
# makefile
SHELL = /bin/sh
# default
RM = rm -f

Ответ 2

GNU make обеспечивает . ПЕРЕМЕННЫЕ который содержит имена всех глобальных переменных. Однако это включает встроенные переменные (например, 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 кажется встроенным переменная в моей системе)

Ответ 3

Благодаря @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))))

Ответ 4

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

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

Ответ 5

Спасибо @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