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

后端 未结 6 1475
面向向阳花
面向向阳花 2020-12-07 16:41

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 := $         


        
相关标签:
6条回答
  • 2020-12-07 17:07

    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
    
    0 讨论(0)
  • 2020-12-07 17:14

    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)

    0 讨论(0)
  • 2020-12-07 17:16

    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
    
    0 讨论(0)
  • 2020-12-07 17:24

    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))))

    0 讨论(0)
  • 2020-12-07 17:27

    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))))
    
    0 讨论(0)
  • 2020-12-07 17:29

    It's also doable without saving all the .VARIABLES and filtering them out.

    Moreover, if one of the original .VARIABLES was modified in your makefile, the two most voted answers won't catch it.

    Check out $(origin) function. This target filters out and prints all the variables that were defined in a makefile:

    print_file_vars:
        $(foreach v, $(.VARIABLES), $(if $(filter file,$(origin $(v))), $(info $(v)=$($(v)))))
    

    I get only a few excess variables this way: CURDIR SHELL MAKEFILE_LIST .DEFAULT_GOAL MAKEFLAGS.

    One can replace file with environment or command line to print the respective kinds of variables.

    0 讨论(0)
提交回复
热议问题