Hi all, On 11/15/09, Paul Smith <psm...@gnu.org> wrote: > I'll say it again, slightly differently: this problem only happens if > you (a) add a new header, that (b) has the same name as an existing > header, and (c) appears earlier in the include list than the existing > header, and (d) does not require any other changes to headers or source > code that include the existing header. In that situation, then make > will fail to rebuild the object file when it should. If any one of > those items is not satisfied, then make will behave correctly.
I'll also say this slightly differently :)... which of these doesn't belong? a) you regularly add new header files b) you may name header files with the same name as existing headers c) you may put a header file with the same name earlier in the include path d) you should know what existing source/header files need to be modified because of the new header file And the answer is... d! How the heck should you or I know what files need to be modified just because a new header was added? That's the build system's job. I may be a newbie to some large software project, and not know every file inside and out. Keep in mind you might not even be the one who actually added the header - it could be pulled in from a version control update. Looking at your example in more detail... > Let's look at it. Suppose you have a file foo.c that #includes > "config.h". Your compiler lists "-I/a -I/b -I/c" on the compile line. > The header "config.h" lives in "/b". There is no "config.h" in "/a" or > "/c". > > Now you run make and it generates a dep file something like this: > > foo.o: foo.c /b/config.h > > Fine. Now someone adds a new header file. Going by my items above (a) > is satisfied (a new header exists). For (b), if the new header is named > "/a/cfg.h" then obviously there's no problem: make won't, and shouldn't, > rebuild foo.o. For (c), if the new header is "/c/config.h", then > there's no problem either: make won't rebuild foo.o, but it SHOULDN'T > rebuild foo.o because foo.o doesn't depend on /c/config.h--by the > include paths /b/config.h will be found first and /c/config.h is not > relevant. For (d), if "/a/config.h" is added and that means that some > change is needed in either foo.c or /b/config.h, then foo.o will be > recompiled ANYWAY since one of its prerequisites was changed, then the > next time you run make it will have the right dependencies (since the > compiler will generate the new list showing "/a/config.h" as the > prereq). I agree with (a), (b), and (c). That all sounds perfectly reasonable. But for (d), I don't buy the argument that "if a/config.h is added and that means that some change is needed in either foo.c or /b/config.h". While it may be true that some change is needed, how do I know that? It's easy to see in this case because there's 3 files. If there's hundreds or thousands, how would I know that some random C file somewhere else entirely needs to be edited? Ideally the build system would rebuild it, and then I'd get an error because I'm now using a different header. Worst case is the build *looks* like it succeeds and you end up checking in your change, and the next poor shlub who does a clean checkout has to find the mess. Mark, I applaud your goal of trying to get make to behave properly in all cases. However, once you have the -I paths knocked out, does your approach also work for -L and libraries? What about for programs that aren't gcc? What happens when you have a Makefile that builds libfoo.a, but you realize 'foo' is already trademarked so you change it to 'libbar.a'? Will all those other Makefiles that still reference libfoo.a report an error? Or will it silently succeed because libfoo.a still exists in the filesystem, and once again leave the mess for the next clean build? Maybe you already have answers to these scenarios, in which case I can come up with more :) -Mike _______________________________________________ Help-make mailing list Help-make@gnu.org http://lists.gnu.org/mailman/listinfo/help-make