From: "Joel Hunsberger" Subject: Re: OT: `make clean' wants to rebuild `.d' files Newsgroups: comp.os.msdos.djgpp References: <200004191406 DOT JAA04929 AT darwin DOT sfbr DOT org> Message-ID: <01bfaef8$cc68b5c0$da06017e@gr-356146> X-Newsreader: Microsoft Internet News 4.70.1155 NNTP-Posting-Host: help-desk-005.si.com Date: 25 Apr 2000 16:57:48 -0500 X-Trace: 25 Apr 2000 16:57:48 -0500, help-desk-005.si.com Organization: Smiths Industries Lines: 109 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com Jason Green wrote in article ... > Jeff Williams wrote: [...snip...] > > No rule to build the .d files is required. The .d files are not > required initially because the first `make' will compile every .c file > anyway. From then on the .d files will be included. If a .c file > changes it will be recompiled and the .d file will be updated. > > I have been using the above solution to manage header dependencies for > a while now and have noticed no ill effects. If anyone can see a > downside to this method then of course please let me know! I LIKE that!!! In the past I have tried a few approaches... (Note that there is a method described in the GNU Make document, 4.12, where you have a .d file for every .c file. Using gcc -MM, these are then manipulated by sed so that one ends up with each .d file being named along with the .o file as a target made from any .c file. (Then they are updated automatically by the messy "%.d: %.c" rule shown.) I didn't like that approach because of the messy requirement for sed (not all MS-DOS users would have sed,) and the number of .d files required. I didn't really come up with anything better than Jason Green , I just created a mess more to my liking :-)) My makefile includes the following lines at various places... (See the explanation after the makefile code...) ------------------------in the makefile --------------- # .d file name is auto generated [... near the top ...] HEADER_DEPENDENCY_FILE=$(TARGET:.exe=.d) #[.... later ...] -include $(HEADER_DEPENDENCY_FILE) ## The one header dependency file is updated if there are any changes in ## the .h files in the local directory. $(HEADER_DEPENDENCY_FILE): $(CFILELIST) $(CC) -MM $(CCFLAGS) $(CFILELIST) > $(HEADER_DEPENDENCY_FILE) $(TARGET): $(HEADER_DEPENDENCY_FILE) $(ALLOBJECTS) $(LD) $(LDFLAGS) -o $@ $(LDLIBS) $(ALLOBJECTS) ---------------------------------------- Here are the features I like about this... * There is only one .d file, and it's name is automatically generated from the target name. For example, a target name TEST.EXE produces HEADER_DEPENDENCY_FILE=TEST.d * A change to any C files always causes the one .d file to be updated, and so do changes to any .h files, because the dependency of .o files on .h files is asserted by the .d file when it is included. * If I understand 'make' behavior, if the .d file does not exist, it is first generated (behavior of 'include') and then make generates it (via its rule) and reads it (again) before examining any other rules. So... any changes in .h files cause recompiles to dependent .c files. * Because the header dependency file depends on the .c files, it is regenerated if there are any changes to files in the CFILELIST (stated explicitely at the begining, or, it can also be autogenerated by CFILELIST=$(wildcard *.c) * Since the TARGET depends on the header dependency file as well as ALLOBJECTS, then the HEADER_DEPENDENCY_FILE is regenerated if it is out of date when the target the TARGET is examined (even though it is not used directly in the LD command. * I had to solve the problem that various FLEX (.l) files included .h files indirectly, and this approach handles that also. (If a flex file is updated, the header dependency file is also regenerated, but that is due to the resultant .c file being regenerated anyway. :-0 no big deal!) Caveats: * I have not exhaustively tested this, nor lived with it long enough to know if it never breaks, or might break under some exotic situation. It just appears to work okay now... (crossed fingers). * C code with certain stupid errors (missing comment endings, etc.) can mess up the header dependency process in the first step, if it errors badly when fed to 'gcc -MM' The way to check out whether a makefile is correctly intercepting changes to header files is (of course) to 'make' the target, then make a meaningless change (or touch) one of the header files. Then see if the related c files are recompiled at the next make. Next, make a meaningless change to one of the c files, or a flex file, and see if the .d file is regenerated as needed. Makefile programming can be as much fun as C programming (sad to say :-)) J. Hunsberger