bug-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: unexpected behavior of $(warning ...) from $(eval ...)


From: Paul D. Smith
Subject: Re: unexpected behavior of $(warning ...) from $(eval ...)
Date: Fri, 16 May 2003 21:01:39 -0400

%% "Robert W. Anderson" <address@hidden> writes:

  rwa> This makefile fragment seems to produce surprising behavior:

  rwa> define FUNC
  rwa>    ifeq (1,2)
  rwa>      $(warning 1 eq 2)
  rwa>    else
  rwa>      $(warning 1 ne 2)
  rwa>    endif
  rwa> endef

  rwa> $(eval $(FUNC))

  rwa> % make
  rwa> GNUmakefile:9: 1 eq 2
  rwa> GNUmakefile:9: 1 ne 2
  rwa> make: *** No targets.  Stop.

  rwa> Should I file this on Savannah, or am I confused?

The latter... but that's OK, eval can be confusing! :).

_Before_ eval parses its arguments, it expands them.  _After_ expansion,
the results of the expansion are parsed as if they were makefiles.

In this case, while make is expanding the variable $(FUNC) it's also, of
course, expanding everything inside the value recursively (as make
always does).  Because this is just simple expansion, not parsing, make
does not recognize that there is an ifeq statement and it does not treat
it as a make conditional.  So, both warnings are evaluated.  In other
words, it goes like this:

 $(eval $(FUNC))

    --> $(FUNC)

        --> ifeq (1,2)
                $(warning 1 eq 2)
            else
                $(warning 1 ne 2)
            endif

(show the warnings, and $(warning ...) evaluates to the empty string)

            --> ifeq (1,2)
                else
                endif

So the content that is actually evaluated is just:

    ifeq (1,2)
    else
    endif


You have two choices.  The first is to use the new $(value ...) function
which inhibits any recursive expansion at all; it simply returns the
value of the variable, like this:

  $(eval $(value FUNC))

This works in your case because you don't want anything expanded until
the eval is running.  However, most of the time you probably _do_ want
some things expanded; in that case you'll have to escape those things
which you _don't_ want expanded, like this:

  define FUNC
    ifeq (1,2)
      $$(warning 1 eq 2)
    else
      $$(warning 1 ne 2)
    endif
  enddef

Now when FUNC is expanded the "$$" will be changed to "$" and the
warning won't be treated as a function, then when the eval reads in the
fragment _then_ it will be evaluated.


Hope this helps...

-- 
-------------------------------------------------------------------------------
 Paul D. Smith <address@hidden>          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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]