This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Automatic dependency complexity
- To: Martin von Loewis <martin at mira dot isdn dot cs dot tu-berlin dot de>, tromey at cygnus dot com
- Subject: Re: Automatic dependency complexity
- From: Jamie Lokier <egcs at tantalophile dot demon dot co dot uk>
- Date: Sun, 6 Dec 1998 15:32:21 +0000
- Cc: egcs at cygnus dot com
- References: <13928.7003.472716.144280.cygnus.egcs@tiamat.golden-gryphon.com> <871zme769q.fsf@cygnus.com> <199812060913.KAA00192@mira.isdn.cs.tu-berlin.de>
On Sun, Dec 06, 1998 at 10:13:56AM +0100, Martin von Loewis wrote:
> > I know that the GNU make documentation suggests having a separate rule
> > to create the `.d' files. However, I think this isn't the best way to
> > go. Instead, I believe that dependencies should be created as a side
> > effect of compilation.
>
> YES!!!!
No problem. Just make the .d files when you compile; you don't need a
makefile rule for them. You do need some rules to cope the other
consequences of the .d files.
> To modify the name of the target, the undocumented SUNPRO_DEPENDENCIES
> was helpful - I wish there was a command line option for that
> functionality, though.
I've been using it for years, to get the right dependencies compiling a
single .cc file to different .o files. Otherwise things go horribly
unrecompiled.
To the maintainers: don't you dare think of removing SUNPRO_DEPENDENCIES
until there's a command line equivalent!
I just found a comment snippet in one of my more complex makefiles.
Maybe this will give someone an idea of what I had to do. (This is a
few snippets cut from a very large makefile; it doesn't do anything
useful by itself).
Automatic dependencies _do_ work very well indeed, when you've got the
makefiles and compiler options right. But it took me more than a year
of finding and eliminating subtle bugs!
Enjoy,
-- Jamie
#{{{ About automatic dependencies and `SUNPRO_DEPENDENCIES'
# We use `SUNPRO_DEPENDENCIES' to output dependency files for each
# object file generated. (Actually, the dependencies are with object
# files as targets, but they are generated in preprocessing rules).
#
# The GCC manual refers to `DEPENDENCIES_OUTPUT' as the official
# variable for this (or use can use `-MD', etc.), but we need to store
# the "system" header dependencies (using `#include <...>') as well as
# the "user" header dependencies (using `#include "..."'). This is
# because we use `#include <...>' to refer to "public" header files
# distributed throughout the source tree. GCC interprets
# `SUNPRO_DEPENDENCIES' to give the behaviour we want, but this isn't
# documented in the GCC manual.
#
# None of the `-MM', `-MMD', `-MD' or `-MMD' options gives us enough
# flexibility with regard to the dependencies file name or the target
# object file name. GCC's defaults are fine for the implicit rules in
# this file, but sometimes we use variables like `COMPILE.cc' in rules
# with unusual target names. For example, if we are compiling a single
# source file more than once with different macros defined. In such
# cases, we want both the dependencies file and the target object file
# named in it to be based on the target of the rule, and unfortunately,
# on the `SUNPRO_DEPENDENCIES' variable gives us the flexibility to
# specify both names and get the right output.
#
# We used to use `-MD', and in those rare cases where the dependency
# file has the wrong name (and the target named in it), we would rename
# the file after compilation. This didn't work with a parallel make,
# because many compiles could be in progress from the same source file.
#
# Using the environment variable instead of an option causes GCC to
# append to the dependencies file. For our purposes, we want the file
# rewritten for each compile, so we must delete it before each compile.
# Actually, we just empty it using a shell operator to avoid an
# invocation of `rm'.
#}}}
define COMPILE.c
@echo 'Compiling $(STRIP_VPATH_<) -> $@'
$Q> '$(basename $@).d'; \
SUNPRO_DEPENDENCIES='$(basename $@).d $(basename $@).o' \
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
endef
%.o: %.c
$(COMPILE.c) $< -o $@
#{{{ Pretend that header files listed in old `.d' files still exist
$(foreach DIR,$(source_dir) $(INCLUDE_DIRS),$(DIR)/%) \
/usr/include/% /usr/i486-linuxaout/include/% /usr/i486-linux/include/% \
/usr/local/include/% /usr/local/gnu/include/% \
/usr/lib/gcc-lib/% /usr/local/lib/gcc-lib/% /usr/local/gnu/lib/gcc-lib/% \
/usr/lib/g++-include/% /usr/include/g++/%:
@echo 'Let'\''s pretend the file `$@'\'' does exist...'
#}}}
#{{{ Include `*.d' dependency files
__DEPENDENCY_FILES := $(wildcard *.d)
ifneq "" "$(__DEPENDENCY_FILES)"
-include $(__DEPENDENCY_FILES)
endif
#}}}