On Mon, Apr 29, 2002 at 09:32:15AM +1000, Ken Foskey wrote:

> gcc has an option -M or -MM (RTFM quoting from memory).   SO you can
> create the dependencies and include them (I dont do this so read the
> make manual (it prints to over 300 pages) it has a sample on ho to do
> this and include it into the source.
> 
> To do this you might do something like:
> 
> yy.inc:  yy.c
>       gcc -MM > yy.inc
> 
> -include yy.inc
> 
> THere is no need to make depend because Make figure this out for
> itself.  Pretty amazing really.

Here's how we do it.  It's based on, but not quite the same as, the
example given in the make info pages.  A few variables need to be
defined:

    COMMON_INCLUDE_DIRS     The list of directories to be searched for
                            header files, separated by spaces.
    CPPFLAGS                Compiler flags to be passed during 
                            pre-processing (may be the same as $(CFLAGS)).
    SOURCES                 The list of source files, separated by spaces.


Now here's the relevant bits of one makefile.  It requires GNU make:

    SHELL := /bin/sh

    # VPATH is used by make to search for header files when examining
    # dependencies.  We need to use this because gcc doesn't include the
    # directory names in dependencies generated with `-MM', and we don't
    # have all our header files in one directory.
    override VPATH := $(COMMON_INCLUDE_DIRS)

    # and convert this list of directories into compiler directives
    override includes := $(patsubst %,-I%,$(VPATH))

    # create the list of object files from the list of source files
    override objs := $(SOURCES:.c=.o)

    ##
    ##-----------------------------------------------------------------------------
    ##

    #
    # Pattern rules to automatically regenerate dependencies when a source file
    # changes - no need to maintain lists of dependencies manually.
    #

    ##
    ##-----------------------------------------------------------------------------
    ##

    #
    # Include the dependency files generated by these pattern rules - this
    # gives make the complete dependency list for each source file.  If a file
    # is changed, the above pattern rules will force any .d files which depend
    # upon it to be rebuilt.  Make will first include all the dependency files,
    # then remake any which require it, then re-read the new dependency file.
    #
    # The reading of dependency lists *before* building anything requires special
    # care to be taken when a source or header file is deleted.  First, remove
    # all references to that file in all source files, and in this makefile.  Then,
    # make the target binary.  Finally, delete the obsolete file.  If you don't
    # follow this procedure, you may get an error from make because it has found a
    # dependency on the obsolete file, but it doesn't exist and make has no rule
    # to make it.  If that happens, delete the .d file which refers to the obsolete
    # file, and restart make.
    #
    include $(objs:.o=.d)

    #
    # ~ is used as pattern separator in sed expressions because some files are
    # located in subdirectories, so '/' may appear in the pattern itself
    # $(notdir) and $(dir) are used to makes sure that the appropriate directory
    # names appear in the targets of the rules - gcc doesn't include the
    # directory name in the output of `gcc -MM'.
    #

    #
    # .d from .c source
    #
    %.d: %.c
        $(SHELL) -ec 'gcc -MM $(CPPFLAGS) $< \
                | sed -e '\''s~\($(notdir $*)\)\.o[ :]*~$(dir $*)\1.o $@: ~g'\'' -e 
'\''s~/\./~/~g'\'' > $@; \
                                [ -s $@ ] || rm -f $@'

    #^^^^^^^^^^^ use tabs here, not spaces



Cheers,

John
-- 
whois [EMAIL PROTECTED]
GPG key id: 0xD59C360F
http://kirriwa.net/john/
-- 
SLUG - Sydney Linux User's Group - http://slug.org.au/
More Info: http://lists.slug.org.au/listinfo/slug

Reply via email to