Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting unused makefile command line arguments

Background

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

Problem

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.

Question

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.

What I've tried

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.

like image 688
Peter de Rivaz Avatar asked Dec 04 '25 14:12

Peter de Rivaz


1 Answers

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)))
like image 195
MadScientist Avatar answered Dec 07 '25 22:12

MadScientist