help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: how to include dependencies only if includes changed


From: Bart Robinson
Subject: Re: how to include dependencies only if includes changed
Date: Tue, 10 Nov 2009 11:37:18 -0800

On Mon, Nov 9, 2009 at 10:02 AM, Pete Johnson <address@hidden> wrote:
> Mark,
>
> See http://make.paulandlesley.org/autodep.html for a good way to handle auto
> dependencies in make. Using the methods described in the article, you will
> only build dependencies when they are needed.
>
> -Pete

To save time for anyone looking to do this (the auto-dependencies, not
Mark's auto-include-auto-dependencies), I just wanted to comment that
the mechanisms in that article are somewhat dated and it is a little
easier to do this now with the gcc -MP flag, which
does what I think is the equivalent of the hairy sed transforms.

If using fairly recent gcc (i can vouch for 3.4.6+), skip to the -MD
part (I suggest -MMD, which omits stdio.h and the like) and also use
-MP:

srcs := src/foo.c stuff/bar.c ...
%.o : %.c
        $(CC) -o $@ -c -MMD -MP -MF $*.d $(CFLAGS) $<
depfiles := $(patsubst %.c,%.d,$(sort $(srcs)))
ifneq ($(depfiles),)
$(depfiles): ;
-include $(depfiles)
endif

The -MF <file> part is only for older distcc (they symptom indicating
this is needed is if all your .d files end up at top-level, e.g.
./foo.d rather than src/foo.d, and the include doesn't find them).
Newer distcc (somewhere in 3.x) has reportedly fixed this.

The sort is only to remove duplicates, which I remember having errors
for years ago.  Might not be necessary anymore (so my example may also
be somewhat dated :-).

The $(depfiles): ; is to speed up make by avoiding the implicit rule
search for these.

This puts them alongside the .o files, which may be annoying if
building within the srcdir.  If that is bothersome then (for several
other reasons as well) I would suggest judicious use of vpath and a
$(srcdir) notion to enable building in a separate dir.

-- bart

> On 11/8/09, Mark Galeck (CW) <address@hidden> wrote:
>>
>> Hello,
>>
>> Suppose for each .c file such as foobar.c I have generated a makefile
>> foobar.d file, that lists dependencies of foobar.o on files included in
>> foobar.c.
>>
>> There are many .d files and each of them has many dependencies, so if I
>> just blindly do
>>
>> -include $(OBJS:.o=.d)
>>
>> then it takes a lot of time for make to just get started.  What I want, is
>> to only include all of those *.d when needed, that is, when some include
>> file has been modified.  I want this whenever a user calls
>>
>> >make target
>>
>> for any target.  How to do this?
>> --------------------------
>>
>> What follows below is my solution to this problem, but it only works for
>> >make
>> (default target)
>> and can be extended to any fixed number of other targets, but not to
>> general target such as
>> >make foobar.o
>> where foobar.c is any .c file
>>
>>
>> The solution,
>> simplified somewhat to show you just the gist of it,
>> is to generate another makefile called "included" like this:
>>
>> chooseIncl:
>>         ($(MAKE) -q lastIncl && ( $(MAKE) noIncl & touch lastIncl)) ||
>> ($(MAKE) incl & touch lastIncl)
>>
>> lastIncl:\
>> foobar.h\
>> foobar1.h\
>> (...)
>>
>>
>> (lastIncl depends on all the included files).
>> If you don't know DOS, the way the rule for chooseIncl works, is that if
>> any included files have changed, then
>> $(MAKE) incl
>> is called, otherwise
>> $(MAKE) noIncl
>> is called
>>
>>
>> then include "included" at the top of the main makefile,
>> and put in the main makefile (where "all" is the original default target):
>>
>> incl noIncl: all
>>
>> ifeq (incl, $(MAKECMDGOALS))
>> -include $(ALL_OBJS:.o=.d)
>> endif
>>
>>
>>
>>
>>
>> _______________________________________________
>> Help-make mailing list
>> address@hidden
>> http://lists.gnu.org/mailman/listinfo/help-make
>
>
> _______________________________________________
> Help-make mailing list
> address@hidden
> http://lists.gnu.org/mailman/listinfo/help-make
>
>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]