Passing arguments to "make run"

Viewed 344658

I use Makefiles.

I have a target called run which runs the build target. Simplified, it looks like the following:

prog: ....
  ...

run: prog
  ./prog

Is there any way to pass arguments? So that

make run asdf --> ./prog asdf
make run the dog kicked the cat --> ./prog the dog kicked the cat
14 Answers

I don't know a way to do what you want exactly, but a workaround might be:

run: ./prog
    ./prog $(ARGS)

Then:

make ARGS="asdf" run
# or
make run ARGS="asdf"

for standard make you can pass arguments by defining macros like this

make run arg1=asdf

then use them like this

run: ./prog $(arg1)
   etc

References for make Microsoft's NMake

No. Looking at the syntax from the man page for GNU make

make [ -f makefile ] [ options ] ... [ targets ] ...

you can specify multiple targets, hence 'no' (at least no in the exact way you specified).

run: ./prog looks a bit strange, as right part should be a prerequisite, so run: prog looks better.

I would suggest simply:

.PHONY: run

run:
    prog $(arg1)

and I would like to add, that arguments can be passed:

  1. as argument: make arg1="asdf" run
  2. or be defined as environment: arg1="asdf" make run

I found a way to get the arguments with an equal sign =! The answer is especially an addition to @lesmana 's answer (as it is the most complete and explained one here), but it would be too big to write it as a comment. Again, I repeat his message: TL;DR don't try to do this!

I needed a way to treat my argument --xyz-enabled=false (since the default is true), which we all know by now that this is not a make target and thus not part of $(MAKECMDGOALS).

While looking into all variables of make by echoing the $(.VARIABLES) i got these interesting outputs:

[...] -*-command-variables-*- --xyz-enabled [...]

This allows us to go two ways: either getting all starting with a -- (if that applies to your case), or look into the GNU make specific (probably not intended for us to use) variable -*-command-variables-*-. ** See footer for additional options ** In my case this variable held:

--xyz-enabled=false

With this variable we can combine it with the already existing solution with $(MAKECMDGOALS) and thus by defining:

# the other technique to invalidate other targets is still required, see linked post
run:
    @echo ./prog $(-*-command-variables-*-) $(filter-out $@,$(MAKECMDGOALS))`

and using it with (explicitly mixing up order of arguments):

make run -- config --xyz-enabled=false over=9000 --foo=bar show  isit=alwaysreversed? --help

returned:

./prog isit=alwaysreversed? --foo=bar over=9000 --xyz-enabled=false config show --help

As you can see, we loose the total order of the args. The part with the "assignment"-args seem to have been reversed, the order of the "target"-args are kept. I placed the "assignment"-args in the beginning, hopefully your program doesn't care where the argument is placed.


following make variables looks promising as well:

MAKEFLAGS =  -- isit=alwaysreverse? --foo=bar over=9000 --xyz-enabled=false
MAKEOVERRIDES = isit=alwaysreverse? --foo=bar over=9000 --xyz-enabled=false

It's been for a while, but I'll provide mine version which I use in production.

I'll hope that someone will find it useful.

Example:

.PHONY: greeting
greeting:
    echo $(if $s,$s,)

Command:

make greeting s="hello world"

Output:

hello world

Another trick I use is the -n flag, which tells make to do a dry run. For example,

$ make install -n 
# Outputs the string: helm install stable/airflow --name airflow -f values.yaml
$ eval $(make install -n) --dry-run --debug
# Runs: helm install stable/airflow --name airflow -f values.yaml --dry-run --debug
Related