manpagez: man pages & more
info autoconf
Home | html | info | man

File: autoconf.info,  Node: Make Target Lookup,  Prev: Tru64 Directory Magic,  Up: VPATH and Make

12.18.6 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:
(make)Search Algorithm.

   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 sources that are not built.

© manpagez.com 2000-2025
Individual documents may contain additional copyright information.