Re: bug? $(warning)/$(error) evaluated from inside a comment in a 'define'?

2007-06-20 Thread Sam Ravnborg
On Tue, Jun 19, 2007 at 08:50:32PM +0200, Stephan Beal wrote:
 Hi, Makers!
 
 i just discovered a Make behaviour which really surprises me. While that 
 in itself is nothing new ;), this one certainly violates the principal 
 of least astonishment:
 
 When a $(warning) or $(error) is inside a 'define', it is evaluated even 
 if it is part of a comment. A demonstration:
 
 [EMAIL PROTECTED]:~/cvs/www.t5$ make --version
 GNU Make 3.81
 ...
 
 Input file to reproduce problem:
 #!/usr/bin/make -f
 ##
 default: all
 define bogo
# $(warning this should not be evaluated here: (bogo $(1)))
abc := $(1)
 endef

On the other hand I would have been suprised if make supported having comments
between define/endef.
So in several cases I have used define/endef to avoid the need to quote #.
Or in other words if # suddenly becomes a comment inside define/endef some
Makefile's will break.

Sam


___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Re: bug? $(warning)/$(error) evaluated from inside a comment in a 'define'?

2007-06-20 Thread Paul Smith
On Tue, 2007-06-19 at 20:50 +0200, Stephan Beal wrote:
 When a $(warning) or $(error) is inside a 'define', it is evaluated
 even if it is part of a comment.

Others have responded with all the info but I'm not sure everyone
understood it.

There are two factors at work here.

First, note that make does not do comment processing inside a define
statement.  If you add a # inside a define, then that literal
character # (plus the rest of the line) is present in the value of the
variable being defined.  In fact nothing is parsed inside a define.  I'm
not sure, from your message, if this is what you feel is the surprising
behavior; to me it seems exactly the way things should work.  Think of a
define as kind of like single-quoted strings in the shell: no special
characters are evaluated.

Second, note that comment characters IN COMMAND SCRIPTS are not
interpreted by make as make comments, either.  That is this:

foo:
# bar

is a target foo with a comment after it and no command script, while
this:

foo:
# bar

is a target foo with a command script of # bar, which passed to the
shell as normal and may or may not end up being a comment in the shell.

So, when you put a variable $(foo) in a command script (preceded by a
TAB) and it's expanded, the expanded value is not parsed for make
comments.  The # and following text is kept.

Then, of course, before make invokes the shell it expands the script,
and when that happens the $(warning ...) or $(info ...) or whatever else
is evaluated.

-- 
---
 Paul D. Smith [EMAIL PROTECTED]  Find some GNU make tips at:
 http://www.gnu.org  http://make.paulandlesley.org
 Please remain calm...I may be mad, but I am a professional. --Mad Scientist


___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Re: bug? $(warning)/$(error) evaluated from inside a comment in a 'define'?

2007-06-20 Thread Stephan Beal
On Wednesday 20 June 2007, Philip Guenther wrote:
 On 6/19/07, Stephan Beal [EMAIL PROTECTED] wrote:
 Okay, so you've defined a variable, 'bogo', whose value consists of
 two lines, the first of which has a '#' as its first non-whitespace
 character.  It isn't a comment at that point, it's just a line with a
 leading '#'.

i see. That makes perfect sense, actually. My intuition told me that 
comments are skipped at an earlier parsing phase (e.g., filtered out 
long before the 'define'd item is called), but obviously that's not the 
case.

 (Then there are comments in the commands for rules, where if they're
 indented with a tab then make sees them as normal parts of the
 commands and passes them to the shell...which then will often ignore
 them based on *its* rules.)

The book Managin Projects with GNU Make demonstrates using that as an 
intesting test/debugging feature instead of using 'echo':

foo:
# MAKEFILE_LIST=$(MAKEFILE_LIST)

Thanks for the clarification!

:)

-- 
- [EMAIL PROTECTED]
http://www.wanderinghorse.net


signature.asc
Description: This is a digitally signed message part.
___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Re: bug? $(warning)/$(error) evaluated from inside a comment in a 'define'?

2007-06-20 Thread Stephan Beal
On Wednesday 20 June 2007, Paul Smith wrote:
 the variable being defined.  In fact nothing is parsed inside a
 define.  I'm not sure, from your message, if this is what you feel is
 the surprising behavior; 

Right - that's what surprised me. i assumed that comments were skipped 
during the initial read-in of the makefile, regardless of their 
context. The behaviour does make sense once one learns that define is 
parsed as a literal. That also explains why i can't use if/endif inside 
a define.

 to me it seems exactly the way things should 
 work.  Think of a define as kind of like single-quoted strings in the
 shell: no special characters are evaluated.

Agreed - i hadn't considered defines to be literals.

Thanks again for the detailed explanation!

:)

PS: it might interest some list readers to know that i recently forked a 
copy of O'Reilly's Managing Projects with GNU Make and am steadily 
updating it:

  http://www.wanderinghorse.net/computing/make/

If anyone out there is interested in contributing to the book, please 
feel free to get in touch.

-- 
- [EMAIL PROTECTED]
http://www.wanderinghorse.net


signature.asc
Description: This is a digitally signed message part.
___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


bug? $(warning)/$(error) evaluated from inside a comment in a 'define'?

2007-06-19 Thread Stephan Beal
Hi, Makers!

i just discovered a Make behaviour which really surprises me. While that 
in itself is nothing new ;), this one certainly violates the principal 
of least astonishment:

When a $(warning) or $(error) is inside a 'define', it is evaluated even 
if it is part of a comment. A demonstration:

