Halo wine-devel people,
Although I understand you probably "enjoy" one of the best or worst f^H debates of all times (who said wine devel is immune to flamewars after all? :-) I would like to pose a somewhat off topic question but still quite technical.
As part of a private investigation I noticed that both WINE and LINUX kernel build systems have a mkdep utility which generates in clude file dependencies. What I am looking for is to understand the reasons behind this decision for the two very popular projects instead the recipe suggested by GNU make documentation.
Here is what GNU MAKE suggests as the preferred way to handle dependencies.
#---------Makefile Start TARGET=a SOURCES=a.c b.c CFLAGS=-ansi -pedantic -Wall
OBJECTS=$(SOURCES:.c=.o) DEPS=$(SOURCES:.c=.d)
%.d: %.c set -e; $(CC) -MM $(CPPFLAGS) $< \ | sed 's/($*).o[ :]*/\1.o $@ : /g'
$@; \
[ -s $@ ] || rm -f $@;
$(TARGET): $(OBJECTS)
include $(DEPS) #---------Makefile End
This method has the several disadvantages:
i) It is GNU specific (unportable): a) Needs accumulative dependencies. That means a.o: a.c a.o: a.h does not override the first entry but it means a.o: a.c a.h
b) It requires the include statement
c) It requires that MAKE will reload the Makefile as soon as it realizes that the Makefile or any of included file has been changed.
d) It uses compiler specific features.
ii) Speed. a) Files has to be parsed twice during compilation.
b) Slight changes to config.h may result in unnecessary, uncontrolled compilations.
---------------
I would like to know if there are any other reasons that is not listed here and or if any of the reasons listed above is more significant than the others.
Thank you for your time.
.Bill
__________________________________________________ Do You Yahoo!? Send FREE Valentine eCards with Yahoo! Greetings! http://greetings.yahoo.com
On 2002.02.13 04:47 Vassilis Virvilis wrote:
Halo wine-devel people,
Although I understand you probably "enjoy" one of the best or worst f^H debates of all times (who said wine devel is immune to flamewars after all? :-) I would like to pose a somewhat off topic question but still quite technical.
Actually, this is probably more ontopic than any of the license flames have been. Need to remember to put on the asbestos underwear before reading this list anymore.
As part of a private investigation I noticed that both WINE and LINUX kernel build systems have a mkdep utility which generates in clude file dependencies. What I am looking for is to understand the reasons behind this decision for the two very popular projects instead the recipe suggested by GNU make documentation.
THANK YOU!
Off the subject of Wine, but relative to this particular discussion, I have been working on a project at work and I briefly investigated Wine's makedep system, and then noted that X11 has its own makedepend command (which is actually installed onto the system). What I have done right now is to use the X11 one to handle my dependencies. I really don't like this as it chokes on some of the #if defined(SOMETHING) || !defined(SOMETHING_ELSE) type constructs in wxWindows code. It also seems to like to do deps for all the system headers as well (well, you can specify ONE system directory it won't do deps against, but that's lame).
Trying to rip Wine's makedepend out was even worse. I tried it first since when I thought make depend the first thing that came to mind was all the times I've typed that compiling wine every few days at least. At least the X11 makedepend had a good manpage.
Here is what GNU MAKE suggests as the preferred way to handle dependencies.
#---------Makefile Start TARGET=a SOURCES=a.c b.c CFLAGS=-ansi -pedantic -Wall
OBJECTS=$(SOURCES:.c=.o) DEPS=$(SOURCES:.c=.d)
%.d: %.c set -e; $(CC) -MM $(CPPFLAGS) $< \ | sed 's/($*).o[ :]*/\1.o $@ : /g'
$@; \
[ -s $@ ] || rm -f $@;
$(TARGET): $(OBJECTS)
include $(DEPS) #---------Makefile End
This method has the several disadvantages:
Before we get to the disadvantages I'd really like to point out that the .d targets would seem like a more reasonable way of working with make. Considering that you can be sure you won't need to update the dependency info (the .d file) unless the source has changed this will actually save you time when rebuilding the project over and over again.
i) It is GNU specific (unportable): a) Needs accumulative dependencies. That means a.o: a.c a.o: a.h does not override the first entry but it means a.o: a.c a.h
Assuming you depend on the standard target to make a .o from a .c (or have defined your own) then there should be no need to have the a.o: a.c line in the makefile itself and thus the "a.o: a.c a.h" style line can be put in the dependency info (like wine's make depend)
b) It requires the include statement c) It requires that MAKE will reload the
Makefile as soon as it realizes that the Makefile or any of included file has been changed.
These to can be gotten around by going back to an actual make depend target that must be run before doing a make. For a non-GNU make you would just make all of the .d files and then append all of their contents to the makefile as per a usual make depend.
d) It uses compiler specific features.
Man, that's a shame that more compilers don't support that. Actually, it seems to just invoke the preprocessor to do this, so one could theoretically just use the GNU cpp to generate the dependency info without using the rest of gcc.
ii) Speed. a) Files has to be parsed twice during compilation.
Of course. With any dependency system you are going to have to parse all of the source files to generate the dependencies and then actually compile them. What is the problem? By compilation I assume you mean the build of the whole project, not the compilation of one individual source file.
b) Slight changes to config.h may result in
unnecessary, uncontrolled compilations.
Umm yeah, ./configure; make depend; make; touch config.h; make and watch it all recompile.
I would like to know if there are any other reasons that is not listed here and or if any of the reasons listed above is more significant than the others.
I think it's more of an issue that a dependency system is pretty trivial to implement with the exception that doing it means time was spent that could otherwise have been spent programming.
I don't think the fact that GNU has a standard for makefile dependencies is going to convince Alexandre to change the tree. Nor do I think Linus will be convinced to change the Linux tree. However for my own projects I'll keep this in mind when I decide to do a bit of house-keeping.
I am by no means a make-guru... however I do believe that Alexandre is.
-Dave
David Elliott dfe@tgwbd.org writes:
On 2002.02.13 04:47 Vassilis Virvilis wrote:
ii) Speed. a) Files has to be parsed twice during compilation.
Of course. With any dependency system you are going to have to parse all of the source files to generate the dependencies and then actually compile them. What is the problem? By compilation I assume you mean the build of the whole project, not the compilation of one individual source file.
Actually an advantage of a makedep tool is that you generate all the dependencies for a directory in one step. This means that you only need to parse each include file once, even if it is included from multiple .c files. This can easily be an order of magnitude faster than preprocessing each file individually (though with recent gccs you can use gcc -MD to generate dependencies while compiling the file, which is even more efficient; sadly it's not portable).
On 2002.02.13 23:41 Alexandre Julliard wrote: [SNIP]
Actually an advantage of a makedep tool is that you generate all the dependencies for a directory in one step. This means that you only need to parse each include file once, even if it is included from multiple .c files. This can easily be an order of magnitude faster than preprocessing each file individually (though with recent gccs you can use gcc -MD to generate dependencies while compiling the file, which is even more efficient; sadly it's not portable).
Ah yes.. good point.
I'll probably wind up using Wine's makedep for my project then. If I recall though, it had issues with includes that were only included if something was specifically defined. Maybe I should take another look at it. X11's makedepend still chokes on #if's with logical operators and also likes to generate dependencies for the system headers too which just fills up the makefile with tons of dependency info.
Maybe I can find some time to look through and extend Wine's makedep to be a bit more usefull for projects other than Wine. Or maybe I should read a bit more documentation on it first. :-)
-Dave
David Elliott dfe@tgwbd.org writes:
I'll probably wind up using Wine's makedep for my project then. If I recall though, it had issues with includes that were only included if something was specifically defined. Maybe I should take another look at it.
Wine's makedep doesn't attempt to handle #if or #ifdef at all. This sometimes results in more dependencies than strictly necessary, but at least for Wine this isn't a problem. And it makes things much simpler.
Maybe I can find some time to look through and extend Wine's makedep to be a bit more usefull for projects other than Wine. Or maybe I should read a bit more documentation on it first. :-)
If you want to read documentation on Wine's makedep, you'll have to write some first ;-)