[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. (For the curious: 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.) I'm looking forward to your opinions on that topic! Regards, Christoph Schulz _______________________________________________ Bug-make mailing list Bug-make@gnu.org http://lists.gnu.org/mailman/listinfo/bug-make