[EMAIL PROTECTED]:~/cvs/www.t5$ make --version
GNU Make 3.81
...

Input file to reproduce problem:
#!/usr/bin/make -f
##
default: all
define bogo
   # $(warning this should not be evaluated here: (bogo $(1)))
   abc := $(1)
endef
$(foreach ARG,abc def ghi,$(eval $(call bogo,$(ARG
all:
##

[EMAIL PROTECTED]:~/cvs/www.t5$ make -f bug.make
bug.make:11: this should not be evaluated here: (bogo abc)
bug.make:11: this should not be evaluated here: (bogo def)
bug.make:11: this should not be evaluated here: (bogo ghi)
make: Nothing to be done for `default'.

As far as i understand, comments are comments, regardless of the 
context. ???

My assumption is that this also applies to other $(functions) inside 
such a comment, but i haven't tried it out.

Or is this a strange as-designed behaviour?


Many thanks in advance for your time and your awesome product,
(No, that's not sarcasm! i'm a huge fan!)

-- 
- [EMAIL PROTECTED]
http://www.wanderinghorse.net


signature.asc
Description: This is a digitally signed message part.
___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Re: bug? $(warning)/$(error) evaluated from inside a comment in a 'define'?

2007-06-19 Thread Agent Zhang

On 6/20/07, Stephan Beal [EMAIL PROTECTED] wrote:


When a $(warning) or $(error) is inside a 'define', it is evaluated even
if it is part of a comment. A demonstration:



I think the test case to demonstrate this bug can be simplified as:

define bogo
 # $(warning this should not happen)
endef
all:
$(bogo)

And make produces

$ make -f a.mk
a.mk:5: this should not happen
#

Yeah, it's really funny.

Also, $(info ...) and its families seem to evaluate too early
according to my vague impression.

Cheers, agentz


___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Re: bug? $(warning)/$(error) evaluated from inside a comment in a 'define'?

2007-06-19 Thread Philip Guenther

On 6/19/07, Stephan Beal [EMAIL PROTECTED] wrote:
...

When a $(warning) or $(error) is inside a 'define', it is evaluated even
if it is part of a comment.


The above statement is nonsensical.  If something is inside a define,
is not inside a comment.


define bogo
   # $(warning this should not be evaluated here: (bogo $(1)))
   abc := $(1)
endef
$(foreach ARG,abc def ghi,$(eval $(call bogo,$(ARG


Okay, so you've defined a variable, 'bogo', whose value consists of
two lines, the first of which has a '#' as its first non-whitespace
character.  It isn't a comment at that point, it's just a line with a
leading '#'.

So why isn't it being treated as a comment when you evaluate it?
Answer: it *is*, but the expansion of the variables and functions in
the value of 'bogo' takes place before 'eval' does anything.  Consider
this:

define bogo2
# $(warning foo! $(1))
endef
all:
   echo '$(bogo2)'
   echo '$(call bogo2,baz)'
$ gmake -f m2
m2:6: foo!
m2:6: foo! baz
echo '# '
#
echo '# '
#
$

When $(bogo2) is expanded, whether directly or via $(call), make
recursively expands the variables and functions inside its value.
That's all without $(eval) being used at all.



As far as i understand, comments are comments, regardless of the
context. ???


Not at all.  A comment is only a comment when being read, either as
part of the raw makefile or as the first step in eval's actual
operation.

(Then there are comments in the commands for rules, where if they're
indented with a tab then make sees them as normal parts of the
commands and passes them to the shell...which then will often ignore
them based on *its* rules.)


Philip Guenther


___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Re: bug? $(warning)/$(error) evaluated from inside a comment in a 'define'?

2007-06-19 Thread Philip Guenther

On 6/19/07, Agent Zhang [EMAIL PROTECTED] wrote:
...

I think the test case to demonstrate this bug can be simplified as:

define bogo
  # $(warning this should not happen)
endef
all:
$(bogo)

And make produces

$ make -f a.mk
a.mk:5: this should not happen
#

Yeah, it's really funny.


Funny in the this computer is broken: it only does what I tell it to,
not want I want! sense, I presume.  You told it to expand $(bogo)
completely, so it did.  If you don't want that, then tell it to only
expand it one level, with $(value):

$ cat Makefile
define bogo
# $(warning this should not be evaluated here)
endef
all:
   echo '$(value bogo)'
$ make
echo '# $(warning this should not be evaluated here)'
# $(warning this should not be evaluated here)
$

The trick is that you can't easily mix $(call) and $(value): there's
no way to say give me the value of 'bogo', expanding *only* the
argument variables $(1), $(2), ... and not other variables or
functions in 'bogo's value.  You have to indicate which variables
should have their expansion delayed *in the value of bogo*, by
doubling their '$':

$ cat Makefile
define bogo
# $$(warning this should not be evaluated here: $(1))
endef
all:
   echo '$(call bogo,foo)'
$ make
echo '# $(warning this should not be evaluated here: foo)'
# $(warning this should not be evaluated here: foo)
$

If you were to say $(eval $(call bogo,foo)) in that file, you wouldn't
get a warning because the $(warning) wouldn't be expanded before the
eval, and in the eval it would be in a comment.



Also, $(info ...) and its families seem to evaluate too early
according to my vague impression.


Like all variables and functions, they are expanded when the context
they are in is expanded.  Section 3.9 of the info pages describes
which contexts are subject to immediately expansion and which are
deferred until the containing variable is expanded or the rule's
commands are invokved.


Philip Guenther


___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make