automake-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

FYI: BUILT_SOURCES example


From: Alexandre Duret-Lutz
Subject: FYI: BUILT_SOURCES example
Date: Mon, 02 Dec 2002 19:01:26 +0100
User-agent: Gnus/5.090008 (Oort Gnus v0.08) Emacs/20.7 (i386-debian-linux-gnu)

I'm checking this in (HEAD & branch-1-7).

2002-12-02  Alexandre Duret-Lutz  <address@hidden>

        * automake.texi (Sources): Illustrate $(BUILT_SOURCES) with an
        example.

Index: automake.texi
===================================================================
RCS file: /cvs/automake/automake/automake.texi,v
retrieving revision 1.305.2.5
diff -u -r1.305.2.5 automake.texi
--- automake.texi       2 Dec 2002 08:09:33 -0000       1.305.2.5
+++ automake.texi       2 Dec 2002 18:00:07 -0000
@@ -3466,7 +3466,7 @@
 
 @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 @@
 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
address@hidden targets are made.  However, such a source file is not
-compiled unless explicitly requested by mentioning it in some other
address@hidden 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.
 
address@hidden 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
address@hidden variable @code{bindir} (inherited from @file{configure})
+as follows.
+
address@hidden
+bindir.h:
+        echo '#define bindir "$(bindir)"' >$@@
address@hidden example
+
+It would be possible to define this preprocessor macro from
address@hidden, 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}.
+
address@hidden
+# 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)"' >$@@
address@hidden 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.
+
address@hidden
+% 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
address@hidden example
+
+A solution is to require @file{bindir.h} to be built before anything
+else.  This is what @code{BUILT_SOURCES} is meant for.
+
address@hidden
+bin_PROGRAMS = foo
+foo_SOURCES = foo.c
+BUILT_SOURCES = bindir.h
+CLEANFILES = bindir.h
+bindir.h:
+        echo '#define bindir "$(bindir)"' >$@@
address@hidden example
+
+See how @file{bindir.h} get built first:
+
address@hidden
+% 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'
address@hidden example
+
+However, as said earlier, @code{$(BUILT_SOURCES)} applies only to the
address@hidden and @code{check} targets.  It still fails if you try to run
address@hidden foo} explicitly:
+
address@hidden
+% 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
address@hidden 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
address@hidden
+
address@hidden
+bin_PROGRAMS = foo
+foo_SOURCES = foo.c
+foo.$(OBJEXT): bindir.h
+CLEANFILES = bindir.h
+bindir.h:
+        echo '#define bindir "$(bindir)"' >$@@
address@hidden 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).
address@hidden(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
address@hidden 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

-- 
Alexandre Duret-Lutz





reply via email to

[Prev in Thread] Current Thread [Next in Thread]