Subject: re: Longstanding bug in "make -I ..."
To: matthew green <mrg@eterna.com.au>
From: Todd Vierling <tv@wasabisystems.com>
List: tech-toolchain
Date: 10/30/2001 21:18:41
On Wed, 31 Oct 2001, matthew green wrote:

: hmmm, i don't see why -I isn't doing what is currently documented?

The bug is that -I paths are being searched for .include <foo> statements.
The include paths are supposed to be, summarizing the manpage and source
code:

.include "foo"  - search makefile's dir, then .PATH, then -I's, then -m's
.include <foo>  - search -m's

Right now, though, the latter is functioning as:

.include "foo"  - search .PATH, then -I's, then -m's

The problem can be found by looking at ParseDoInclude().  The offending
block is:

    if (fullname == (char *)NULL) {
        /*
         * System makefile or makefile wasn't found in same directory as
         * included makefile. Search for it first on the -I search path,
         * then on the .PATH search path, if not found in a -I directory.
         * XXX: Suffix specific?
         */
        fullname = Dir_FindFile (file, parseIncPath);
        if (fullname == (char *)NULL) {
            fullname = Dir_FindFile(file, dirSearchPath);
        }
    }

The problem is that this block, which searches .PATH followed by the -I's,
should (per the manpage) be inside the preceding "if (!isSystem)" block.
Moving this offending block up there fixes my perception of what
".include <foo>" should be doing.

===

To reproduce this, do the following.  (If you don't do the "touch" to create
/tmp/bsd.prog.mk, the -I case will silently succeed and a ktrace won't show
an attempt to open /tmp/bsd.prog.mk; this is because make(1) uses readdir to
find the requested file.)

$ touch /tmp/bsd.prog.mk
$ cd /usr/src/bin/ls
$ make -m /tmp
[fails, correctly]
$ make -I /tmp
[fails, but should not; the fix above makes this succeed]

-- 
-- Todd Vierling <tv@wasabisystems.com>  *  Wasabi & NetBSD:  Run with it.
-- CDs, Integration, Embedding, Support -- http://www.wasabisystems.com/