web-dev-qa-db-ja.com

Makefile ifeq:それらはいつ評価されますか?

以下は、正常に動作しないように見える非常に単純なmakefileです。

TEST=ON

buildbegin:
ifeq ($(TEST),ON)        
    @echo TEST PASSED
else
    @echo TEST FAILED
endif

TEST変数を何に設定しても、ifeqステートメントは成功します。私は常にテストに合格しました。誰かが私がここで間違っていることを知っていますか?

編集:

oK。私の例は正確ではありませんでした。私が実際に持っているのはこれです:

Shell = /bin/sh

DEFAULT_TARGS:= all  all_debug  
DEBUG_TARGS:= all_debug
ALL_TARGS:= $(DEFAULT_TARGS) $(DEBUG_TARGS)

.PHONY: $(ALL_TARGS)
.PHONY: buildbegin

$(ALL_TARGS): buildbegin

TEST=ON

$(DEBUG_TARGS): TEST=OFF

buildbegin:
    @echo $(TEST)
ifeq ($(TEST),ON)
    @echo PASSED
else
    @echo FAILED
endif

Make allまたはmake all_debugを実行すると、「PASSED」が出力されます。条件の前に$(TEST)をエコーすると、ルールが変数を変更しているように見えますが、ifeqはデフォルト値が何であるかしか認識しません。

17
kalden

makeは、makefileを読み取るときに条件文を評価します(2つのパスを使用していることがわかっています)。参照: Makefileの条件部分warningを使用してこれを簡単に確認できます(makefileをデバッグするのに適しています)。

buildbegin:
    @echo $(TEST)
$(warning now we reached ifeq TEST=$(TEST))
ifeq ($(TEST),ON)
    @echo PASSED
else
    @echo FAILED
endif

代わりにシェルコマンドを使用し、ルールに含める必要があります。

buildbegin:
      @if [ "$(TEST)" = "ON" ]; then echo "PASSED"; else echo "FAILED"; fi
36
pmod

ここにあなたが望むことをするためのよりきれいな(とにかく、とにかく)方法があります:

all:
    $(MAKE) TEST=ON buildbegin

all_debug:
    $(MAKE) TEST=OFF buildbegin

buildbegin:
    @echo $(TEST)
ifeq ($(TEST),ON)
    @echo PASSED
else
    @echo FAILED
endif
3
twalberg

make変数を使用してシェルコマンドをパラメーター化します。これにより、再帰的なmakeやシェルさえも回避されます(makeはコマンドを直接フォークし、コマンドにシェルのメタ文字(<> "&;などが含まれていない場合はシェルを経由しません))。

何かのようなもの:

result<ON> := PASSED
result<OFF> := FAILED

buildbegin:
    @echo ${result-<${TEST}>}

<...>は、ある種の間接参照を示すための単なる規約です。

1
bobbogo

質問は古いですが、もっと簡単な方法を共有したいと思います。

ターゲットのリストを表す MAKECMDGOALS variableを使用します。

あなたの場合、解決策はおそらく:

buildbegin:
    @echo $(MAKECMDGOALS)
ifeq ($(MAKECMDGOALS),all)
    @echo PASSED
else ifeq ($(MAKECMDGOALS),debug_all)
    @echo FAILED
endif


debug_all: buildbegin

all: buildbegin

使用法: make debug_allまたはmake all

1
nhnghia