This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Automatic dependency complexity


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

#}}}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]