Reputation: 5957
My makefile makes use of auto-generated dependencies. To do this, I have in my top-level makefile something similar to:
# Makefile
include target1.deps
include target2.deps
all: target2.deps
cat $^
target2.deps: target1.deps
target1.deps:
echo "target2.deps:" > $@
echo " touch target2.deps" >> $@
Initially, target1.deps
and target2.deps
do not exist. When make is first instantiated, it parses the entire Makefile and searches for a way to generate these include files. After building them, it reinvokes itself, causing the Makefile to be reparsed and the include files to be included this time. At least, that's my understanding.
The issue is that when I run the above Makefile, Make first builds target1.deps
, then executes the body of the all
rule, never having built or included target2.deps
. This causes cat
to error: cat: target2.deps: No such file or directory
This seems like a contradiction to me. I explicitly tell Make
that all
depends on target2.deps
, but it attempts to execute the rule before satisfying its prerequisites!
The intended behavior is that target1.deps
should be built and included, then target2.deps
should be built and included using the rule contained within target1.deps
, and then all
should be run. How do I achieve this?
Context: Since this is weirdly abstract, here's my goal: I have a target index.html
, which gets generated from a template index.html.in
, but I don't know anything about its dependencies. I need to find out (a) which files I need to create before building index.html
and (b) which files index.html
will depend on at runtime.
For example index.html
includes some inline css that's pulled out of global.css
- I need to therefore build global.css
before building index.html
. On the other hand, index.html
links to about.html
, so after I build index.html
I want to also build about.html
. I call the former "build dependencies" and the latter "runtime dependencies". So my makefile looks something like this:
include index.html.build_deps
include index.html.runtime_deps
all: index.html $(runtime_deps_index.html)
%.build_deps: %.in
./extract_build_deps %< -o %@
%.runtime_deps: %
./extract_runtime_deps %< -o %@
%: %.in
./compile_template %< -o $@
What I want to happen is for Make to follow these steps:
index.html.build_deps
index.html.build_deps
global.css
(now a known prerequisite of index.html
)index.html
index.html.runtime_deps
index.html.runtime_deps
$(runtime_deps_index.html)
included from index.html.runtime_deps
)all
is reachedWhat actually happens:
index.html.build_deps
can be directly build from index.html.in
; does so.index.html.runtime_deps
can be built from index.html
, can be built from index.html.in
.index.html
. It errors because global.css
hasn't yet been built.If Make
had included index.html.build_deps
after building that, then it would be aware of the global.css
dependency. But because it tries to build all include files before expanding any of them, it's unaware of the dependency. I want to add a dependency "index.html.runtime_deps depends on index.html.build_deps having been included, but I'm not sure how to specify such a dependency.
Upvotes: 1
Views: 667
Reputation: 100781
@Dario is correct. To be a bit more specific, these are the steps make will follow here:
target1.deps
and execute the recipe.target1.deps
still does not exist, so make doesn't mark the target as updated.target1.deps
, which make already built, but there's no recipe for it so make doesn't mark target2.deps
as updated (since it was never updated, as far as make can tell--it didn't run any recipe to update it).all
; it sees that all
depends on target2.deps
but make already considered that target and decided it didn't need to be rebuilt, so now make is done with all its work.You can run make -d
and follow along with the decisions make takes.
Upvotes: 3