stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Travis Vitek <vi...@roguewave.com>
Subject Re: missing build line for 22.locale.codecvt.out
Date Fri, 09 Nov 2007 00:22:59 GMT




Martin Sebor wrote:
> 
> Ugh. I really don't want to hack around it by renaming the test.
> If it bothers you that much why don't you take the time to figure
> out what's behind the make behavior we don't understand? We'll
> all learn something :)
> 

No problem. Here is a simple makefile testcase...


[vitek@robot vitek]$ cat GNUmakefile 

%.c:
        touch $@

%:      %.c
        touch $@

%.out:  %
        touch $@

[vitek@robot vitek]$ gmake a.c b.out.c
touch a.c
touch b.out.c
[vitek@robot vitek]$ gmake a
touch a
[vitek@robot vitek]$ gmake b.out
gmake: *** No rule to make target `b.out'.  Stop.
[vitek@robot vitek]$ 


You're probably asking why this happens. Well, here is the output of `gmake
-d a'...


Updating goal targets....
Considering target file `a'.
 File `a' does not exist.
 Looking for an implicit rule for `a'.
 Trying pattern rule with stem `a'.
 Trying implicit prerequisite `a.c'.
 Found an implicit rule for `a'.
  Considering target file `a.c'.
   Looking for an implicit rule for `a.c'.
   Trying pattern rule with stem `a'.
   Found an implicit rule for `a.c'.
   Finished prerequisites of target file `a.c'.
  No need to remake target `a.c'.
 Finished prerequisites of target file `a'.
Must remake target `a'.
touch a
Putting child 0x00535ff0 (a) PID 27247 on the chain.
Live child 0x00535ff0 (a) PID 27247 
Got a SIGCHLD; 1 unreaped children.
Reaping winning child 0x00535ff0 PID 27247 
Removing child 0x00535ff0 PID 27247 from chain.
Successfully remade target file `a'.


We can see that gmake looks for `a', and finds the rule with prerequisite
`a.c'. The target `a.c' is evaluated and gmake discovers that it is up to
date, so it avoids remaking `a.c'. Now that the prerequisites exist, `a' is
generated.

Now look at the output of `gmake -d b.out'...


Considering target file `b.out'.
 File `b.out' does not exist.
 Looking for an implicit rule for `b.out'.
 Trying pattern rule with stem `b'.
 Trying implicit prerequisite `b'.
 Trying pattern rule with stem `b.out'.
 Trying implicit prerequisite `b.out,v'.
 Trying pattern rule with stem `b.out'.
 Trying implicit prerequisite `RCS/b.out,v'.
 Trying pattern rule with stem `b.out'.
 Trying implicit prerequisite `RCS/b.out'.
 Trying pattern rule with stem `b.out'.
 Trying implicit prerequisite `s.b.out'.
 Trying pattern rule with stem `b.out'.
 Trying implicit prerequisite `SCCS/s.b.out'.
 Trying pattern rule with stem `b'.
 Trying implicit prerequisite `b'.
 Looking for a rule with intermediate file `b'.
  Avoiding implicit rule recursion.
  Trying pattern rule with stem `b'.
  Trying implicit prerequisite `b,v'.
  Trying pattern rule with stem `b'.
  Trying implicit prerequisite `RCS/b,v'.
  Trying pattern rule with stem `b'.
  Trying implicit prerequisite `RCS/b'.
  Trying pattern rule with stem `b'.
  Trying implicit prerequisite `s.b'.
  Trying pattern rule with stem `b'.
  Trying implicit prerequisite `SCCS/s.b'.
 No implicit rule found for `b.out'.
 Finished prerequisites of target file `b.out'.
Must remake target `b.out'.
gmake: *** No rule to make target `b.out'.  Stop.


when trying to match the target `b.out', make sees the pattern rule to
generate `b.out' from `b' [%.out: %]. There is also the pattern rule to
generate `b.out' from `b.c' [%: %.c]. According to step 3 of the make
implicit rule search algorithm
[http://www.gnu.org/software/make/manual/html_node/Implicit-Rule-Search.html#Implicit-Rule-Search],
the latter of these rules will be discarded because the former is
essentially a 'better match'.

So this leaves gmake trying to generate `b.out' from `b'. According to the
docs, it attempts to find if the prerequisite `b' should exist or not. If
`b' is an explicit prerequisite for `b.out' or `b' is mentioned as a target,
then `b' should exist, otherwise it should not. I'm under the impression
that the pattern rule to generate `b' is not considered, so it is done. The
rule to make `b.out' from `b' cannot build `b.out', so it isn't a valid rule
to make `b.out' and you get the error message that we see above.


A simple makefile can be used to verify that this is correct.

[vitek@robot t]$ cat GNUmakefile 

%:
        touch $@

%.foo:  %.bar
        touch $@

[vitek@robot t]$ gmake a.foo
gmake: *** No rule to make target `a.foo'.  Stop.


So now we are pretty sure we know what is happening. All target names that
end in .out will match to the pattern rule for generating .out files first.
The question is how to fix it. Here are the options I see.

    1. rename the source file so the generated executable will not end in
.out
    2. change the .out rule to generate output files with some other
extension
    3. create an rule that is a better match than %.out so that rule is
selected for 22.locale.codecvt.out
    4. create a new makefile that includes the original GNUmakefile.tst, but
defines the more explicit rule mentioned in 3

I dislike option 3 the most, and from the sound of it you won't want to use
option 1. So how does option 2 sound?

Travis


-- 
View this message in context: http://www.nabble.com/missing-build-line-for-22.locale.codecvt.out-tf4385887.html#a13659042
Sent from the stdcxx-dev mailing list archive at Nabble.com.


Mime
View raw message