Re: [PATCH 2/2] order_only prereq shall not use parent per_target variables
On September 16, 2014 10:59:44 AM GMT+02:00, Bernhard Reutner-Fischer rep.dot@gmail.com wrote: On 16 September 2014 06:21, Paul Smith psm...@gnu.org wrote: On Mon, 2014-09-15 at 13:03 +0200, Bernhard Reutner-Fischer wrote: Order-only prerequisites should not use the per_target variables of it's parent. given: obj.o: X=-Dobj crt1.o: obj.o: | crt1.o we do not want crt1.o to be built with X set. I haven't applied this change yet: this is a change in the current functionality of GNU make and it's not clear to me why target-specific variables should work this way rather than the way they do now. I can see arguments both ways. Why shouldn't an order-only prerequisite take target-specific values from its parent? See below for my reasoning. OK? TIA and cheers, Because an order-only prerequisite is, well, order-only? :) My reasoning is that per-target variables are to be used only for the target they are defined for, not for random other targets, especially not for order-only targets. You would not want a per-target append variable to alter upper-scopes value either (i.e. not -Udir1 -Udir2 in one cc invocation in the sample below). How do you suggest would i build crt1.o above without X being in the scope of crt1.o? The only working workaround i can see is spawning a separate instance, but that is something i really do not want to do: $ /usr/bin/make -f GNUmakefile.workaround workaround=workaround /usr/bin/make -f GNUmakefile.workaround crt1.o make[1]: Entering directory '/scratch/src/bug-make' cc -c a.c -o crt1.o make[1]: Leaving directory '/scratch/src/bug-make' cc -Udir1 -c a.c -o dir1/file1.o -Ddir1 cc -Udir2 -c a.c -o dir2/file1.o -Ddir2 $ Sample once again: ---8--- .SUFFIXES: MAKEFLAGS += -r default: dir1/file1.o dir2/file1.o # workaround is either 'workaround' or 'crt1.o' workaround ?= crt1.o workaround: $(MAKE) -f $(word 1,$(MAKEFILE_LIST)) crt1.o dir1/file1.o dir2/file1.o: | $(workaround) CFLAGS-dir1 := -Ddir1 CFLAGS-dir2 := -Ddir2 doit = @echo $(CC) $(CFLAGS) -c a.c -o $@ $(PER_DIR) define add_per_dir ifneq ($(strip $(2)),) __add := $(2) $$(__add): PER_DIR:=$$(CFLAGS-$(1)) $$(__add): CFLAGS+=-U$(1) endif endef $(eval $(call add_per_dir,dir1,dir1/file1.o)) $(eval $(call add_per_dir,dir2,dir2/file1.o)) %.o: $(doit) $(if $(PER_DIR),$(if $(findstring crt1,$*),false PER_DIR=$(PER_DIR) but should not be set for $*)) ---8--- See what i mean? thanks, Signed-off-by: Bernhard Reutner-Fischer rep.dot@gmail.com --- tests/scripts/features/targetvars | 92 +++ variable.c| 20 - 2 files changed, 110 insertions(+), 2 deletions(-) diff --git a/tests/scripts/features/targetvars b/tests/scripts/features/targetvars index a9b8dbe..c1337e2 100644 --- a/tests/scripts/features/targetvars +++ b/tests/scripts/features/targetvars @@ -270,4 +270,96 @@ a: ; @echo $(A) # ', # '', local\n); +# TEST #21: per-target variable should not be inherited by order-only +# prerequisite +$details = \ +Per-target variable should not be inherited by order-only prerequisite; + +$makefile = get_tmpfile; +unlink $makefile if -f $makefile; + +open(MAKEFILE, $makefile); + +print MAKEFILE 'EOF'; +.SUFFIXES: +default: dir1/file1.o dir2/file1.o | dir3/file3.o + +CFLAGS := -O2 +CFLAGS-dir1 := -Ddir1 +CFLAGS-dir2 := -Ddir2 +doit = @echo $(CC) -c a.c -o $@ $(CFLAGS) $(PER_DIR) +define add_per_dir +ifneq ($(strip $(2)),) +__add := $(2) +$$(__add): PER_DIR:=$$(CFLAGS-$(1)) +endif +endef +$(eval $(call add_per_dir,dir1,dir1/file1.o)) +$(eval $(call add_per_dir,dir2,dir2/file1.o)) +%.o: + $(doit) + @#$(if $(PER_DIR),@test $* != dir3/file3 || false PER_DIR=$(PER_DIR) but should not be set) +ifndef OK +dir1/file1.o: | dir3/file3.o +endif +EOF + +close(MAKEFILE); + +# Variant 1 +run_make_with_options($makefile, , get_logfile); +$answer = cc -c a.c -o dir3/file3.o -O2\ncc -c a.c -o dir1/file1.o -O2 -Ddir1\ncc -c a.c -o dir2/file1.o -O2 -Ddir2\n; +compare_output($answer,get_logfile(1)); + +# Variant 2 +run_make_with_options($makefile, OK=1, get_logfile); +$answer = cc -c a.c -o dir1/file1.o -O2 -Ddir1\ncc -c a.c -o dir2/file1.o -O2 -Ddir2\ncc -c a.c -o dir3/file3.o -O2\n; +compare_output($answer,get_logfile(1)); + +# TEST #22: per-target variable should not be inherited by order-only +# prerequisite + +$makefile = get_tmpfile; +unlink $makefile if -f $makefile; +open(MAKEFILE, $makefile); + +print MAKEFILE 'EOF'; +.SUFFIXES: +default: libdir1.so libdir2.so | dir3/file3.o + +CFLAGS := -O2 +CFLAGS-dir1 := -Ddir1 +CFLAGS-dir2 := -Ddir2 +doit = @echo $(CC) -c a.c -o $@ $(CFLAGS) $(PER_DIR) +linkit = @echo $(CC) -o $@ dir3/file3.o $^ $(CFLAGS) $(PER_DIR) +define add_per_dir +ifneq ($(strip $(2)),) +__add := $(2) +$$(__add): PER_DIR:=$$(CFLAGS-$(1)) +endif +endef +$(eval $(call add_per_dir,dir1,dir1/file1.o)) +$(eval
bug with order-only prerequisites implicit rules implementation ?
Greetings - Please could anyone explain the behaviour of this test makefile (attached) : quotecode TMP:=/tmp %.ext: touch $@ .PHONY: *.oop %.oop: @echo 'A phony order-only prequisite of /tmp/a.t'; #$(TMP)/%.t: | %.oop $(TMP)/%.t:$(TMP)/%.ext | %.oop @echo Specific Rule %.t:%.ext @echo General rule /code/quote when invoked with : $ make -f ${the_makefile} /tmp/a.t I would expect that the most specific matching first rule would be invoked always, with its extra order-only pre-requisite recipe always being invoked, but actually this occurs only if /tmp/a.ext does not already exist - I tested latest make-4.1, and make-3.82, on a RHEL6 linux platform, and both show the same behaviour: $ make -f ${the_makefile} /tmp/a.t touch /tmp/a.ext A phony order-only prequisite of /tmp/a.t Specific Rule rm /tmp/a.ext but if I : $ touch /tmp/a.ext and then : $ make -f ${the_makefile} /tmp/a.t Gemeral Rule If I remove the phony order only dependency. so that the /tmp/%.t rule reads: quotecode $(TMP)/%.t:$(TMP)/%.ext /code/quote then the makefile always runs the first recipe, regardless of the existence of /tmp/a.ext : $ make -f ${the_makefile} /tmp/a.t Specific Rule $ touch /tmp/a.ext $ make -f ${the_makefile} /tmp/a.t Specific Rule $ rm /tmp/a.ext $ make -f ${the_makefile} /tmp/a.t touch /tmp/a.ext Specific Rule rm /tmp/a.ext Also, a second problem is that order-only dependencies are not recognized when specified by multiple rules without recipes are specified for same target , ie: quotecode $(TMP)/%.t: | %.oop $(TMP)/%.t:$(TMP)/%.ext /quote/code has the same effect (recipe for implicit order-only pre-requisite never runs) as no order-only dependency being specified at all. I thought the dependencies should be merged and the %.oop recipe should be run in this case, especially as I've told make that all *.oop targets are phony. Is this a bug with make ? Any responses much appreciated. Thank You Regards, Jason Vas Dias ___ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make
bug with order-only prerequisites implicit rules implementation ?
Greetings - Please could anyone explain the behaviour of this test makefile (attached) : quotecode TMP:=/tmp %.ext: touch $@ .PHONY: *.oop %.oop: @echo 'A phony order-only prequisite of /tmp/a.t'; #$(TMP)/%.t: | %.oop $(TMP)/%.t:$(TMP)/%.ext | %.oop @echo Specific Rule %.t:%.ext @echo General rule /code/quote when invoked with : $ make -f ${the_makefile} /tmp/a.t I would expect that the most specific matching first rule would be invoked always, with its extra order-only pre-requisite recipe always being invoked, but actually this occurs only if /tmp/a.ext does not already exist - I tested latest make-4.1, and make-3.82, on a RHEL6 linux platform, and both show the same behaviour: $ make -f ${the_makefile} /tmp/a.t touch /tmp/a.ext A phony order-only prequisite of /tmp/a.t Specific Rule rm /tmp/a.ext but if I : $ touch /tmp/a.ext and then : $ make -f ${the_makefile} /tmp/a.t Gemeral Rule If I remove the phony order only dependency. so that the /tmp/%.t rule reads: quotecode $(TMP)/%.t:$(TMP)/%.ext /code/quote then the makefile always runs the first recipe, regardless of the existence of /tmp/a.ext : $ make -f ${the_makefile} /tmp/a.t Specific Rule $ touch /tmp/a.ext $ make -f ${the_makefile} /tmp/a.t Specific Rule $ rm /tmp/a.ext $ make -f ${the_makefile} /tmp/a.t touch /tmp/a.ext Specific Rule rm /tmp/a.ext Also, a second problem is that order-only dependencies are not recognized when specified by multiple rules without recipes are specified for same target , ie: quotecode $(TMP)/%.t: | %.oop $(TMP)/%.t:$(TMP)/%.ext /quote/code has the same effect (recipe for implicit order-only pre-requisite never runs) as no order-only dependency being specified at all. I thought the dependencies should be merged and the %.oop recipe should be run in this case, especially as I've told make that all *.oop targets are phony. Is this a bug with make ? Any responses much appreciated. Thank You Regards, Jason Vas Dias ___ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make
Re: bug with order-only prerequisites implicit rules implementation ?
On Sat, Jan 10, 2015 at 7:06 PM, Jason Vas Dias jason.vas.d...@gmail.com wrote: Please could anyone explain the behaviour of this test makefile (attached) : quotecode TMP:=/tmp %.ext: touch $@ .PHONY: *.oop %.oop: @echo 'A phony order-only prequisite of /tmp/a.t'; #$(TMP)/%.t: | %.oop $(TMP)/%.t:$(TMP)/%.ext | %.oop @echo Specific Rule %.t:%.ext @echo General rule /code/quote when invoked with : $ make -f ${the_makefile} /tmp/a.t I would expect that the most specific matching first rule would be invoked always, with its extra order-only pre-requisite recipe always being invoked, but actually this occurs only if /tmp/a.ext does not already exist - I tested latest make-4.1, and make-3.82, on a RHEL6 linux platform, and both show the same behaviour: $ make -f ${the_makefile} /tmp/a.t touch /tmp/a.ext A phony order-only prequisite of /tmp/a.t Specific Rule rm /tmp/a.ext but if I : $ touch /tmp/a.ext and then : $ make -f ${the_makefile} /tmp/a.t Gemeral Rule This behavior is documented. To quote from the info pages, section 10.5.4 How Patterns Match: A pattern rule can be used to build a given file only if there is a target pattern that matches the file name, _and_ all prerequisites in that rule either exist or can be built. The rules you write take precedence over those that are built in. Note however, that a rule whose prerequisites actually exist or are mentioned always takes priority over a rule with prerequisites that must be made by chaining other implicit rules. When /tmp/a.ext exists but a.oop doesn't, then the 'general' rule has precedence because all the prerequisites exist, while the 'specific' rule has a non-existent prerequisite (a.oop). If I remove the phony order only dependency. so that the /tmp/%.t rule reads: quotecode $(TMP)/%.t:$(TMP)/%.ext /code/quote then the makefile always runs the first recipe, regardless of the existence of /tmp/a.ext : Given the explanation above, that should make sense. Also, a second problem is that order-only dependencies are not recognized when specified by multiple rules without recipes are specified for same target , ie: quotecode $(TMP)/%.t: | %.oop $(TMP)/%.t:$(TMP)/%.ext /quote/code has the same effect (recipe for implicit order-only pre-requisite never runs) as no order-only dependency being specified at all. I thought the dependencies should be merged and the %.oop recipe should be run in this case, especially as I've told make that all *.oop targets are phony. Pattern rules, unlike normal rules, are never merged. Each one stands alone and either completely overrides a previous pattern rule with the exact same target and prerequisites (but possibly different commands, or *no* commands, which cancels the previous pattern rule), or adds a new pattern for the target with different prerequisites. Philip Guenther ___ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make