[bug #20394] vpath directive drops entries

2007-07-07 Thread anonymous

URL:
  

 Summary: vpath directive drops entries
 Project: make
Submitted by: None
Submitted on: Samstag 07.07.2007 um 08:09 UTC
Severity: 3 - Normal
  Item Group: Bug
  Status: None
 Privacy: Public
 Assigned to: None
 Open/Closed: Open
 Discussion Lock: Any
   Component Version: 3.81
Operating System: POSIX-Based
   Fixed Release: None

___

Details:

With GNU make v3.81 (as well as earlier versions, eg. 3.81beta4 and v3.80),
the vpath directive for libraries seems to "forget" entries under certain
circumstances.

Example:

A project with the following directory layout:

Makefile
foo1/
 foo1/Makefile
foo2/
 foo2/Makefile
foo3/
 foo3/Makefile
foo4/
 foo4/Makefile
foo5/
 foo5/Makefile
foo6/
 foo6/Makefile
foo7/
 foo7/Makefile
foo8/
 foo8/Makefile
include/
lib/

and this top-level Makefile:


#
SUBDIRS  := foo1 foo2 foo3 foo4 foo5 foo6 foo7 foo8
TARGET   := app
LIBDIRS  := $(patsubst %,-L%,$(SUBDIRS))
LIBS := $(patsubst %,-l%,$(SUBDIRS))


vpath %.h include
vpath %.a lib $(SUBDIRS)


all: subdirs $(TARGET)

subdirs:
@(for module in $(SUBDIRS); \
do \
$(MAKE) -w -C $$module -f Makefile $(MAKECMDGOALS); \
done)

$(TARGET): $(LIBS)
$(CC) -o $@ $(LIBDIRS) $(LIBS)
#


and this as each of the subdir-Makefiles:


LIBNAME := $(shell basename `pwd`)
LIBFILENAME := lib$(LIBNAME).a
LIBTARGET := $(LIBFILENAME)

all: $(LIBTARGET)

$(LIBTARGET):
touch $@




Output:


$ make
make[1]: Entering directory `/home/luna/tmp/testmake3/foo1'
touch libfoo1.a
make[1]: Leaving directory `/home/luna/tmp/testmake3/foo1'
make[1]: Entering directory `/home/luna/tmp/testmake3/foo2'
touch libfoo2.a
make[1]: Leaving directory `/home/luna/tmp/testmake3/foo2'
make[1]: Entering directory `/home/luna/tmp/testmake3/foo3'
touch libfoo3.a
make[1]: Leaving directory `/home/luna/tmp/testmake3/foo3'
make[1]: Entering directory `/home/luna/tmp/testmake3/foo4'
touch libfoo4.a
make[1]: Leaving directory `/home/luna/tmp/testmake3/foo4'
make[1]: Entering directory `/home/luna/tmp/testmake3/foo5'
touch libfoo5.a
make[1]: Leaving directory `/home/luna/tmp/testmake3/foo5'
make[1]: Entering directory `/home/luna/tmp/testmake3/foo6'
touch libfoo6.a
make[1]: Leaving directory `/home/luna/tmp/testmake3/foo6'
make[1]: Entering directory `/home/luna/tmp/testmake3/foo7'
touch libfoo7.a
make[1]: Leaving directory `/home/luna/tmp/testmake3/foo7'
make[1]: Entering directory `/home/luna/tmp/testmake3/foo8'
touch libfoo8.a
make[1]: Leaving directory `/home/luna/tmp/testmake3/foo8'
make: *** No rule to make target `-lfoo8', needed by `app'.  Stop.



Interestingly, it works again if any one of these actions is taken:
* the lib/ directory is removed
* the include/ directory is removed
* one of the entries of SUBDIRS is removed
* the line with *vpath %.h include* is removed
* the line with *vpath %.h include* is put _after_ the *vpath %.a ...*
* in the line with *vpath %.a ...*, the entry *lib* is moved to the end of
the list




___

File Attachments:


---
Date: Samstag 07.07.2007 um 08:09 UTC  Name: make_vpath_error.tar.gz  Size:
845B   By: None
Example directory structure, as described above


___

Reply to this item at:

  

___
  Nachricht geschickt von/durch Savannah
  http://savannah.gnu.org/



___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


[bug #20394] vpath directive drops entries

2007-07-07 Thread anonymous

Follow-up Comment #1, bug #20394 (project make):

gmake caches directories from the 10th on. So it will not see a file in those
directories if it didn't exist initially (except under windows NT, where it
checks the directory timestamps). 

Just looks like foo1..8 plus lib, include and . were one more than 10.


___

Reply to this item at:

  

___
  Message sent via/by Savannah
  http://savannah.gnu.org/



___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


[bug #20394] vpath directive drops entries

2007-07-07 Thread Paul D. Smith

Follow-up Comment #2, bug #20394 (project make):

It's not exactly correct to say that GNU make caches directories from the
10th on, but you're on exactly the right track; thanks for the note.

What make actually does is cache EVERY directory... BUT it caches them
"lazily", AND it only allows 10 directories to be open at any one time. 
Basically, when make wants to check a file in a directory it opens the
directory for reading and looks for that file.  As it reads the directory it
caches the contents.  Once the file is found, it leaves the directory open
but stops reading.  If make looks for another file in that directory and it's
not in the cache, make continues reading (and caching) where it left off.  If
it gets to the end of the directory it closes the directory.

In order to avoid too many directories being open by make at one time, if
make gets to a point where more than 10 directories are open, it will
completely read and cache the current (latest) directory, then close it.

The issue of make's caching is well-known (see bug #443 for example).  In
your case it takes an odd twist but this is definitely the issue.  A
completely correctly-written makefile shouldn't run across cache problems,
but I recognize there are situations where it's not possible to write that
makefile.  However, in your case I think you can do what you want.  Change
your makefile like this:


LIBS := $(patsubst %,-l%,$(SUBDIRS))
LIBTARGETS := $(foreach L,$(LIBS),$(L)/lib$(L).a)

all: $(TARGET)

$(TARGET): $(LIBTARGETS)
$(CC) -o $@ $(LIBDIRS) $(LIBS)

$(LIBTARGETS): FORCE
$(MAKE) -w -C $(@D) -f Makefile $(MAKECMDGOALS)
FORCE:


This has some other advantages over the method you were using (for one thing,
your example does not work properly if any of the sub-makes fail).

___

Reply to this item at:

  

___
  Message sent via/by Savannah
  http://savannah.gnu.org/



___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make