From 079244725cc129fa67861661490f0d99c753e8c8 Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Mon, 2 Dec 2002 18:01:28 +0000 Subject: [PATCH] * automake.texi (Sources): Illustrate $(BUILT_SOURCES) with an example. --- ChangeLog | 3 ++ automake.texi | 144 ++++++++++++++++++++++++++++++++++++++++++++++++-- stamp-vti | 4 +- version.texi | 4 +- 4 files changed, 146 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1d674bb5..843e8dab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2002-12-02 Alexandre Duret-Lutz + * automake.texi (Sources): Illustrate $(BUILT_SOURCES) with an + example. + * automake.texi (Options): Programs listed in AM_INSTALLCHECK_STD_OPTIONS_EXEMPT should have $(EXEEXT) appended. * tests/gnits3.test (AM_INSTALLCHECK_STD_OPTIONS_EXEMPT): diff --git a/automake.texi b/automake.texi index 5387574a..97782014 100644 --- a/automake.texi +++ b/automake.texi @@ -3466,7 +3466,7 @@ dist_pkgdata_DATA = clean-kr.am clean.am @dots{} @cindex BUILT_SOURCES, defined -Occasionally a file which would otherwise be called @samp{source} +Occasionally a file which would normally be called @samp{source} (e.g. a C @samp{.h} file) is actually derived from some other file. Such files should be listed in the @code{BUILT_SOURCES} variable. @vindex BUILT_SOURCES @@ -3475,16 +3475,150 @@ Such files should be listed in the @code{BUILT_SOURCES} variable. must be created early in the build process can be listed in this variable. -A source file listed in @code{BUILT_SOURCES} is created before the other -@code{all} targets are made. However, such a source file is not -compiled unless explicitly requested by mentioning it in some other -@samp{_SOURCES} variable. +A source file listed in @code{BUILT_SOURCES} is created on @code{make +all} or @code{make check} before other targets are made. However, such +a source file is not compiled unless explicitly requested by mentioning +it in some other @samp{_SOURCES} variable. So, for instance, if you had header files which were created by a script run at build time, then you would list these headers in @code{BUILT_SOURCES}, to ensure that they would be built before any other compilations (perhaps ones using these headers) were started. +@subsection Example + +Here is an example. Suppose that @file{foo.c} includes @file{bindir.h}, +which is built on demand and not distributed. Here @file{bindir.h} +defines the preprocessor macro @code{bindir} to the value of the +@command{make} variable @code{bindir} (inherited from @file{configure}) +as follows. + +@example +bindir.h: + echo '#define bindir "$(bindir)"' >$@@ +@end example + +It would be possible to define this preprocessor macro from +@file{configure}, either in @file{config.h} (@pxref{Defining +Directories, , Defining Directories, autoconf, The Autoconf Manual}), or +by processing a @file{bindir.h.in} file using @code{AC_CONFIG_FILES} +(@pxref{Configuration Actions, ,Configuration Actions, autoconf, The +Autoconf Manual}). It's even safer because you won't have to play the +dirty tricks discussed below. However, it's not always possible to +build sources from @file{configure} (especially when these sources are +generated by a tool that needs to be built first...). So let's ignore +this possibility and discuss the implication of building @file{bindir.h} +at @command{make} time. + +Here is a tentative @file{Makefile.am}. + +@example +# This won't work. +bin_PROGRAMS = foo +foo_SOURCES = foo.c +nodist_foo_SOURCES = bindir.h +CLEANFILES = bindir.h +bindir.h: + echo '#define bindir "$(bindir)"' >$@@ +@end example + +This setup doesn't work, because Automake doesn't know that @file{foo.c} +includes @file{bindir.h}. Remember, automatic dependency tracking works +as a side-effect of compilation, so the dependencies of @file{foo.o} will +be known only after @file{foo.o} has been compiled (@pxref{Dependencies}). +The symptom is as follows. + +@example +% make +source='foo.c' object='foo.o' libtool=no \ +depfile='.deps/foo.Po' tmpdepfile='.deps/foo.TPo' \ +depmode=gcc /bin/sh ./depcomp \ +gcc -I. -I. -g -O2 -c `test -f 'foo.c' || echo './'`foo.c +foo.c:2: bindir.h: No such file or directory +make: *** [foo.o] Error 1 +@end example + +A solution is to require @file{bindir.h} to be built before anything +else. This is what @code{BUILT_SOURCES} is meant for. + +@example +bin_PROGRAMS = foo +foo_SOURCES = foo.c +BUILT_SOURCES = bindir.h +CLEANFILES = bindir.h +bindir.h: + echo '#define bindir "$(bindir)"' >$@@ +@end example + +See how @file{bindir.h} get built first: + +@example +% make +echo '#define bindir "/usr/local/bin"' >bindir.h +make all-am +make[1]: Entering directory `/home/adl/tmp' +source='foo.c' object='foo.o' libtool=no \ +depfile='.deps/foo.Po' tmpdepfile='.deps/foo.TPo' \ +depmode=gcc /bin/sh ./depcomp \ +gcc -I. -I. -g -O2 -c `test -f 'foo.c' || echo './'`foo.c +gcc -g -O2 -o foo foo.o +make[1]: Leaving directory `/home/adl/tmp' +@end example + +However, as said earlier, @code{$(BUILT_SOURCES)} applies only to the +@code{all} and @code{check} targets. It still fails if you try to run +@code{make foo} explicitly: + +@example +% make clean +test -z "bindir.h" || rm -f bindir.h +test -z "foo" || rm -f foo +rm -f *.o core *.core +% : > .deps/foo.Po # Suppress previously recorded dependencies +% make foo +source='foo.c' object='foo.o' libtool=no \ +depfile='.deps/foo.Po' tmpdepfile='.deps/foo.TPo' \ +depmode=gcc /bin/sh ./depcomp \ +gcc -I. -I. -g -O2 -c `test -f 'foo.c' || echo './'`foo.c +foo.c:2: bindir.h: No such file or directory +make: *** [foo.o] Error 1 +@end example + +Usually people are happy enough with @code{$(BUILT_SOURCES)} because +they never run such targets before @code{make all}. However if this +matters to you, you can record such dependencies explicitly in the +@file{Makefile.am}. + +@example +bin_PROGRAMS = foo +foo_SOURCES = foo.c +foo.$(OBJEXT): bindir.h +CLEANFILES = bindir.h +bindir.h: + echo '#define bindir "$(bindir)"' >$@@ +@end example + +You don't have to list @emph{all} the dependencies of @code{foo.o} +explicitly, only those which might need to be built. If a dependency +already exists, it will not hinder the first compilation and will be +recorded by the normal dependency tracking code. (Note that after this +first compilation the dependency tracking code will also have recorded +the dependency between @code{foo.o} and @code{bindir.h}; so our explicit +dependency is really useful to the first build only.) + +Adding explicit dependencies like this can be a bit dangerous if you are +not careful enough. This is due to the way Automake tries not to +overwrite your rules (it assumes you know better than it). +@code{foo.$(OBJEXT): bindir.h} supersedes any rule Automake may want to +output to build @code{foo.$(OBJEXT)}. It happens to work in this case +because Automake doesn't have to output any @code{foo.$(OBJEXT):} +target: it relies on a suffix rule instead (i.e., @code{.c.$(OBJEXT):}). +Always check the generated @file{Makefile.am} if you do this. + +It should be clearer now why building @file{bindir.h} from +@file{configure} is seducing for this example: @file{bindir.h} will +exist before you build any target, hence will not cause any dependency +issue. @node Other GNU Tools, Documentation, Other objects, Top @chapter Other GNU Tools diff --git a/stamp-vti b/stamp-vti index a777d3cb..2e497298 100644 --- a/stamp-vti +++ b/stamp-vti @@ -1,4 +1,4 @@ -@set UPDATED 13 November 2002 -@set UPDATED-MONTH November 2002 +@set UPDATED 2 December 2002 +@set UPDATED-MONTH December 2002 @set EDITION 1.7a @set VERSION 1.7a diff --git a/version.texi b/version.texi index a777d3cb..2e497298 100644 --- a/version.texi +++ b/version.texi @@ -1,4 +1,4 @@ -@set UPDATED 13 November 2002 -@set UPDATED-MONTH November 2002 +@set UPDATED 2 December 2002 +@set UPDATED-MONTH December 2002 @set EDITION 1.7a @set VERSION 1.7a -- 2.43.5