Consider the following setup:
$ touch 1.src 2.src 3.src
$ cat Makefile
%.dst: %.src
@convert -o "$@" "$<"
We can compile our .src
files into .dst
files by running make 1.dst 2.dst 3.dst
which calls the convert
(just a placeholder) tool three times.
This setup is fine if there is little overhead in calling convert
. However, in my case, it has a startup penalty of a few seconds for every single call. Luckily, the tool can convert multiple files in a single call while paying the startup penalty only once, i.e. convert -o '{}.dst' 1.src 2.src 3.src
.
Is there a way in GNU make to specify that multiple src files should be batched into a single call to convert
?
Edit: To be more precise, what feature I am looking for: Say that 1.dst
is already newer than 1.src
so it doesn't need to be recompiled. If I run make 1.dst 2.dst 3.dst
, I would like GNU make to execute convert -o '{}.dst' 2.src 3.src
.
A quick and dirty way would be creating a .PHONY
rule that simply converts all src files to dst files but that way I would convert every src file each and every time. Further more, specifying dst files as prerequisites in other rules would also no longer be possible.
Thanks in advance!
If you have GNU make 4.3 or above, you can use grouped targets like this:
DST_FILES = 1.dst 2.dst 3.dst
SRC_FILES = $(_DST_FILES:.dst=.src)
all: $(DST_FILES)
$(DST_FILES) &: $(SRC_FILES)
convert -o '{}.dst' $?
@touch $(DST_FILES)
If your convert
is only updating some of the targets then you need the explicit touch
to update the rest.
Here's a way to do it with passing a goal on the command line that might work; change DST_FILES
to:
DST_FILES := $(or $(filter %.dst,$(MAKECMDGOALS)),1.dst 2.dst 3.dst)