bug-automake
[Top][All Lists]
Advanced

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

Re: automake 1.7.1 dependency tracking regression?


From: David Relson
Subject: Re: automake 1.7.1 dependency tracking regression?
Date: Mon, 02 Dec 2002 07:41:14 -0500

Alexandre,

The proposed documentation is well written and easy to understand. The content is excellent. I have a few corrections and suggestions.

Using configure to generate bindir.c should be suggested sooner. As the last line, at the end of the example, it could easily be missed. Perhaps it go just _before_ the example.

You have misspelled "explicitly" in several places.  It only has one "e" in it.

In the first sentence of "Built sources", the word "otherwise" is clumsy. I'd use "normally" in its place.

Well done. As a picky reader I often find many more flaws in the documents I read. You've done a good job.

David

At 06:34 AM 12/2/02, Alexandre Duret-Lutz wrote:

Sorry for the delay.

>>> "Matthias" == Matthias Andree <address@hidden> writes:

[...]

 Matthias> Could this be documented in 1.7.2/1.8 automake.info
 Matthias> until it's fixed -- for example, the dependencies and
 Matthias> BUILT_SOURCES sections were good places to list this.

(It's unlikely to get fixed.)

Here is a proposal for the documentation.  Let me know what you
think.  It also answers your other questions.

Built sources
=============

   Occasionally a file which would otherwise be called `source' (e.g. a
C `.h' file) is actually derived from some other file.  Such files
should be listed in the `BUILT_SOURCES' variable.

   `BUILT_SOURCES' is actually a bit of a misnomer, as any file which
must be created early in the build process can be listed in this
variable.

   A source file listed in `BUILT_SOURCES' is created on `make all' or
`make check' before other targets are made.  However, such a source
file is not compiled unless explicitly requested by mentioning it in
some other `_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
`BUILT_SOURCES', to ensure that they would be built before any other
compilations (perhaps ones using these headers) were started.

Example
-------

   Here is an example.  `foo.c' includes `bindir.h', which is built on
demand and not distributed.

     # This won't work.
     bin_PROGRAMS = foo
     foo_SOURCES = foo.c
     nodist_foo_SOURCES = bindir.h
     CLEANFILES = bindir.h
     bindir.h:
             echo "#define bindir \"@address@hidden"" >$@

   This setup doesn't work, because Automake doesn't know that `foo.c'
includes `bindir.h'.  Remember, automatic dependency tracking works as
a side-effect of compilation, so the dependencies of `foo.o' will be
known only after `foo.o' has been compiled (*note Dependencies::).  The
symptom is as follows.

     % 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

   A solution is to require `bindir.h' to be built before anything
else.  This is what `BUILT_SOURCES' is meant for.

     bin_PROGRAMS = foo
     foo_SOURCES = foo.c
     BUILT_SOURCES = bindir.h
     CLEANFILES = bindir.h
     bindir.h:
             echo "#define bindir \"@address@hidden"" >$@

   See how `bindir.h' get built first:

     % make
     echo >bindir.h "#define bindir \"/usr/local/bin\""
     make  all-am
     make[1]: Entering directory `/home/adl/tmp/automake-bindir'
     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/automake-bindir

   However, as said earlier, `$(BUILT_SOURCES)' applies only to the
`all' and `check' targets.  It still fails if you try to run `make foo'
explicitly

     % 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 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

   Usually people are happy enough with `$(BUILT_SOURCES)' because they
never run such targets before `make all'.  However if this matters to
you, you can record such dependencies explicitely in the `Makefile.am'.

     bin_PROGRAMS = foo
     foo_SOURCES = foo.c
     bindir.$(OBJEXT): bindir.h
     CLEANFILES = bindir.h
     bindir.h:
             echo "#define bindir \"@address@hidden"" >$@

   You don't have to list _all_ the dependencies if `foo.o'
explicitely, only those which need to be built.  If a dependencies
already exist, it will not hinder the first compilation, and will be
recorded by the normal dependency tracking code.

   This game can turn to be a bit dangerous if you are not careful
enough.  `bindir.$(OBJEXT): bindir.h' overwrites any rule that Automake
may want to output to build `bindir.$(OBJEXT)'.  It happens to work
here because Automake doesn't have to output any `bindir.$(OBJEXT):'
target, as it relies on a suffix rule instead (i.e., `.c.$(OBJEXT):').
Always check the generated `Makefile.am' if you do this.

   Another much safer solution to the same problem is to generate
`bindir.h' from `configure'.

--
Alexandre Duret-Lutz





reply via email to

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