The eMake subbuild feature is designed to help speed up component builds through intelligent build avoidance. Currently, the subbuild feature’s scope includes the following use case:
Makefile: ------------- .PHONY: a b all: a b @echo all a b: $(MAKE) -C $@
a/Makefile ------------- all: a.lib @echo a
a.lib: @touch $@
b/Makefile ------------- all: ../a/a.lib @echo b
Explanation : If something from ‘ a
’ changes, and you are building from ‘ b
’, the only way to pick up the new a.lib
is to build from the top level directory. With subbuilds, you know b
’s dependencies so you can build those dependencies directly without having to build everything from the top level directory.
The subbuild database must be built beforehand to make the dependency list available without having to parse any Makefiles that are not in the current directory.
The following sections describe how to use subbuilds. Refer to Subbuild Limitations for additional information about subbuild limitations.
Subbuild Database Generation
The following command runs your build as normal and also generates a subbuild database with the name emake.subbuild.db
.
emake --emake-gen-subbuild-db=1 --emake-root=<path> --emake-subbuild-db=emake.subbuild.db
Where < path
> is the eMake root directory setting.
--emake-root
is required for cluster builds.
--emake-subbuild-db
is optional. If it is missing, the default emake.subbuild.db
name is used.
Run a Build Using Subbuild
The following command runs a build with subbuild information:
emake --emake-subbuild-db=emake.subbuild.db
Specify --emake-subbuild-db=<file>
to run a build with subbuild information. When you invoke eMake with the --emake-subbuild-db
option, it uses the dependencies extracted from the makefile and the subbuild database to determine which build components are prerequisites of the desired current make, then rebuilds those components before proceeding as normal.
When you specify --emake-subbuild-db=<file>
, do not specify --emake-gen-subbuild-db
, otherwise eMake regenerates the database.
Subbuild Limitations
-
There is no incremental building of the database. Each time you change something in a makefile in your build, you must rebuild the database by doing a full build.
-
The database is not currently optimized for size. This might result in an extremely large database for very large builds.
-
Subbuilds do not provide additional gains in non-recursive make builds.
-
Because of the manner in which subbuilds are currently scheduled, there is interleaving output for the “Entering directory…” and “Leaving directory…” messages.
For example: If a subbuild database was built for the following build:
Makefile: ------------- .PHONY: a b all: a b a b: $(MAKE) -C $@
a/Makefile ---------------- all: a.lib a.lib: echo aaa > $@
b/Makefile: ---------------- all: ../a/a.lib echo b
When you proceed to build just ‘ b
’ (maybe with “ emake -C b
”) and a/a.lib
is missing, you receive “entering directory a” after “entering directory b”, even though ‘ a
’ is supposed to be built before ‘ b
’.
make: Entering directory 'b' make -C a make[1]: Entering directory 'a' echo aaa > a.lib make[1]: Leaving directory 'a' echo b b make: Leaving directory 'b'
Information Applying to Local Builds Only
-
Rules to build a sub-directory’s output files must not overlap. For example: The rule to build
sub1/foo.o
must appear insub1/Makefile
only and notsub2/Makefile
. Default suffix rules can cause eMake to find a way to buildsub1/foo.o
while trying to buildsub2
. In this situation, adding “.SUFFIXES:
” tosub2/Makefile
can resolve the issue. -
Subbuilds require that the build be componentized to some degree.
-
Subbuilds require that you have practiced “good hygiene” in your build tree—there must be explicit dependencies mentioned in the component makefiles.
For example: If a build has two components, foo
and bar
, where foo
produces a library foo.dll
and bar
uses that library, the rule might be written to produce bar.exe
such as this in bar/Makefile
:
bar.exe: $(BAR_OBJS) link $(BAR_OBJS) -l $(OUTDIR)/foo/foo.dll
For subbuilds to work (in local mode), it must be modified as in the following:
bar.exe: $(BAR_OBJS) $(OUTDIR)/foo/foo.dll link $(BAR_OBJS) -l $(OUTDIR)/foo/foo.dll
Note that it is explicitly stated that bar.exe
requires foo.dll
. Also note that it is NOT required to have a rule to build foo.dll
in bar/Makefile
.
There cannot be ANY rule at all to build $(OUTDIR)/foo/foo.dll
in bar/Makefile
, explicit or implicit, otherwise you will get the wrong information for building foo/foo.dll
in the subbuilds database. The subbuilds database currently allows updates to existing entries while building the database.