If I have a makefile with an optional argument, I normally will use:
make target
but sometimes (if I think there might be a problem with the assembler optimisations) I want to pass an extra command line argument, e.g.
make target VERIFY_ASSEMBLY_OPTIMISATIONS=1
Sometimes I may have a typo in the command line argument, e.g.
make target VERIFY_ASSEMBLY_OPTIMIZATIONS=1
and this can cause me to waste a lot of time as the wrong thing has been built.
Is there a simple way of verifying Makefile command line arguments?
In other words, I want the Makefile to instantly raise an error if an unrecognized command line argument has been used.
I've tried the following code to detect unexpected variables:
ALLOWED_VARS := foo bar
$(foreach v, \
$(filter-out $(ALLOWED_VARS),$(.VARIABLES)), \
$(info $(v) = $($(v))))
Unfortunately, this seems to detect lots of extra variables (such as LANG, TERM, LEX) that I did not specify on the command line.
There is an undocumented variable that contains all the command line variable assignments, -*-command-variables-*- (yes, that's the actual name of the variable).
So if you have this makefile:
all:
@echo '$(-*-command-variables-*-)'
and you run make, it will print nothing. If you run make FOO=bar BIZ=baz, it will print FOO=bar BIZ=baz. This is not 100% reliable because this is an undocumented variable and so it's conceivable that someday it may change, and it's slightly problematic because it quotes whitespace, so make FOO='foo bar' with the above makefile will print FOO=foo\ bar. But it's probably good enough.
If you wanted it to be bulletproof the only option I can suggest is looping through the $(.VARIABLES) value, which contains a list of variables that have been defined, passing each to the $(origin ...) function and looking for command line as the value. Something like this:
CMDVARS := $(strip $(foreach V,$(.VARIABLES),$(if $(findstring command,$(origin $V)),$V)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With