[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[bug #19108] Pattern rules with multiple target patterns do not honor th
From: |
Christoph Schulz |
Subject: |
[bug #19108] Pattern rules with multiple target patterns do not honor the dependencies of all targets correctly |
Date: |
Tue, 20 Feb 2007 13:45:25 +0000 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.0.9) Gecko/20061206 Firefox/1.5.0.9 |
URL:
<http://savannah.gnu.org/bugs/?19108>
Summary: Pattern rules with multiple target patterns do not
honor the dependencies of all targets correctly
Project: make
Submitted by: kristovschulz
Submitted on: Dienstag 20.02.2007 um 14:45
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: Any
Fixed Release: None
_______________________________________________________
Details:
[Tested on Windows with native (non-MSYS) MinGW build of GNU make 3.81, found
in http://prdownloads.sourceforge.net/mingw/mingw32-make-3.81-1.tar.gz, and on
Gentoo Linux with portage-compiled make 3.81.]
Hello,
I think I've found a bug in GNU make. When a pattern rule with multiple
targets exists, and make determines that it needs that rule to built one
matching target, it uses this rule even if the other targets implicitly built
by this rule don't have their dependencies built yet.
As this is quite complicated to explain, I created a little example:
final: x
@echo "making final"
touch $@
x: x.tgt1 x.tgt2
@echo "making x"
touch $@
x.tgt2: dep
dep:
@echo "making dep"
sleep 5
touch $@
%.tgt1 %.tgt2: %.src
cp $< $(patsubst %.src,%.tgt1,$<)
cp $< $(patsubst %.src,%.tgt2,$<)
clean:
-rm -f final x dep x.tgt1 x.tgt2
(Note: To run this makefile successfully you have to create a file named
"x.src" at first, to cause the pattern rule to be applied.)
This Makefile has some unwanted properties. At first, building "final" does
not result in building "dep", although the dependency chain
"final-->x-->x.tgt2-->dep" exists. Make traverses the dependency tree from
left to right. It finds that x depends on x.tgt1 and that x.tgt1 can only be
built by the pattern rule. However, at build time, this rule also builds
x.tgt2. So x.tgt2's non-existent dependencies are ignored as it already
exists.
If you reverse the order of x's prerequisites, you encounter an even stranger
effect. Running make (after a proper "make clean", of course) seems to work.
However, if you use "make -j" you will see that the "dep" target will be
finished long after the "final" target. This is due to the fact that the
dependency x.tgt2-->dep is not properly tracked across the pattern rule.
Additionally, in both cases (Makefile with original order of x's
prerequisites and Makefile with reversed order and using "make -j"), one has
to run make a second time until everything is built.
I don't know whether this behaviour is by design. But I think that pattern
rules with multiple (pattern) targets must only be run if make determines
that all dependencies for *all* the targets the pattern rule would create are
already in place. Currently, make seems to perform the dependency check only
for that target that triggers the rule. This is not enough IMHO. In the
example above, make should be running the pattern rule only after the
dependencies of both x.tgt1 *and* x.tgt2 have been built successfully. This
would also help to get rid of the "reordering changes semantics" effect
described above.
The background: The real case was a system where the compiler (MSVC++) also
creates a precompiled header file for a special dummy source file. To account
for the fact that compiling all "normal" source files needs this precompiled
headers I built a pattern rule like the following one (the pattern rule was
necessary in order to tell "make" that the command build both files
simultaneously):
OBJS := library-pchgen.obj <further library objects>
$(OBJS): library-pchgen.obj
%.pch %-pchgen.obj: %-pchgen.src
<compiler call to compile the pchgen and pch files>
$(TARGET): $(OBJS) library.pch
<linker call>
Because there were dependencies on other libraries, all the object files had
additional prerequisites:
$(OBJS): other_lib/other_lib.dll another_lib/another_lib.dll
However, this did not work when using "make -j", as library-pchgen.obj was
built before the other libraries were built. Stating explicitly that the pch
file (library.pch) also depends on the other libraries via:
$(OBJS) library.pch: other_lib/other_lib.dll another_lib/another_lib.dll
solved the problem, but - as I already said - I don't think this should be
necessary.)
Regards,
Christoph Schulz
_______________________________________________________
File Attachments:
-------------------------------------------------------
Date: Dienstag 20.02.2007 um 14:45 Name: Makefile Size: 290B By:
kristovschulz
Testcase
<http://savannah.gnu.org/bugs/download.php?file_id=12019>
_______________________________________________________
Reply to this item at:
<http://savannah.gnu.org/bugs/?19108>
_______________________________________________
Nachricht geschickt von/durch Savannah
http://savannah.gnu.org/
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [bug #19108] Pattern rules with multiple target patterns do not honor the dependencies of all targets correctly,
Christoph Schulz <=