Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a simple hierarchical Makefile?

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!

like image 901
marcmagransdeabril Avatar asked Jul 09 '12 07:07

marcmagransdeabril


People also ask

What does a makefile consist of?

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.

What are the prerequisites for a makefile?

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.

What is the use of Make file in Linux?

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.

Is makefile enough for small scale projects?

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.


1 Answers

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

like image 110
charley Avatar answered Oct 14 '22 22:10

charley