[Top][All Lists]
[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