automake
[Top][All Lists]
Advanced

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

Re: Removing dependencies


From: Alexandre Duret-Lutz
Subject: Re: Removing dependencies
Date: Mon, 07 Apr 2003 21:11:48 +0200
User-agent: Gnus/5.090016 (Oort Gnus v0.16) Emacs/21.2 (gnu/linux)

>>> "Bill" == Bill Moseley <address@hidden> writes:

[...]

 Bill> This works fine with GNU Make because (if I understand correctly) the
 Bill> GNU Make looks for *targets* in the VPATH as well as the current
 Bill> directory.

 Bill> What I'm seeing on BSD it only searches for source files.
 Bill> So the targets are missing (in the build directory, but
 Bill> not in the sourcedir) so it always runs the rules to
 Bill> rebuild the docs.

Correct.  The issues we know about make portability are summarized in
the `Limitation of Make' section of the *Autoconf* manual.  I'm
appending the part about `VPATH & target lookup' below because it has
been significantly augmented since the last Autoconf release.

An issue similar to yours plagues all the Automake 1.7.x
releases.  Automake <= 1.6.x used to build info files in
$(srcdir), because these files are distributed.  In 1.7, I
changed the rules to build info files in the build directory.
The intent was to simplify the code and prepare support for
non-distributed info files (as well as non-distributed texi
files).  Unfortunately it "broke" VPATH builds with most BSD
implementations: the info files get always rebuilt when you
attempt a VPATH built on such system.  In 1.8 I'll have to
revert these rules back to the way they were, so that info files
are built in $(srcdir).

Generally, forcing a target to be built in $(srcdir) is just a
matter of prefixing everything you can put your hands on with
`$(srcdir)', including the target itself.



    target lookup
          GNU `make' uses a rather complex algorithm to decide when it
          should use files found via a `VPATH' search.  *Note How
          Directory Searches are Performed: (make)Search Algorithm.
          
          If a target needs to be rebuilt, GNU `make' discards the
          filename found during the `VPATH' search for this target, and
          builds the file locally using the filename given in the
          `Makefile'.  If a target does not need to be rebuilt, GNU
          `make' uses the filename found during the `VPATH' search.
          
          Other `make' implementations, like NetBSD `make', are easier
          to describe: the filename found during the `VPATH' search
          will be used whether the target needs to be rebuilt or not.
          Therefore new files are created locally, but existing files
          are updated at their `VPATH' location.

          OpenBSD and FreeBSD `make's, however, will never perform a
          `VPATH' search for a dependency which has an explicit rule.
          This is extremely annoying.
          
          When attempting a `VPATH' build for an autoconfiscated package
          (e.g, `mkdir build; ../configure'), this means the GNU `make'
          will build everything locally in the `build' directory, while
          BSD `make' will build new files locally and update existing
          files in the source directory.

               % cat Makefile
               VPATH = ..
               all: foo.x bar.x
               foo.x bar.x: newer.x
                       @echo Building $@
               % touch ../bar.x
               % touch ../newer.x
               % make        # GNU make
               Building foo.x
               Building bar.x
               % pmake       # NetBSD make
               Building foo.x
               Building ../bar.x
               % fmake       # FreeBSD make, OpenBSD make
               Building foo.x
               Building bar.x
               % tmake       # Tru64 make
               Building foo.x
               Building bar.x
               % touch ../bar.x
               % make        # GNU make
               Building foo.x
               % pmake       # NetBSD make
               Building foo.x
               % fmake       # FreeBSD make, OpenBSD make
               Building foo.x
               Building bar.x
               % tmake       # Tru64 make
               Building foo.x
               Building bar.x

          Note how NetBSD `make' updates `../bar.x' in its VPATH
          location, and how FreeBSD, OpenBSD, and Tru64 `make' always
          update `bar.x', even when `../bar.x' is up to date.

          Another point worth mentioning is that once GNU `make' has
          decided to ignore a `VPATH' filename (e.g., it ignored
          `../bar.x' in the above example) it will continue to ignore
          it when the target occurs as a prerequisite of another rule.

          The following example shows that GNU `make' does not look up
          `bar.x' in `VPATH' before performing the `.x.y' rule, because
          it ignored the `VPATH' result of `bar.x' while running the
          `bar.x: newer.x' rule.

               % cat Makefile
               VPATH = ..
               all: bar.y
               bar.x: newer.x
                       @echo Building $@
               .SUFFIXES: .x .y
               .x.y:
                       cp $< $@
               % touch ../bar.x
               % touch ../newer.x
               % make        # GNU make
               Building bar.x
               cp bar.x bar.y
               cp: cannot stat `bar.x': No such file or directory
               make: *** [bar.y] Error 1
               % pmake       # NetBSD make
               Building ../bar.x
               cp ../bar.x bar.y
               % rm bar.y
               % fmake       # FreeBSD make, OpenBSD make
               echo Building bar.x
               cp bar.x bar.y
               cp: cannot stat `bar.x': No such file or directory
               *** Error code 1
               % tmake       # Tru64 make
               Building bar.x
               cp: bar.x: No such file or directory
               *** Exit 1

          Note that if you drop away the command from the `bar.x:
          newer.x' rule, GNU `make' will magically start to work: it
          knows that `bar.x' hasn't been updated, therefore it doesn't
          discard the result from `VPATH' (`../bar.x') in succeeding
          uses.  Tru64 will also work, but FreeBSD and OpenBSD still
          don't.

               % cat Makefile
               VPATH = ..
               all: bar.y
               bar.x: newer.x
               .SUFFIXES: .x .y
               .x.y:
                       cp $< $@
               % touch ../bar.x
               % touch ../newer.x
               % make        # GNU make
               cp ../bar.x bar.y
               % rm bar.y
               % pmake       # NetBSD make
               cp ../bar.x bar.y
               % rm bar.y
               % fmake       # FreeBSD make, OpenBSD make
               cp bar.x bar.y
               cp: cannot stat `bar.x': No such file or directory
               *** Error code 1
               % tmake       # True64 make
               cp ../bar.x bar.y

          It seems the sole solution that would please every `make'
          implementation is to never rely on `VPATH' searches for
          targets.  In other words, `VPATH' should be reserved to
          unbuilt sources.

-- 
Alexandre Duret-Lutz





reply via email to

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