web-dev-qa-db-fra.com

gnu make: liste les valeurs de toutes les variables (ou "macros") dans une exécution particulière

Comment puis-je répertorier la valeur actuelle de toutes les variables (également appelées macros) dans un Makefile lors de l'exécution de make?

Par exemple. si c'est dans le Makefile:

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

Ensuite, je voudrais qu'il me dise:

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

J'ai fini par le faire comme ceci:

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

qui donne:

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 est vraiment verbeux et ressemble un peu à ceci:

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

GNU make fournit . VARIABLES qui contient tous les noms des variables globales. Cependant, cela inclut des variables intégrées (comme MAKEFLAGS). Si vous devez exclure des variables intégrées, un filtrage comme celui-ci peut être nécessaire. Le makefile suivant imprime les variables définies par l'utilisateur (CUR-DIR, LOG-DIR) en utilisant 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))))

(J'ai renommé CURDIR en CUR-DIR parce que CURDIR semble être une variable intégrée dans mon système)

37
Ise Wisteria

Grâce à @Ise Wisteria, condensé, cela montre toutes les variables, utiles pour les grands projets avec plusieurs makefiles (Buildroot).

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

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

Si vous obtenez une erreur comme: insufficient number of arguments (1) to function 'addprefix' ce projet avait des variables cassées ... J'ai coupé la liste des variables à afficher, seulement avec un préfixe BR2_

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

Merci à @kevinf pour cette excellente idée. Je suggérerais une modification mineure pour empêcher .VARIABLE de s'imprimer dans la liste des variables:

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

0
WiiBopp

Merci à @kevinf pour la solution foreach - si l'on veut exporter cette liste en tant que fichier quelque peu lisible par machine, on aura du mal avec des guillemets inégaux ou des nouvelles lignes lors de l'utilisation d'écho ou de printf, car Make ne peut pas citer les données correctement - il faut utiliser la fonction $ (fichier ...) pour écrire les données pour éviter que sh/bash ne se plaigne d'une syntaxe invalide. Par exemple, utilisez ceci dans votre règle - il imprime le nom de la variable, la définition et la valeur développée:

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

(Cela ne permettra toujours pas de distinguer les variables malveillantes avec des doubles sauts de ligne de deux variables, car celle-ci ajoute maintenant un séparateur suffisamment unique devant chaque nouvelle ligne générée par Makefile juste après chaque virgule à l'intérieur de $(file >> NAME,TEXT))

Définissez MAKEFILE_ENV_FILE sur un nom de fichier, par exemple:

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