38934


Makefileのターゲット内で変数に値を設定し，  
その変数を用いて条件分岐により処理を切り替えたいと考えています．

ターゲット内では単に代入はできずevalを用いる必要があるため  
以下のようなMakefileを書きました．

[code]

    build:
        $(eval CC := gcc)
    
    ifeq ($(CC),gcc)
        @echo $(CC) is gcc
    else
        @echo $(CC) is not gcc
    endif
    
[/code]

しかし，これを実行しても変数CCはgccでないと判定されます．

[code]

    $ make
    gcc is not gcc
    
[/code]

変数に値を設定する場所がターゲット外の場合は  
期待した通り変数CCはgccであると判定されます．

[code]

    CC := gcc
    
    build:
    ifeq ($(CC),gcc)
        @echo $(CC) is gcc
    else
        @echo $(CC) is not gcc
    endif
    
[/code]

この実行結果は以下の通りです

[code]

    $ make
    gcc is gcc
    
[/code]

ターゲット外でevalを用いて変数を設定した場合も同様です．

[code]

    $(eval CC := gcc)
    
    build:
    ifeq ($(CC),gcc)
        @echo $(CC) is gcc
    else
        @echo $(CC) is not gcc
    endif
    
[/code]

この実行結果は以下の通りです．

[code]

    $ make
    gcc is gcc
    
[/code]

なぜターゲット内外で変数を設定した場合に条件分岐の挙動が異なるのでしょうか．  
また，ターゲット内で変数を設定した場合の条件分岐はどのように実装すればよいのでしょうか．

利用環境:  
GNU Make 4.1  
OS: Ubuntu 16.04.3 LTS


CC BY-SA 3.0
2017-10-21T09:19:18.883
38930
2017-10-21T14:02:35.057
7770
question
makefile
Makefileでターゲット内で設定した変数を用いた条件分岐が意図した動作にならない


make.info に以下のように書いてあります。

[code]

    Conditionals control what 'make' actually "sees" in
    the makefile, so they _cannot_ be used to control recipes at the time of
    execution.
    
[/code]

条件分岐は Makefile を読む時に行われるので、実行時には無理のようです。

代わりに以下の方法でいかがでしょうか。

[code]

    build:
            $(eval CC := gcc)
    
            @if test "$(CC)" = gcc; then echo "$(CC)" is gcc; else echo "$(CC)" is not gcc; fi
    
[/code]


CC BY-SA 3.0
2017-10-21T10:38:46.577
38934
2017-10-21T10:38:46.577
5288
38930
answer


参考までに、GNU make の [if
function](https://www.gnu.org/software/make/manual/html_node/Conditional-
Functions.html) を使う方法もあろうかと思います。

**Makefile**

[code]

    build_with_gcc: CC := gcc
    build_with_gcc: build
    
    build_with_clang: CC := clang
    build_with_clang: build
    
    build:
        @$(if $(CC:gcc=), \
            echo "$(CC) is not gcc", \
            echo "$(CC) is gcc" \
        )
    
[/code]

**実行**

[code]

    $ make build_with_gcc
    gcc is gcc
    
    $ make build_with_clang
    clang is not gcc
    
    $ make build
    cc is not gcc  # `cc' is the default value of $(CC)
    
[/code]


CC BY-SA 3.0
2017-10-21T14:02:35.057
38939
2017-10-21T14:02:35.057
38930
answer