Mail Archives: djgpp/2000/04/25/19:43:38
Jason Green <news AT jgreen4 DOT fsnet DOT co DOT uk> wrote in article
<u66sfso397b17skt2lk2du0pijk1paa437 AT 4ax DOT com>...
> Jeff Williams <jeffw AT darwin DOT sfbr DOT org> 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 <news AT jgreen4 DOT fsnet DOT co DOT uk> , 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
- Raw text -