(autoconf.info)Make Target Lookup


Prev: Tru64 Directory Magic Up: VPATH and Make

11.13.5 Make Target Lookup
--------------------------

GNU `make' uses a complex algorithm to decide when it should use files
found via a `VPATH' search.  Note: How Directory Searches are
Performed.

   If a target needs to be rebuilt, GNU `make' discards the file name
found during the `VPATH' search for this target, and builds the file
locally using the file name given in the makefile.  If a target does
not need to be rebuilt, GNU `make' uses the file name found during the
`VPATH' search.

   Other `make' implementations, like NetBSD `make', are easier to
describe: the file name found during the `VPATH' search is 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', however, never perform a `VPATH' search
for a dependency that has an explicit rule.  This is extremely annoying.

   When attempting a `VPATH' build for an autoconfiscated package
(e.g., `mkdir build && cd build && ../configure'), this means GNU
`make' builds everything locally in the `build' directory, while BSD
`make' builds new files locally and updates 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' file name (e.g., it ignored `../bar.x' in the above
example) it continues 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' magically starts 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 also works, 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       # Tru64 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.


automatically generated by info2www