Some days ago I posted an answer in stack overflow about how to write a hierarchical make (http://stackoverflow.com/questions/1498213/make-hierarchical-make-file). The answer was deleted, therefore I assume that it was completely wrong or off topic (or both).
I would like to know how to write hierarchical Makefile. This is a Makefile that calls several Makefiles in sub-directories. I assume a directory structure like:
- project
|--module1
|--Makefile
|--...
|--module2
|--Makefile
|--module2.1
|--module2.2
|--...
|--module3
|--Makefile
|--...
|--etc
I also assume that the project members have only agreed only upon a minimal set of makefile targets like: all (default), clean, install, and so. So, the following commands including make flags will be propagate to the modules:
cd project
make clean
make -k
make install
#etc
What is wrong with the following project Makefile:
PACKAGES = \
module1 \
module2 \
emodule3
VIRTUAL_PACKAGES = $(addsuffix /.virtual.Makefile,${PACKAGES})
TARGETS=clean install all
.PHONY: $(TARGETS)
default: all
FLAGS = $(ifeq $(MAKEFLAGS) "","",-$(MAKEFLAGS))
$(TARGETS): $(VIRTUAL_PACKAGES)
$(VIRTUAL_PACKAGES):
$(MAKE) $(FLAGS) -C $(@D) $(MAKECMDGOALS)
yes, the $VIRTUAL_PACKAGES in the Makefile looks odd. The alternative of mixing a for loop is a bit shorter but I am not sure if it is better (as I need to rely on bash): PACKAGES = \ module1 \ module2 \ emodule3
TARGETS=clean install all
.PHONY: $(TARGETS)
default: all
FLAGS = $(ifeq $(MAKEFLAGS) "","",-$(MAKEFLAGS))
$(TARGETS):
for p in $(PACKAGES) ; do $(MAKE) $(FLAGS) -C $$p $@ || break; done
Thanks!
A Makefile consists of a set of rules. A rule generally looks like this: targets: prerequisites command command command The targets are file names, separated by spaces.
A Makefile consists of a set of rules. A rule generally looks like this: The targets are file names, seperated by spaces. Typically, there is only one per rule. The commands are a series of steps typically used to make the target (s). These need to start with a tab character, not spaces. The prerequisites are also file names, seperated by spaces.
If the environment variable MAKEFILES is defined, make considers its value as a list of names (separated by white space) of additional makefiles to be read before the others. This works much like the include directive: various directories are searched for those files.
Using this form of makefile is sufficient for most small scale projects. However, there is one thing missing: dependency on the include files. If you were to make a change to hellomake.h, for example, make would not recompile the .c files, even though they needed to be.
There are "dragons" here. It can be done, but the implications can be tricky.
Google, "Recursive Make Considered Harmful". You will get very good (simple) illustrations of exactly what you want (e.g., hierarchical-make), plus good explanations of the pitfalls/concerns. Some of the "responses" will discuss possible "best-practices", and ways to mitigate problems. Then, you can decide if the issues raised are compelling for your application or not.
The original paper:
http://miller.emu.id.au/pmiller/books/rmch/
Some other links:
http://c2.com/cgi/wiki?RecursiveMakeConsideredHarmful
http://dbaspot.com/configuration-management/194597-thoughts-recursive-make-considered-harmful.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With