I have a very simple Makefile that isn’t doing what I expect it would do. The ultimate goal is that it should call itself recursively, including the appropriate file each time, resulting in a build specific to what was included (I’m building several projects that all share the same code base, but utilize different combinations of the source files). I’ve never really dealt with recursive calls to make, so I must be missing something obvious. At the moment, I only have one .mk file in the same folder as my Makefile. It’s a simple one-liner just for the purposes of this test. It will eventually contain various per-project settings.
Makefile:
SHELL = /bin/sh
ifdef MYFILE
include $(MYFILE)
PROGRAM = $(basename $(MYFILE))
endif
all: $(wildcard *.mk)
dummy:
@echo -- Entering dummy stub ... why do I need this?
%.mk: dummy
@echo Calling $(MAKE) MYFILE=$@ $*
$(MAKE) MYFILE=$@ $*
$(PROGRAM): objs
@echo Time to link!
objs:
@echo Building objs!
test.mk
SOMEVAR = SomeValue
I have the following two problems:
Problem 1
If I remove the dummy prerequisite from my pattern rule, the pattern rule never gets called (I get the dreaded ‘Nothing to be done for all’ error). Is there a way I can get the recipes under the %.mk rule to run without needing that dummy prerequisite?
Problem 2
Given the two aforementioned files, I would expect make to do the following:
- make[1] starts and hit the
allrule - make[1] jumps down to the
%.mkpattern rule - make[1] calls itself recursively (the call would look like
make MYFILE=test.mk test) - make[2] starts, includes the test.mk file, and sets up the PROGRAM variable
- make[2] jumps down to the $(PROGRAM) rule (since we were explicitly called with that target)
- make[2] jumps to the objs rule, runs the recipes, and returns back up the chain
In actuality, make gets stuck on the %.mk pattern rule and enters an infinite loop. I don’t understand why it’s insisting on hitting the pattern rule, when I explicitly told it to build test in my first recursive call (which should correspond to the $(PROGRAM) target). What am I missing here?
Problem 0:
This is overdesigned. You don’t need to use recursive Make here.
Problem 1:
The reason Make doesn’t try to rebuild
test.mk(without a dummy preq) is thattest.mkis up to date. A better approach is to switch to a static pattern rule and use PHONY:An even better approach is not to use the name of a real file as a target of a rule that doesn’t rebuild (or even “touch”) that file.
Problem 2:
In make[2], the makefile includes
test.mk. If a makefile includes another file, Make will attempt to rebuild that file before doing anything else. If there is a rule for that file (which there is) and if it succeeds (which it does) Make then reinvokes itself.You should reconsider this design from the ground up. There are many ways to get the behavior you’re looking for, depending on the specifics (how many variable will be defined in a
foo.mk? do you really want to manage the build by manually moving those files around? and so on).P.S. Here’s one kludge that springs to mind. Whether it suits your case depends on the specifics:
makefile:
test.mk: