This chapter is devoted to those facilities in PMake that allow you to do a great deal in a makefile with very little work, as well as do some things you could not do in Make without a great deal of work (and perhaps the use of other programs). The problem with these features, is they must be handled with care, or you will end up with a mess.
Once more, I assume a greater familiarity with UNIX® or Sprite than I did in the previous two chapters.
PMake supports the dispersal of
      files into multiple directories by allowing you to specify
      places to look for sources with .PATH
      targets in the makefile.  The directories you give as sources
      for these targets make up a “search path”.  Only
      those files used exclusively as sources are actually sought on a
      search path, the assumption being that anything listed as a
      target in the makefile can be created by the makefile and thus
      should be in the current directory.
There are two types of search paths in
      PMake: one is used for all types of
      files (including included makefiles) and is specified with a
      plain .PATH target (e.g. .PATH
      : RCS), while the other is specific to a certain
      type of file, as indicated by the file's suffix.  A specific
      search path is indicated by immediately following the
      .PATH with the suffix of the file.  For
      instance:
.PATH.h : /sprite/lib/include /sprite/att/lib/include
would tell PMake to look in the
      directories /sprite/lib/include and
      /sprite/att/lib/include for any
      files whose suffix is .h.
The current directory is always consulted first to see if a file exists. Only if it cannot be found there are the directories in the specific search path, followed by those in the general search path, consulted.
A search path is also used when expanding wildcard characters. If the pattern has a recognizable suffix on it, the path for that suffix will be used for the expansion. Otherwise the default search path is employed.
When a file is found in some directory other than the
      current one, all local variables that would have contained the
      target's name (.ALLSRC, and
      .IMPSRC) will instead contain
      the path to the file, as found by
      PMake.
      Thus if you have a file ../lib/mumble.c
      and a makefile like this:
.PATH.c : ../lib mumble : mumble.c $(CC) -o $(.TARGET) $(.ALLSRC)
the command executed to create mumble would be
      cc -o mumble ../lib/mumble.c.
      (as an aside, the command in this case is not strictly
      necessary, since it will be found using transformation rules
      if it is not given.  This is because .out
      is the null suffix by default and a transformation exists
      from .c to
      .out.  Just thought I would throw that in).
      If a file exists in two directories on the same search path,
      the file in the first directory on the path will be the one
      PMake uses.  So if you have
      a large system spread over many directories, it would
      behoove you to follow a naming convention that avoids such
      conflicts.
Something you should know about the way search paths are
      implemented is that each directory is read, and its contents
      cached, exactly once – when it is first encountered
      – so any changes to the directories while
      PMake is running will not be noted
      when searching for implicit sources, nor will they be found when
      PMake attempts to discover when the
      file was last modified, unless the file was created in the
      current directory.  While people have suggested that
      PMake should read the directories
      each time, my experience suggests that the caching seldom causes
      problems.  In addition, not caching the directories slows things
      down enormously because of PMake's attempts
      to apply transformation rules through non-existent files – the
      number of extra file-system searches is truly staggering,
      especially if many files without suffixes are used and the null
      suffix is not changed from .out.
All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/
Questions that are not answered by the
    documentation may be
    sent to <freebsd-questions@FreeBSD.org>.
    Send questions about this document to <freebsd-doc@FreeBSD.org>.