Makefile target with makefile as dependency - makefile

I am currently working on a project where I have a couple applications in a parent folder that need to be rebuilt whenever the libraries contained in child folders are updated. The apps in the parent folder are built with a makefile, and the libraries are built with a separate makefile in the respective folder. This looks something like :
ParentDir
app1
app2
Makefile
libdir1
Makefile
libdir2
Makefile
I'm currently doing something like this for my makefile in the parent dir
all : app1 app2
libs = libdir1/lib1.a libdir2/lib2.a
.PHONY : $(libs)
$(all) : $(libs)
#do stuff to make the apps
libdir1/lib1.a :
$(MAKE) -c libdir1
libdir2/lib2.a :
$(MAKE) -c libdir2
My problem is, I don't want the apps in the parent dir's makefile to rebuild unless one of the makefiles it "depends" on are updated. I know that the reason this is happening currently is that I have my libs declared as PHONY ( so they always rebuild ), but that was the only way I could figure out to actually call the children makefiles.
So, what I want is for each app to build only when either of the libdirs makefile's would actually do something, and to call each libdir's makefile that would "do something" before building the app.
Thanks for your help in advance.

You should make a dummy dependency for the libraries so that their Makefiles are always processed. Here is a good example and explanation: http://owen.sj.ca.us/~rk/howto/slides/make/slides/makerecurs.html

Related

GNU Make does not include all auto-generated includes before executing dependent rule

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:
Build index.html.build_deps
Include index.html.build_deps
Build global.css (now a known prerequisite of index.html)
Build index.html
Build index.html.runtime_deps
Include index.html.runtime_deps
Build about.html (contained inside $(runtime_deps_index.html) included from index.html.runtime_deps)
Target all is reached
What actually happens:
Make sees that index.html.build_deps can be directly build from index.html.in; does so.
Make sees that index.html.runtime_deps can be built from index.html, can be built from index.html.in.
Make builds 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.
#Dario is correct. To be a bit more specific, these are the steps make will follow here:
Read the makefile.
Try to build target1.deps.
Find a target target1.deps and execute the recipe.
The recipe succeeds, but make observes that the file target1.deps still does not exist, so make doesn't mark the target as updated.
Try to build target2.deps.
There's a target for it that depends on 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).
So, make decides none of the included makefiles were actually updated and it won't re-exec.
Then make wants to build 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.

Prefix an inherited Makefile target

My project's Makefile includes another makefile to which we do not want to make local modifications.
From it, we inherit a target called test.
How can I edit my own Makefile, to ensure a custom command gets run before the inherited make test target?
I get around this now by defining a new itest target, but I'd rather just be able to call make test.
include: other-project/rules.mk
.PHONY: itest
itest:
<my-command> $(MAKE) test
Just add a prerequisite:
include: other-project/rules.mk
test: itest
.PHONY: itest
itest:
<my-command>

Best way to define makefile dependencies when the compiler doesn't generate them?

I'm creating a makefile to build an existing project. We're using GNU Make 4, but the compiler doesn't automatically generate dependency information so I'm trying to determine the best way to specify dependencies for code that includes header files which in turn may include header files. Due to the complexity of the codebase, I think it will be unrealistic to traverse the entire #include tree, gather up all the header files, and then specify them for each source file.
One solution is to create makefile definitions of each header file and its direct dependencies, then create a recipe for a header file that touches that header file to trigger the recompile of the source that includes it:
a123.o: a123.c header1.h
header1.h: header2.h
header2.h: header3.h
# Recipes
%.o:
# compile command for building a .o
%.h:
#touch $#
This seems to work; if header3.h changes, then the %.h recipe updates header2.h's timestamp, which causes header1.h's timestamp to be updated, which causes a123.o to be rebuilt.
However, it seems messy, with all the touching, plus it seems odd to create a recipe for a source file that isn't directly compiled. Is this the correct way to do this sort of thing, or is there a cleaner approach? Please note that I simplified my question; in reality several languages are in use with different file extensions, the compiler isn't GCC, and the output isn't a .o file. But the logic is exactly the same.

GCC dependencies generation full path

In a makefile I am trying to build the list of dependencies for a cpp file. This is the structure of the makefile:
DEPS=dep_file
build:
$(MAKE) dep_file;
.....
dep_file:
#$(GXX) -MM $(file_path) | $(SED) 's/\.o:/.cpp.html:/' >$(DEPS)
I am getting this error when caling the build target for the file CC_Interface.cpp:
/prj/comp/cc/base/src/CC_Interface.h:42:17: CMF.h: No such file or directory
/prj/comp/cc/base/src/CC_Interface.h:43:25: Data.h: No such file or directory
/prj/comp/cc/base/src/CC_Interface.h:44:26: UTMsg.h: No such file or directory
/prj/comp/cc/base/src/CC_Interface.cpp:53:26: bb/Elem.hpp: No such file or directory
/prj/comp/cc/base/src/CC_Interface.cpp:56:18: BB.hpp: No such file or directory
...............
In /prj/comp/cc/base/src I have CC_Interface.h/cpp.
In /prj/comp/bb/ I have Elem.hpp
I want to obtain the full path when building the file with dependencies in the dep_file target from makefile. I was triyng -M, -MM, -MM -MT but it doesn't work.
There is a section in the manual on generating prerequisites automatically. You may not need to follow the whole thing, but at least follow the general setting up of targets, prereqs, and recipe.

How can I control the order in which make targets are executed?

Let's say I have a main target, exe which depends on three libs:
exe: LIB1.lib LIB2.lib LIB3.lib
and the lib targets have something like this:
LIB1: $(LIB1OBJECTS)
LIB2: $(LIB2OBJECTS)
LIB3: $(LIB3OBJECTS)
Giving that most of the time, make will be run with a -j flag, and I would like for LIB1 and LIB2 to be built in parallel, how can I make sure that LIB3 is always built after LIB2?
Make LIB3 dependent on LIB2.

Resources