I have a Makefile that defines docker-compose project. It essentially assembles me a command:
COMMAND := docker-compose --project-name=$(PREFIX) --file=$(FILE_PATH)
up:
$(COMMAND) up -d
I would like to add a target
named dc
to which I would be able to pass any arguments I want.
I know there is one solution:
target:
$(COMMAND) $(ARGS)
And then call it with make target ARGS="--help"
for example.
But isn't there an easier way like in bash $@
? I would like to skip the ARGS=... part and send everything to the command after target
name.
@smarber You can't pass arguments to make without make interpreting them as its own command line flags, targets or variable assignments.
$@ is the name of the target. This is quite useful when the target is a pattern rather than fixed. $^ is the name of the prerequisite that caused the rule to execute.
When you type make or make [target] , the Make will look through your current directory for a Makefile. This file must be called makefile or Makefile . Make will then look for the corresponding target in the makefile. If you don't provide a target, Make will just run the first target it finds.
Not really. The make program interprets all arguments (that don't contain =
) as target names to be built and there's no way you can override that. So even though you can obtain the list of arguments given on the command line (via the GNU make-specific $(MAKECMDGOALS)
variable) you can't prevent those arguments from being considered targets.
You could do something like this, which is incredibly hacky:
KNOWN_TARGETS = target
ARGS := $(filter-out $(KNOWN_TARGETS),$(MAKECMDGOALS))
.DEFAULT: ;: do nothing
.SUFFIXES:
target:
$(COMMAND) $(ARGS)
(untested). The problem here is you have to keep KNOWN_TARGETS
up to date with all the "real" targets so you can remove them from the list of targets given on the command line. Then add the .DEFAULT
target which will be run for any target make doesn't know how to build, which does nothing. Reset the .SUFFIXES
meta-target to remove built-in rules.
I suspect this still will have weird edge-cases where it doesn't work.
Also note you can't just add options like --help
to the make command line, because make will interpret them itself. You'll have to prefix them with --
to force make to ignore them:
make target -- --help
Another option would be to add a target like this:
target%:
$(COMMAND) $*
Then you can run this:
make "target --help"
But you have to include the quotes.
In general I just recommend you reconsider what you want to do.
You could write a bash wrapper script to do what you'd like:
#/bin/bash
make target ARGS=\"$@\"
The reason you don't want to do it in make, is that make parses the command line parameters before it parse the makefile itself, so by the time you read the makefile, the targets, variables, etc have already been set. This means that make will have already interpreted the extra parameters as new targets, variables etc.
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