MirBSD Weblog

Sponsored by
HostEurope Logo

MirBSD Weblog

All 1 2 3 4 5 6 7 8 9 10 11

Diego Biurrun, who was both actually present and interested in my FrOSCon talk, pointed me to a paper called "Recursive Make Considered Harmful" [1]. (Thank you!) In response to the question he asked about this during the Q&A session, I said that recursive Make is automake's default and only behavior. This is not true.

The author of the paper starts with an example project very much like mine (two .c files, one header) and creates an artificial module boundary. Unsurprisingly, dependencies do not work as they should any more. I have witnessed this phenomenon and have seen large recursive build systems fall apart. Continuing a mozilla build for example takes unacceptably long, and you see many IDL files unnecessarily being regenerated.

However, implementing the one-Makefile-per-project technique outlined by Miller is actually very easy to do in automake. Older automake versions did not have good support for source files in other directories but this has not been a problem at least since automake 1.8.

If you paid close attention, the Makefile.am I created in the talk was not really recursive because only one Makefile actually did some compiling. In fact, you can merge Makefile.am and src/Makefile.am into one file, like this:

ACLOCAL_AMFLAGS = -I .

bin_PROGRAMS = hw
hw_SOURCES = src/main.c src/hello.h
hw_LDADD = libhello.la

lib_LTLIBRARIES = libhello.la
libhello_la_SOURCES = src/hello.c src/hello.h
libhello_la_LDFLAGS = -version-info ${LIBHELLO_VER}

If you insert all your targets into one Makefile.am, the automatically inserted stuff from automake only needs to be inserted once, thus you get a lower overhead. Dependency tracking should be even more efficient, and build times should decrease. One technique proposed by Miller is to use per-project Makefile fragments which are included by the main Makefile. Automake supports an include directive, which is directly evaluated during the automake run and thus fully portable.

One problem I see with this approach is that all objects are put into one directory. Thus, you will have problems if different files in different directories have the same name. For example, compiling both foo/main.c and bar/main.c inside the same Makefile.am will not work. I do not know if there is an easy solution to this problem—perhaps an automake option to put the object files in subdirectories. Any automake expert reading this, please contact me if you know of something.

References

  1. Miller, P. A., Recursive Make Considered Harmful, AUUGN Journal of AUUG Inc., 19 (1), 14–25 (1998).

    URL: http://miller.emu.id.au/pmiller/books/rmch/

MirOS Logo