help-make
[Top][All Lists]
Advanced

[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





reply via email to

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