I would like to execute a task in several directories but found no "makefile-like" solution up to now. I know this is an often asked question and I know how to solve it for sub-makfiles and so on, but I am looking for something simpler.
Instead of doing
copy:
cd module1 && mkdir foo
cd module2 && mkdir foo
cd module3 && mkdir foo
I would like to have something like
directories = module1 module2 module3
copy: $(directories)
cd $< && mkdir foo
but that does not work, since the receipe is called only once with the first directory. I came up with this solution which works but is probably not in the style of Makefiles:
directories = module1 module2 module3
copy:
for d in $(directories); do cd $$d && mkdir foo && cd ..; done
How can I do this more nicely?
There are lots of ways of doing this.
You can do what Andrew suggests without hard-coding a prefix:
directories = module1 module2 module2
%/foo: ; mkdir -p -- "$@"
copy: $(addsuffix /foo,$(directories))
which gives
$ make -n copy
mkdir -p -- "module1/foo"
mkdir -p -- "module2/foo"
mkdir -p -- "module3/foo"
You can also generate the copy
target from the makefile:
directories = module1 module2 module2
define copy-target
copy:: ; cd $1 && mkdir foo
endef
$(foreach dir,$(directories),$(eval $(call copy-target,$(dir))))
This gives:
$ make -n copy
cd module1 && mkdir foo
cd module2 && mkdir foo
cd module3 && mkdir foo
You could also generate the commands, not the target:
directories = module1 module2 module2
copy: ; $(foreach dir,$(directories),(cd $(dir) && mkdir foo) &&) :
which results in
$ make -n copy
(cd module1 && mkdir foo) && (cd module2 && mkdir foo) && (cd module3 && mkdir foo) && :
In Makefiles, whenever you want to create a file, make a rule with the name of the file as the target, and give the command to create the target file.
copy: module1/foo module2/foo module3/foo
module%/foo:
mkdir $@
If you'd like to parameterize that a bit to avoid duplication, you could also write something like
MODULE_NUMBERS = 1 2 3
copy: ${MODULE_NUMBERS:%=module%/foo}
module%/foo:
mkdir $@
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