.\" .\" aegis - project change supervisor .\" Copyright (C) 1997, 2001, 2002, 2006-2008, 2010, 2012 Peter Miller .\" .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by .\" the Free Software Foundation; either version 3 of the License, or .\" (at your option) any later version. .\" .\" This program is distributed in the hope that it will be useful, .\" but WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU .\" General Public License for more details. .\" .\" You should have received a copy of the GNU General Public License .\" along with this program. If not, see . .\" .nh 1 "The Big Picture" This section brings together all of the preceding discussion, and presents the example project with its separate modules, but with a whole\[hy]project \f(CWMakefile\fP. The directory structure is changed little from the recursive case, except that the deeper \f(CWMakefiles\fP are replaced by module specific include files: .so lib/en/auug97/07.figure1.so .LP The \f(CWMakefile\fP looks like this: .TS H center,box; lw(2.5i)f(CW). .TH MODULES := ant bee .sp 0.2 # look for include files in # each of the modules CFLAGS += $(patsubst %,\-I%,\e $(MODULES)) .sp 0.2 # extra libraries if required LIBS := .sp 0.2 # each module will add to this SRC := .sp 0.2 # include the description for # each module include $(patsubst %,\e %/module.mk,$(MODULES)) .sp 0.2 # determine the object files OBJ := \e $(patsubst %.c,%.o, \e $(filter %.c,$(SRC))) \e $(patsubst %.y,%.o, \e $(filter %.y,$(SRC))) .sp 0.2 # link the program prog: $(OBJ) $(CC) \-o $@ $(OBJ) $(LIBS) .sp 0.2 # include the C include # dependencies include $(OBJ:.o=.d) .sp 0.2 # calculate C include # dependencies %.d: %.c depend.sh `dirname $*.c` \e $(CFLAGS) $*.c > $@ .TE This looks absurdly large, but it has all of the common elements in the one place, so that each of the modules' \fImake\fP includes may be small. .LP The \f(CWant/module.mk\fP file looks like: .TS center,box; lw(2.5i)f(CW). SRC += ant/main.c .TE The \f(CWbee/module.mk\fP file looks like: .TS center,box; lw(2.5i)f(CW). SRC += bee/parse.y LIBS += \-ly .sp 0.2 %.c %.h: %.y $(YACC) \-d $*.y mv y.tab.c $*.c mv y.tab.h $*.h .TE .LP Notice that the built\[hy]in rules are used for the C files, but we need special yacc processing to get the generated \f(CW.h\fP file. .LP The savings in this example look irrelevant, because the top\[hy]level \f[CW]Makefile\fP is so large. But consider if there were 100 modules, each with only a few non\[hy]comment lines, and those specifically relevant to the module. The savings soon add up to a total size often \fIless than\fP the recursive case, without loss of modularity. .LP The equivalent DAG of the \f(CWMakefile\fP after all of the includes looks like this: .so lib/en/auug97/07.figure2.so .LP The vertexes and edges for the include file dependency files are also present as these are important for \fImake\fP to function correctly. .nh 2 "Side Effects" There are a couple of desirable side\[hy]effects of using a single Makefile. .LP \(bu The GNU Make \f[CW]\-j\fP option, for parallel builds, works even better than before. It can find even more unrelated things to do at once, and no longer has some subtle problems. .\" My thanks to Marcus Harnisch for this .\" insight into parallel build problems. .LP \(bu The general make \f[CW]\-k\fP option, to continue as far as possible even in the face of errors, works even better than before. It can find even more things to continue with. .\" vim: set ts=8 sw=4 et :