The (mini) c++ repository - make
Every C++ programmer using make to manage build order
should read the Recursive
make considered harmfull paper by Peter Miller.
Modern makefiles for developers
Makefiles are (ab)used for a variety of reasons these days. From
automatically building projects, over installation scripts to
configuration. On this page I focus on the first task, ie how
to write makefiles which are handy for a developer (in C/C++).
A lot of the following ideas build on the paper referenced
above.
First, what do I like in a Makefile?
- A makefile should stay out of the way. As it is merely a convencience
(albeit an important one), the less time spent toying with makefiles,
the better. Ideally, makefiles should be generated fully automatically.
But, once generated, it should still be possible to edit them by
hand. An alternative is a static template which seperates build
logic from build files.
- Dependencies should be generated automatically. They should always
be accurate, complete but at the same as miminal as possible.
- Subdirectories should be handled gracefully. Recursive make is
in many ways not an answer. The above mentioned paper explains why.
I also dislike the one project=one directory approach. Even small
projects quickly consist of a large number of source files. It's easy
and convenient to put sources in relevant groups. And that's
exactly what directories are good for in my opinion.
- Makefiles should be transparant and easy to understand. Thus the need
for basic guidelines. Like an easy way to include extra source files.
Or an easy way to change configurations.
What is wrong with automake?
Automake is part
of the GNU build toolset and is responsible for generating Makefiles.
The first, obvious question, is why introduce yet another tool
in the build process? More tools means less transparency, greater
dependencies and much more that can go wrong in areas where a
developer does not necessarily has (or even WANT to have) the
necessary experience.
Automake is, despite it's name, also not fully automatic. Which
means as a developer you have to know certain things about it.
Since I am lazy
I feel the case for the use of Automake in a lot of projects is
not sufficiently strong. I think the advantages of using automake
can also be obtained with a well thought out template Makefile
which includes (simple) project specific Makefile fragments
enumerating (only) the sources which make up the project.
The modern Makefile
More specifically I am looking for a makefile which allows me
to write a Makefile fragment
include SubDir1/Makefile.fragment
include SubDir2/Makefile.fragment
CLASSES += MyClass1 MyClass2 MyClass3
and takes it from there after a simple 'make'.
This makefile
- stays out of the way. The main makefile is a template that doesn't change.
- handles dependencies automatically. Either with a .d file per source file or
one .d file for each subdir when using a fast dependency generator like
fastdep.
- does not descend recursively in each directory but instead includes
small fragments which describe the logical contents of one directory.
- is easy to understand and is transparent. No knowledge is needed for
a simple build user and only basic knowledge of make for a real developer.
- generates dependencies in a seperate step. This avoids problems such
as those in an
overview of dependency tracking in automake.
Remaining problems
I am still working on an good Makefile template. To get an idea
of how it looks, check out one of the
software packages I've written.
A few problems remain with my current approach.
- There is no easy way to only build one subdirectory of a project.
- The Makefile.files fragments still contain a but of redundant
information, which needs to be kept in sync by hand (notably, the
subdirectory part of the CLASSES_ variable).