help-make
[Top][All Lists]
Advanced

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

Re: How to rebuild on recipe change?


From: Philip Guenther
Subject: Re: How to rebuild on recipe change?
Date: Tue, 16 Feb 2010 03:19:31 -0800

On Tue, Feb 16, 2010 at 1:37 AM, Kirill Smelkov <address@hidden> wrote:
...
> Yes, this sort of works. But how about e.g. target specific variables?
> Look:
>
>> I.e., something like:
>> --------
>> # delete the normal rule, so that ours is preferred
>> %.o: %.c
>>
>> # provide ours that expects %.o_c to contain the command for building
>> the .o file
>> %.o: %.o_c %.c
>>         $(shell cat $(filter %.o_c,$^)) $(OUTPUT_OPTION) $(filter %.c,$^)
>>
>> # generate or update the file containing the command.  The FORCE is because
>> # we need this to be rebuilt each time, but we can't declare it .PHONY (as 
>> then
>> # the %.o would always be rebuilt too, even if the %.o_c didn't change)
>> %.o_c: FORCE
>>         @+new='$(COMPILE.c)'; \
>>         printf '%s\n' "$$new" | cmp -s - $@ || printf '%s\n' "$$new" >$@
>
> When you dump command, you expand $(COMPILE.c) in %.o_c context, and
> that looses e.g. target specific CFLAGS for e.g.
>
> 1.o : CFLAGS += -O6

Nope, that works just fine with my example.  Seriously, give it a shot.

I just noticed a bug in my example: the .SECONDARY rule should be
changed to .PRECIOUS, as .SECONDARY doesn't accept patterns.  (This
has tripped me up before, yes)


> Also, if $<, $^ and $+ are present in $(COMPILE.c) they are not the
> same they would be when building %.o .

Well, in my experience, auto-dependency generation already handles
changes to prerequisite lists without any extra effort.  How are those
variables changing without one of the files in the *previous* list
actually being changed (i.e., mtime bump)?


>  Yes, it is possible to leave
> ``$<'' and friends in command output as is (i.e. unexpanded), and to
> later substitute them by hand, but that's not correct -- e.g. $+ could
> change between runs, and we would not notice.

Can you expand on how that would occur?

[Checking this over before sending it, I just realized what a horrible
pun that sentence was...]


> I know default $(COMPILE.c) does not have auto variables, and so the
> whole target cmd has additional
>
>    ... $(OUTPUT_OPTION) $(filter %.c,$^)
>
> but is that 100% correct? e.g. $(OUTPUT_OPTION) could change between
> runs and we won't notice. More, e.g. for link commands, $^ could change
> (e.g. user adds new .o to, or removes unneeded .o from list of library
> objects), and this wouldn't be noticed either.

OUTPUT_OPTION is just "-o $@", so don't worry about other random
variables in it.  I'm not sure why it was ever put into GNU make; I'm
trying to think of a way to use it that wouldn't be *better* done by
altering other variables and am coming up blank.  IMO, the right
solution for this is to just use "-o $@" in that rule.  In fact,
consider that another bug in what I originally suggested.

Note that in POSIX compliant mode, GNU make doesn't use OUTPUT_OPTION
in the default rules.  Just Say No.


> The main problem here is that $(COMPILE.c) or whatever, gets expanded
> not in the target context, and that's the main pity -- correct expansion
> is only possible in target context in _recipe_ only.

Yes, automatic variables are only defined as necessary in the target
rule's context.  You have two options:
1) detect changes to them via other means, or
2) abandon the idea of using make's built-in file dependency
   logic to detect when commands have changed.

I've never had any problems doing choice #1, but perhaps you can
illustrate how you're running into it.


...
> #         .------- says expand following in target context when rule is 
> already
> #         |        selected and add expansion result to prerequisites. We 
> could
> #         |        have ``&|'' as well.
> #         v
> %.o: %.c  & $(call @.force-if-cmd-changed,cmd_cc_o_c)
>        $(cmd_cc_o_c)
>        echo 'cmd_$@ := $(cmd_cc_o_c)' > address@hidden
...
> How is that? Very similar to second expansion, but a bit different.

It sounds like (I haven't looked closely) there's a bug in
.SECONDEXPANSION.  If that bug was fixed, would you need this
additional feature?  If no (the fix would be sufficient), then I
strongly recommend that you just try to fix the bug (or work with
Paul, Boris, et al to fix it) instead of trying to get a subtle
feature added.  If nothing else, consider how much more work
*documenting* this (with a good example of a problem it solves that
can't easily be otherwise solved!) would be!


Philip Guenther




reply via email to

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