Re: [PATCH 2/2] order_only prereq shall not use parent per_target variables

2015-01-10 Thread Bernhard Reutner-Fischer
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 ?

2015-01-10 Thread Jason Vas Dias
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 ?

2015-01-10 Thread Jason Vas Dias
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 ?

2015-01-10 Thread Philip Guenther
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