Message ID | dac8f92abae72426b9b1c19f1a3ee5e173d101e3.1636810092.git.yann.morin.1998@free.fr |
---|---|
State | Accepted |
Headers | show |
Series | core: add show-vars, a json-formatted equivalent to printvars (branch yem/show-vars) | expand |
On Sat, 13 Nov 2021 14:28:27 +0100 "Yann E. MORIN" <yann.morin.1998@free.fr> wrote: > The current printvars output suffers from a serious design flaw: > variables are not delimited, which makes it impossible to reliably > retrieve the value of variables; only variables that are known to > not contain a \n can be relatively safely extracted. > > However, in some cases, it is important to be able to retrieve the > multi-line value of a variable, notably the CMDS or the hooks. One > such use-case (to follow in an unscheduled future) would be to hash > the variables that make up a package "configuration", and cache or > extract the files for that package to speed up the build. > > Modeled after printvars and show-info, we introduce show-vars (what a > lack of imagination here) that outputs a json dictionary which keys are > the variable names, and for each variable, provides the raw and expanded > values. > > Unlike printvars, we do not provide a way to get either the raw or > expanded value; both are systematically printed; a user will get just > the one is needs. Additionally, strings in JSON are quoted, so there is > no need to provide a way to quote variables; that would not make sense. > > Note: for printvars, we require that the user provides an explicit > pattern to filter variables on. This is historical (see fd5bd12379dc, > Makefile: printvars: don't print anything when VARS is not set). The > underlying reasoning was that printvars is too "raw", and variables are > not well delimited, so printvars was mostly used to extract a few values > here and there, from scripts, or to quickly inspect a specific package's > variables during debugging. > > But show-vars, although technically plain-text, being JSON, is not very > human-readable, and is mostly aimed at tools that will parse it with a > real JSON parser, and which will want to have a complete view of a lot > of variables at once. As such, and contrary to printvars, it makes sense > to report on all variables by default, unless the user explicitly > requested a subset. > > As a final note: a lot of our variables only make sense in the context > of an actual make target. For example, a variable of package foo, that > contains $(@D)/bar, would expand to .../build/FOO-VERSION/bar. This is > because our CMDS and hooks are expanded as the recipe of a stamp file > that lies in the package build directory. > > But for show-info, this falls flat on its face: it is not the stamp file > of a package, so there is no package directory, and show-info itself has > not directory part, so $(@D) expands to '.' (dot). > > Additionally, some variables may contain calls to $(shell) (e.g. to call > pkg-config), and this also does not work with show-info. > > These two issues make it impossible to emit the correct expanded value > of variables. To be noted: printvars has the exact same limitations for > the exact same reasons. > > Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr> > --- > Makefile | 21 ++++++++++++++++++++- > 1 file changed, 20 insertions(+), 1 deletion(-) Applied to master, thanks. However, there are two things that are missing: (1) Update to the Buildroot manual (2) At least one test case in supporting/testing/ Thanks! Thomas
diff --git a/Makefile b/Makefile index 6f6bb72de3..0a24f7c5be 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ nobuild_targets := source %-source \ clean distclean help show-targets graph-depends \ %-graph-depends %-show-depends %-show-version \ graph-build graph-size list-defconfigs \ - savedefconfig update-defconfig printvars + savedefconfig update-defconfig printvars show-vars ifeq ($(MAKECMDGOALS),) BR_BUILDING = y else ifneq ($(filter-out $(nobuild_targets),$(MAKECMDGOALS)),) @@ -1058,6 +1058,7 @@ endif # Makefiles. Alternatively, if a non-empty VARS variable is passed, # only the variables matching the make pattern passed in VARS are # displayed. +# show-vars does the same, but as a JSON dictionnary. .PHONY: printvars printvars: @: @@ -1070,6 +1071,22 @@ printvars: $(info $V=$(if $(RAW_VARS),$(value $V),$($V)))))) # ')))) # Syntax colouring... +.PHONY: show-vars +show-vars: VARS?=% +show-vars: + @: + $(info $(call clean-json, { \ + $(foreach V, \ + $(sort $(filter $(VARS),$(.VARIABLES))), \ + $(if $(filter-out environment% default automatic, $(origin $V)), \ + "$V": { \ + "expanded": $(call mk-json-str,$($V))$(comma) \ + "raw": $(call mk-json-str,$(value $V)) \ + }$(comma) \ + ) \ + ) \ + } )) + .PHONY: clean clean: rm -rf $(BASE_TARGET_DIR) $(BINARIES_DIR) $(HOST_DIR) $(HOST_DIR_SYMLINK) \ @@ -1162,6 +1179,8 @@ help: @echo ' pkg-stats - generate info about packages as JSON and HTML' @echo ' missing-cpe - generate XML snippets for missing CPE identifiers' @echo ' printvars - dump internal variables selected with VARS=...' + @echo ' show-vars - dump all internal variables as a JSON blurb; use VARS=...' + @echo ' to limit the list to variables names matching that pattern' @echo @echo ' make V=0|1 - 0 => quiet build (default), 1 => verbose build' @echo ' make O=dir - Locate all output files in "dir", including .config'
The current printvars output suffers from a serious design flaw: variables are not delimited, which makes it impossible to reliably retrieve the value of variables; only variables that are known to not contain a \n can be relatively safely extracted. However, in some cases, it is important to be able to retrieve the multi-line value of a variable, notably the CMDS or the hooks. One such use-case (to follow in an unscheduled future) would be to hash the variables that make up a package "configuration", and cache or extract the files for that package to speed up the build. Modeled after printvars and show-info, we introduce show-vars (what a lack of imagination here) that outputs a json dictionary which keys are the variable names, and for each variable, provides the raw and expanded values. Unlike printvars, we do not provide a way to get either the raw or expanded value; both are systematically printed; a user will get just the one is needs. Additionally, strings in JSON are quoted, so there is no need to provide a way to quote variables; that would not make sense. Note: for printvars, we require that the user provides an explicit pattern to filter variables on. This is historical (see fd5bd12379dc, Makefile: printvars: don't print anything when VARS is not set). The underlying reasoning was that printvars is too "raw", and variables are not well delimited, so printvars was mostly used to extract a few values here and there, from scripts, or to quickly inspect a specific package's variables during debugging. But show-vars, although technically plain-text, being JSON, is not very human-readable, and is mostly aimed at tools that will parse it with a real JSON parser, and which will want to have a complete view of a lot of variables at once. As such, and contrary to printvars, it makes sense to report on all variables by default, unless the user explicitly requested a subset. As a final note: a lot of our variables only make sense in the context of an actual make target. For example, a variable of package foo, that contains $(@D)/bar, would expand to .../build/FOO-VERSION/bar. This is because our CMDS and hooks are expanded as the recipe of a stamp file that lies in the package build directory. But for show-info, this falls flat on its face: it is not the stamp file of a package, so there is no package directory, and show-info itself has not directory part, so $(@D) expands to '.' (dot). Additionally, some variables may contain calls to $(shell) (e.g. to call pkg-config), and this also does not work with show-info. These two issues make it impossible to emit the correct expanded value of variables. To be noted: printvars has the exact same limitations for the exact same reasons. Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr> --- Makefile | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-)