help-make
[Top][All Lists]
Advanced

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

Re: Variable definition in eval'd function


From: Bryan Ischo
Subject: Re: Variable definition in eval'd function
Date: Thu, 11 Oct 2007 02:49:20 -0400 (EDT)
User-agent: SquirrelMail/1.4.8-4.fc5

First off - thank you very much for your detailed explanations; they
really help me to understand the underlying behavior of make much better
than I did.

As to my particular problem, I ended up solving it by creating a template
that I invoked with parameters whose values were the variables I needed. 
In this way I get the $(call) behavior of replacing variable values
immediately, rather than the $(eval) behavior of replacing variables only
when the variable is used (sometimes).  To expand my previous example to
show what I did:

--- begin foo.mk ---
VARIABLE = foo_variable
--- end foo.mk ---

--- begin bar.mk
VARIABLE = bar_variable
--- end bar.mk ---

--- begin Makefile ---

FRAGMENTS = foo bar

define TEST_RULE

.PHONY: $(1)
$(1):
       @echo $$@
       @echo $(2)

endef

define PROCESS_FRAGMENT

-include $(1).mk

$$(eval $$(call TEST_RULE,$(1),$$(VARIABLE)))

endef

$(foreach i, $(FRAGMENTS), $(eval $(call PROCESS_FRAGMENT,$(i))))

--- end Makefile ---

This allows me to use a single variable, VARIABLE, that is defined in
foo.mk and bar.mk, and each makefile fragment results in the rules that I
was hoping for, i.e.:

.PHONY: foo
foo:
        @echo foo
        @echo foo_variable

.PHONY: bar
bar:
        @echo bar
        @echo bar_variable

Paul Smith wrote:

> Either or both of these easily lend themselves to a templated
> environment.  In fact I wrote a full environment very similar (even down
> to syntax) to the one you're using and I found that derived variables
> were VERY helpful in this model; I could do things like:
>
>       LIBRARIES = foo
>
>       foo_SRCS = foo.c bar.c baz.c
>       foo_CFLAGS = -Wall -Werror
>       bar.o_CFLAGS = -Wno-error
>
> etc.

Yes, this is exactly the approach that I am using, and it makes for really
concise and powerfile makefile 'fragments'.  The only caveat is that
without using techniques like I wrote above (causing variables to be
substituted via $(call) instead of via $(eval)), the "LIBRARIES" variable
would not be useable via multiple makefile fragments in my system.  It
would have to be "foo_LIBRARIES" and "bar_LIBRARIES" or somesuch, but with
the workaround I wrote about above, I get to have generic variable names
whose values are substituted at the time that the template is
instantiated.

> It's really important not to fall into the trap of reading makefiles as
> if they were a procedural programming language like a shell script: they
> are most definitely NOT.  Makefiles are essentially a declarative
> programming language.

Good point.  I try to think of the $(call) and $(eval) functions more like
text-replacing, kind of like a preprocessor on steroids.  And that concept
works pretty well in practice except when it comes to variables that are
in rules, which don't get substituted as I expected (but now see that GNU
make is doing the 'right' thing).

Anyway, thanks again very much for your help, and best wishes,
Bryan






reply via email to

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