[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
define and conditionals directives
From: |
Yann Droneaud |
Subject: |
define and conditionals directives |
Date: |
Fri, 23 May 2014 18:10:21 +0200 |
Hi,
I've written something like the makefile fragment below and I was
surprised to have it working as I'd like to instead of how I've
understand the documentation:
define macro
rule_$(strip $(1))_stamp:
ifneq ($(strip $(wildcard $(2)/*.stamp)),)
for f in $(wildcard $(2)/*.stamp)) ; do echo $$$$f ; done
endif
touch $$@
endef
$(eval $(call macro,name,stamp-dir))
all: rule_all_stamp
Running "make rule_all_stamp" will show that recipe from
"rule_all_stamp" rule is correctly processing the files in "stamp-dir"
directory.
This make me wonder about the relation between conditionals directive
and multi line variables defined with "define" directive.
Another "simplified" test case would be
variables += foo
define foo
ifeq($(bar),)
$(info Foo: empty $(bar))
endif
endef
variables += fuu
define fuu
ifeq($$(bar),)
$$(info Fuu: empty $$(bar))
endif
endef
define printvar_u
$(info Unexpanded:)$(info )$(foreach var, $(variables), $(info
$(var) = $(value $(var)))$(info ))$(info )
endef
define printvar_e
$(info Expanded:)$(info )$(foreach var, $(variables), $(info $(var)
= $($(var)))$(info ))$(info )
endef
printvar:
@ : $(printvar_u) $(printvar_e)
Executing this makefile would produce:
$ make
Unexpanded:
foo = ifeq($(bar),)
$(info Foo: empty $(bar))
endif
fuu = ifeq($$(bar),)
$$(info Fuu: empty $$(bar))
endif
Expanded:
Foo: empty
foo = ifeq(,)
endif
fuu = ifeq($(bar),)
$(info Fuu: empty $(bar))
endif
As you can see the conditionals directives are not processed when the
variables are defined: the variables contains the directive asis.
It seems that 'define' have precedence over conditionals directives.
(Note: conditionals directives are not processed as part of variable
expansion, $(eval ) should be used for that).
According to the documentation:
"Conditional directives are parsed immediately."
3.7 How make Reads a Makefile
http://www.gnu.org/software/make/manual/html_node/Reading-Makefiles.html
"The define directive does not expand variable references and
function calls in the canned sequence; the ‘$’ characters,
parentheses, variable names, and so on, all become part of the
value of the variable you are defining. See Defining Multi-Line
Variables, for a complete explanation of define."
5.8 Defining Canned Recipes
http://www.gnu.org/software/make/manual/html_node/Canned-Recipes.html
"As this example illustrates, conditionals work at the textual
level: the lines of the conditional are treated as part of the
makefile, or ignored, according to the condition. This is why the
larger syntactic units of the makefile, such as rules, may cross
the beginning or the end of the conditional."
7.1 Example of a Conditional
http://www.gnu.org/software/make/manual/html_node/Conditional-Example.html
"make evaluates conditionals when it reads a makefile."
7.2 Syntax of Conditionals
http://www.gnu.org/software/make/manual/html_node/Conditional-Syntax.html
It seems that conditionals directive are not evaluated when make reads
a multiline variable definition. That should probably be mentioned in
the documentation, just be sure this behavior won't be lost in future
make release: it's an important behavor for being able to use
conditionals directives with $(eval ) function.
Regards.
--
Yann Droneaud
OPTEYA
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- define and conditionals directives,
Yann Droneaud <=