I wrote a Makefile which uses a similar idea to the one here. That is, I define a set of directories and using foreach
and define
I build all objects in each one of the directories. Here how my Makefile looks roughly
all_dirs := $(shell ...) # long shell command which finds all directories
all_objs := $(shell ...) # long shell command which finds all objects
define compile_rule
$(BUILDDIR)/$(1)/%.o : $(1)/%.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep)
endef
$(foreach dir,$(all_dirs:$(BUILDDIR)/%=%),$(eval $(call compile_rule,$(dir))))
all : program_name
program_name: $(all_objs)
$(LD) -o $@ $(all_objs) $(LDFLAGS)
I always run the make
command with -j32
argument. Usually it works fine but in some cases I get an error from the Makefile it self saying No rule to make target
with the first object file name in $(all_objs)
list needed by program_name
.
Looking here the problem is clear. Since I'm using -j
it seems like the make command starts to evaluate program_name
before it expands the rules created by foreach
. I tried to write the foreach
inside a rule so I could guarantee the order of execution between program_name
and the foreach
but then I got the error prerequisites cannot be defined in recipes
.
Any idea how to solve this? I might be able to solve this using a two step make, that is by first building $(all_objs)
with something like make objs
and then linking them together with something like make prog
but I prefer it will all happen in one command and I have a feeling I miss something simple. Please advise.