Reputation: 4288
I have a setup like this:
/Makefile
/foo/Makefile
/foo/bar/Makefile
/foo/baz/Makefile
The top-level Makefile contains a task which calls the /foo/Makefile
. This Makefiles creates a list of makefiles in the subdirectories (bar
, baz
in the example). For each subdir, it calls the Makefiles:
$(SUB_DIRS):
$(MAKE) -C $@
Which is fine for, say, the all
task. But if I want to do something else, I get stuck. Is there a possibility to pass the target to the list of sub-makefiles? For example:
$(SUB_DIRS):
$(MAKE) -C $@ <task>
clean: $(SUB_DIRS)-clean # or something?
Or is my whole concept wrong?
Upvotes: 13
Views: 9535
Reputation: 10486
You could simply use the MAKECMDGOALS
variable:
Make will set the special variable
MAKECMDGOALS
to the list of goals you specified on the command line. If no goals were given on the command line, this variable is empty.
$(SUB_DIRS):
+$(MAKE) -C $@ $(MAKECMDGOALS)
The +
sign is important so the underlying job server also handles the recursive make calls with the right amount of threads/core.
You can also use the $(foreach )
function like this:
clean:
$(foreach DIR, $(SUB_DIRS), $(MAKE) -C $(DIR) $@;)
Do note as @musicmatze mentionned in the comments that Make flags (like -j
) won't be passed to the sub-make processes correctly here.
Upvotes: 11
Reputation: 4288
I finally got it work. The approach is:
SUB_DIRS = $(wildcard */.)
SUB_DIRS_ALL = $(SUB_DIRS:%=all-%)
SUB_DIRS_TEST = $(SUB_DIRS:%=test-%)
SUB_DIRS_CLEAN = $(SUB_DIRS:%=clean-%)
#
# Standard task
#
all: $(SUB_DIRS_ALL)
test_uml: $(SUB_DIRS_TEST)
clean: $(SUB_DIRS_CLEAN)
$(SUB_DIRS_ALL):
@$(MAKE) $(MAKE_FLAGS) -C $(@:all-%=%)
$(SUB_DIRS_TEST):
@$(MAKE) $(MAKE_FLAGS) -C $(@:test-%=%) test
$(SUB_DIRS_CLEAN):
@$(MAKE) $(MAKE_FLAGS) -C $(@:clean-%=%) clean
I found this solution here: http://lackof.org/taggart/hacking/make-example/
Upvotes: 4
Reputation: 5477
Yes you simply do it as specified, the fun comes in handling at the next level when you may want to both do something and also potentially recurse again.
for example i have a recursive installation like this:
$(INSTALL_DIRS):
$(MAKE) -C $@ install
Upvotes: 1