[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: automake 1.7.1 dependency tracking regression?
From: |
Alexandre Duret-Lutz |
Subject: |
Re: automake 1.7.1 dependency tracking regression? |
Date: |
Mon, 02 Dec 2002 12:34:24 +0100 |
User-agent: |
Gnus/5.090008 (Oort Gnus v0.08) Emacs/20.7 (i386-debian-linux-gnu) |
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
- Re: automake 1.7.1 dependency tracking regression?,
Alexandre Duret-Lutz <=
- Re: automake 1.7.1 dependency tracking regression?, David Relson, 2002/12/02
- Re: automake 1.7.1 dependency tracking regression?, Alexandre Duret-Lutz, 2002/12/02
- Re: automake 1.7.1 dependency tracking regression?, David Relson, 2002/12/02
- Re: automake 1.7.1 dependency tracking regression?, Alexandre Duret-Lutz, 2002/12/02
- Re: automake 1.7.1 dependency tracking regression?, Matthias Andree, 2002/12/02
- Re: automake 1.7.1 dependency tracking regression?, Alexandre Duret-Lutz, 2002/12/02
- Re: automake 1.7.1 dependency tracking regression?, Matthias Andree, 2002/12/02
- Re: automake 1.7.1 dependency tracking regression?, David Relson, 2002/12/02
Message not available
Re: automake 1.7.1 dependency tracking regression?, Matthias Andree, 2002/12/02