19

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

TEST=ON

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

TEST 変数を何に設定しても、ifeq ステートメントは成功します。いつもTEST PASSEDと表示されます。ここで私が間違っていることを誰かが見ていますか?

編集:

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

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 はデフォルト値が何であれしか認識しません。

4

4 に答える 4

44

makeは、makefile を読み取るときに条件を評価します (ご存知のように、2 つのパスを使用します) 。 Makefile の条件付き部分 を参照してください。これは、警告を使用して簡単に確認できます(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
于 2012-08-16T19:58:02.900 に答える
3

これは、あなたが望むことを行うためのよりクリーンな(とにかくだと思います)方法です:

all:
    $(MAKE) TEST=ON buildbegin

all_debug:
    $(MAKE) TEST=OFF buildbegin

buildbegin:
    @echo $(TEST)
ifeq ($(TEST),ON)
    @echo PASSED
else
    @echo FAILED
endif
于 2012-08-16T21:03:46.750 に答える
2

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

何かのようなもの:

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

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

<...>は、ある種の間接性を示すための単純な規則です。

于 2012-08-24T13:30:02.187 に答える