[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.5 Searching Directories for Prerequisites

For large systems, it is often desirable to put sources in a separate directory from the binaries. The directory search features of make facilitate this by searching several directories automatically to find a prerequisite. When you redistribute the files among directories, you do not need to change the individual rules, just the search paths.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.5.1 VPATH: Search Path for All Prerequisites

The value of the make variable VPATH specifies a list of directories that make should search. Most often, the directories are expected to contain prerequisite files that are not in the current directory; however, make uses VPATH as a search list for both prerequisites and targets of rules.

Thus, if a file that is listed as a target or prerequisite does not exist in the current directory, make searches the directories listed in VPATH for a file with that name. If a file is found in one of them, that file may become the prerequisite (see below). Rules may then specify the names of files in the prerequisite list as if they all existed in the current directory. See section Writing Recipes with Directory Search.

In the VPATH variable, directory names are separated by colons or blanks. The order in which directories are listed is the order followed by make in its search. (On MS-DOS and MS-Windows, semi-colons are used as separators of directory names in VPATH, since the colon can be used in the pathname itself, after the drive letter.)

For example,

 
VPATH = src:../headers

specifies a path containing two directories, ‘src’ and ‘../headers’, which make searches in that order.

With this value of VPATH, the following rule,

 
foo.o : foo.c

is interpreted as if it were written like this:

 
foo.o : src/foo.c

assuming the file ‘foo.c’ does not exist in the current directory but is found in the directory ‘src’.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.5.2 The vpath Directive

Similar to the VPATH variable, but more selective, is the vpath directive (note lower case), which allows you to specify a search path for a particular class of file names: those that match a particular pattern. Thus you can supply certain search directories for one class of file names and other directories (or none) for other file names.

There are three forms of the vpath directive:

vpath pattern directories

Specify the search path directories for file names that match pattern.

The search path, directories, is a list of directories to be searched, separated by colons (semi-colons on MS-DOS and MS-Windows) or blanks, just like the search path used in the VPATH variable.

vpath pattern

Clear out the search path associated with pattern.

vpath

Clear all search paths previously specified with vpath directives.

A vpath pattern is a string containing a ‘%’ character. The string must match the file name of a prerequisite that is being searched for, the ‘%’ character matching any sequence of zero or more characters (as in pattern rules; see section Defining and Redefining Pattern Rules). For example, %.h matches files that end in .h. (If there is no ‘%’, the pattern must match the prerequisite exactly, which is not useful very often.)

%’ characters in a vpath directive’s pattern can be quoted with preceding backslashes (‘\’). Backslashes that would otherwise quote ‘%’ characters can be quoted with more backslashes. Backslashes that quote ‘%’ characters or other backslashes are removed from the pattern before it is compared to file names. Backslashes that are not in danger of quoting ‘%’ characters go unmolested.

When a prerequisite fails to exist in the current directory, if the pattern in a vpath directive matches the name of the prerequisite file, then the directories in that directive are searched just like (and before) the directories in the VPATH variable.

For example,

 
vpath %.h ../headers

tells make to look for any prerequisite whose name ends in ‘.h’ in the directory ‘../headers’ if the file is not found in the current directory.

If several vpath patterns match the prerequisite file’s name, then make processes each matching vpath directive one by one, searching all the directories mentioned in each directive. make handles multiple vpath directives in the order in which they appear in the makefile; multiple directives with the same pattern are independent of each other.

Thus,

 
vpath %.c foo
vpath %   blish
vpath %.c bar

will look for a file ending in ‘.c’ in ‘foo’, then ‘blish’, then ‘bar’, while

 
vpath %.c foo:bar
vpath %   blish

will look for a file ending in ‘.c’ in ‘foo’, then ‘bar’, then ‘blish’.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.5.3 How Directory Searches are Performed

When a prerequisite is found through directory search, regardless of type (general or selective), the pathname located may not be the one that make actually provides you in the prerequisite list. Sometimes the path discovered through directory search is thrown away.

The algorithm make uses to decide whether to keep or abandon a path found via directory search is as follows:

  1. If a target file does not exist at the path specified in the makefile, directory search is performed.
  2. If the directory search is successful, that path is kept and this file is tentatively stored as the target.
  3. All prerequisites of this target are examined using this same method.
  4. After processing the prerequisites, the target may or may not need to be rebuilt:
    1. If the target does not need to be rebuilt, the path to the file found during directory search is used for any prerequisite lists which contain this target. In short, if make doesn’t need to rebuild the target then you use the path found via directory search.
    2. If the target does need to be rebuilt (is out-of-date), the pathname found during directory search is thrown away, and the target is rebuilt using the file name specified in the makefile. In short, if make must rebuild, then the target is rebuilt locally, not in the directory found via directory search.

This algorithm may seem complex, but in practice it is quite often exactly what you want.

Other versions of make use a simpler algorithm: if the file does not exist, and it is found via directory search, then that pathname is always used whether or not the target needs to be built. Thus, if the target is rebuilt it is created at the pathname discovered during directory search.

If, in fact, this is the behavior you want for some or all of your directories, you can use the GPATH variable to indicate this to make.

GPATH has the same syntax and format as VPATH (that is, a space- or colon-delimited list of pathnames). If an out-of-date target is found by directory search in a directory that also appears in GPATH, then that pathname is not thrown away. The target is rebuilt using the expanded path.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.5.4 Writing Recipes with Directory Search

When a prerequisite is found in another directory through directory search, this cannot change the recipe of the rule; they will execute as written. Therefore, you must write the recipe with care so that it will look for the prerequisite in the directory where make finds it.

This is done with the automatic variables such as ‘$^’ (see section Automatic Variables). For instance, the value of ‘$^’ is a list of all the prerequisites of the rule, including the names of the directories in which they were found, and the value of ‘$@’ is the target. Thus:

 
foo.o : foo.c
        cc -c $(CFLAGS) $^ -o $@

(The variable CFLAGS exists so you can specify flags for C compilation by implicit rules; we use it here for consistency so it will affect all C compilations uniformly; see section Variables Used by Implicit Rules.)

Often the prerequisites include header files as well, which you do not want to mention in the recipe. The automatic variable ‘$<’ is just the first prerequisite:

 
VPATH = src:../headers
foo.o : foo.c defs.h hack.h
        cc -c $(CFLAGS) $< -o $@

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.5.5 Directory Search and Implicit Rules

The search through the directories specified in VPATH or with vpath also happens during consideration of implicit rules (see section Using Implicit Rules).

For example, when a file ‘foo.o’ has no explicit rule, make considers implicit rules, such as the built-in rule to compile ‘foo.c’ if that file exists. If such a file is lacking in the current directory, the appropriate directories are searched for it. If ‘foo.c’ exists (or is mentioned in the makefile) in any of the directories, the implicit rule for C compilation is applied.

The recipes of implicit rules normally use automatic variables as a matter of necessity; consequently they will use the file names found by directory search with no extra effort.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.5.6 Directory Search for Link Libraries

Directory search applies in a special way to libraries used with the linker. This special feature comes into play when you write a prerequisite whose name is of the form ‘-lname’. (You can tell something strange is going on here because the prerequisite is normally the name of a file, and the file name of a library generally looks like ‘libname.a’, not like ‘-lname’.)

When a prerequisite’s name has the form ‘-lname’, make handles it specially by searching for the file ‘libname.so’, and, if it is not found, for the file ‘libname.a’ in the current directory, in directories specified by matching vpath search paths and the VPATH search path, and then in the directories ‘/lib’, ‘/usr/lib’, and ‘prefix/lib’ (normally ‘/usr/local/lib’, but MS-DOS/MS-Windows versions of make behave as if prefix is defined to be the root of the DJGPP installation tree).

For example, if there is a ‘/usr/lib/libcurses.a’ library on your system (and no ‘/usr/lib/libcurses.so’ file), then

 
foo : foo.c -lcurses
        cc $^ -o $@

would cause the command ‘cc foo.c /usr/lib/libcurses.a -o foo’ to be executed when ‘foo’ is older than ‘foo.c’ or than ‘/usr/lib/libcurses.a’.

Although the default set of files to be searched for is ‘libname.so’ and ‘libname.a’, this is customizable via the .LIBPATTERNS variable. Each word in the value of this variable is a pattern string. When a prerequisite like ‘-lname’ is seen, make will replace the percent in each pattern in the list with name and perform the above directory searches using each library filename.

The default value for .LIBPATTERNS is ‘lib%.so lib%.a’, which provides the default behavior described above.

You can turn off link library expansion completely by setting this variable to an empty value.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]

This document was generated by Davide Tacchella on November 3, 2010 using texi2html 1.82.