On Tue, Feb 16, 2010 at 12:37:10PM +0300, Kirill Smelkov wrote: [...]
> > So, how about if you save the command line in a file > > and make that file a dependency of foo.o. If the rule to build the > > command file only updates the file if the command actually changed, > > then you'll get the desired behavior, no? > > 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 Dummy me, of course this will work for target-specific variables, because 1.o_c will inherit all target-specific changes for 1.o . Sorry... However the rest about automatic variables still seems to be true. Or am I missing something here too? > Also, if $<, $^ and $+ are present in $(COMPILE.c) they are not the > same they would be when building %.o . 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. > > 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. > > ---- > > 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. > > Even second expansion does not work -- it correctly expand target > specific variables, but treats $<, $^ and $+ differently compared to > in-recipe context. > > > If only there could be a way to add hooks in place where make 1) already > found rule for target, but 2) before that rule actually gets executed! > > This could be used to e.g. add FORCE prerequisite to force $@ rebuild, > or something more constrained... The main question here is to how to > inject make code which will get expanded in target context exactly, but > before that target gets run... > > Then something like the following should do what I need cleanly: > > ---- 8< ---- > > # @.force-if-cmd-changed <cmd-patter-name> > @.force-if-cmd-changed = \ > $(if $(call sne,$($1),$(cmd_$@)),\ > $(info $@: forcing rebuild due to CMD change) \ > FORCE) > > # .------- 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)' > [email protected] > > -include *.cmd > > ---- 8< ---- > > > How is that? Very similar to second expansion, but a bit different. > > > > That's pretty crude, but maybe it'll give you ideas on where to go. > > Thanks, I appreciate it. > > Kirill _______________________________________________ Help-make mailing list [email protected] http://lists.gnu.org/mailman/listinfo/help-make
