bugmake - Bugs: bug #14126, Incorrect...

 
 

bug #14126: Incorrect pattern-specific-variable values applied to pattern rule commands

Submitter:  None
Submitted:  Sun 14 Aug 2005 11:02:09 PM UTC
   
 
Severity:  3 - Normal Item Group:  Enhancement
Status:  None Privacy:  Public
Assigned to:  None Open/Closed:  Open
Component Version:  3.80 Operating System:  Any
Fixed Release:  None Triage Status:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Wed 08 Feb 2006 10:50:39 PM UTC, comment #6: 

I'm really not thrilled about the idea of making this behavior optional.  Having two completely different ways to do something as fundamental as search patterns seems to me to be a maintenance and support nightmare.  I want to get 3.81 out the door, then we can think about how to address this issue.  We'll need to get input from the wider community as well.

Paul D. Smith <psmith>
Group administrator
Wed 08 Feb 2006 07:20:23 AM UTC, comment #5: 


> I don't know what can be done to fix this, now that there are
> several versions with IMHO the incorrect behaviour out there.


The new behavior can be made optional. You will have to explicitly turn it on by setting a special variable or mentioning a special target in your makefiles. The fix is quite simple: we need to stable-pre-sort pattern-specific variables (and patter rules) in the shortest-stem-first order. Paul, do you think we can get this feature into 3.81? John is the second individual (not including me) who got bitten by this in the past couple of months.

Boris Kolpackov <bosk>
Group Member
Wed 08 Feb 2006 03:24:27 AM UTC, comment #4: 


> The manual says " Variables defined in this way are searched
> ... BEFORE target-specific variables defined for the parent
> target"


That's completely unrelated to the behavior you're talking about.  That sentence is talking about the fact that target-specific variables are "inherited" through target/prerequisite relationships, so that in:

  FOO = global
  foo: bar
  foo: FOO = foo
  bar: ; @echo $(FOO)

will print "foo", not "global", because "bar" inherits foo's target-specific variable settings.  But, if you also define:

  bar: FOO = bar

then you'll get "bar", because the setting for "bar" takes precendence over the setting for "foo" when building "bar".

You are taking this part of the docs out of context and trying to make it fit the behavior of patterns.  The documentation is very, very clear about how pattern-specific variables match, so there's no reason for confusion on this point.  This sentence comes just before the sentence you quote above:

> If a target matches more than one pattern, all the matching
> pattern-specific variables are interpreted in the order in
> which they were defined in the makefile, and collected
> together into one set.

Paul D. Smith <psmith>
Group administrator
Wed 08 Feb 2006 02:01:49 AM UTC, comment #3: 

I was bitten hard by this bug/defect/feature.

The manual says " Variables defined in
this way are searched ... BEFORE target-specific variables defined
for the parent target"

So it would seem to me that:

foo/bar/%.o: FOO=xxx

should take precedence over

foo/%.o:  FOO=yy

and that would be the intuitive behaviour too.  (Longest pattern matches, like in lex ).  Unfortunately the opposite is true.

I don't know what can be done to fix this, now that there are several versions with IMHO the incorrect behaviour out there.

John Darrington <jmd>
Thu 19 Jan 2006 12:56:54 PM UTC, comment #2: 

It's a normal feature, not a defect.

1) Target-specific variable assignment rules are different from dependency rules.  Dependency rules are combined into a single rule for each target.  The assignment rules stay separate.

2) Every assignment rule that matches the current target is executed, in order, from the beginning of the makefile to its end.  (That behavior is needed, in order to set more than one variable.)  The last assignment to a particular variable is the one that "sticks."

3) "dir/%.o" is a more general version of the "dir/dbg/%.o" pattern.  Therefore, "dir/dbg/blah.o" matches both of them -- the V variable is assigned twice!  ("dir/blah.o" matches only one of the patterns.)  Yes, the order in which those assignments are done has a significant side-effect.

If there is a defect, it's in the documentation.  We can infer that behavior, but only if we "read between the lines."

 -Greg

Anonymous
Mon 15 Aug 2005 02:58:03 PM UTC, comment #1: 

This is not a bug per se, rather a defect in the way pattern-specific variables override each other.

Some time ago I proposed changing pattern rules selection algorithm from picking the first applicable rule to picking the most specialized one (formally, the one with the shortest stem). I guess this will also be useful (or even more so) for pattern-specific variables.

Paul, what do you think?

Boris Kolpackov <bosk>
Group Member
Sun 14 Aug 2005 11:02:09 PM UTC, original submission:  

Something's not right with pattern-rule-specific variables in make 3.81beta3:

$ ls
makefile
makefile.good
$ cat makefile
.PHONY: all dbg nondbg

all: blah.cpp dir/dbg/blah.o dir/blah.o

blah.cpp: ; touch $@

dbg: ; echo dbg
nondbg: ; echo nondbg

dir/dbg/%.o : V = dir/dbg
dir/dbg/%.o : %.cpp | $$(V)/. dbg ; echo dbg-V:$(V); touch $@

dir/%.o : V = dir/nondbg
dir/%.o : %.cpp | $$(V)/. nondbg ; echo nondbg-V:$(V); touch $@

.PRECIOUS: %/.
%/.: ; mkdir -p $*

$ make-3.81beta3
touch blah.cpp
echo dbg
mkdir -p dir/nondbg
echo dbg-V:dir/nondbg; touch dir/dbg/blah.o
echo nondbg
echo nondbg-V:dir/nondbg; touch dir/blah.o

The value of V seems to come from the nondbg pattern rule, although the dbg pattern rule's commands are executed.  I think this is also why there is no 'mkdir -p dir/dbg' when there should be (because the order-only 'dbg' prerequisite was run).

The nasty thing is, if you reverse the order of the dbg and nondbg pattern rules in the makefile, you get the proper behavior:

$ cat makefile.good
.PHONY: all dbg nondbg

all: blah.cpp dir/dbg/blah.o dir/blah.o

blah.cpp: ; touch $@

dbg: ; echo dbg
nondbg: ; echo nondbg

dir/%.o : V = dir/nondbg
dir/%.o : %.cpp | $$(V)/. nondbg ; echo nondbg-V:$(V); touch $@

dir/dbg/%.o : V = dir/dbg
dir/dbg/%.o : %.cpp | $$(V)/. dbg ; echo dbg-V:$(V); touch $@

.PRECIOUS: %/.
%/.: ; mkdir -p $*

$ make-3.81beta3 -f makefile.good
touch blah.cpp
echo dbg
mkdir -p dir/dbg
echo dbg-V:dir/dbg; touch dir/dbg/blah.o
echo nondbg
mkdir -p dir/nondbg
echo nondbg-V:dir/nondbg; touch dir/blah.o

This is a serious problem for non-recursive make scenarios that make extensive use of pattern rules for commands to build objects from source in various subdirectories, because the pattern-specific variable values that are used depend on the order of the rules.

Anonymous

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files
file #3359:  makefiles.tar added by None (10KiB - application/x-tar - makefile and makefile.good)

 

Depends on the following items: None found

Items that depend on this one: None found

 

CC list is empty

 

There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

Only logged-in users can vote.

 

Follow 5 latest changes.

Date Changed by Updated Field Previous Value => Replaced by
2005-08-24 psmith Item GroupBug Enhancement
    Component Version4.0 3.80
    Operating SystemPOSIX-Based Any
2005-08-14 paxunix Carbon-Copy- Added -email is unavailable-
2005-08-14 None Attached File- Added makefiles.tar, #2820

Back to the top

Powered by Savane 3.13-4448.
Corresponding source code