以下は、正常に動作しないように見える非常に単純な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はデフォルト値が何であるかしか認識しません。
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
ここにあなたが望むことをするためのよりきれいな(とにかく、とにかく)方法があります:
all:
$(MAKE) TEST=ON buildbegin
all_debug:
$(MAKE) TEST=OFF buildbegin
buildbegin:
@echo $(TEST)
ifeq ($(TEST),ON)
@echo PASSED
else
@echo FAILED
endif
make変数を使用してシェルコマンドをパラメーター化します。これにより、再帰的なmakeやシェルさえも回避されます(makeはコマンドを直接フォークし、コマンドにシェルのメタ文字(<> "&;などが含まれていない場合はシェルを経由しません))。
何かのようなもの:
result<ON> := PASSED
result<OFF> := FAILED
buildbegin:
@echo ${result-<${TEST}>}
<...>
は、ある種の間接参照を示すための単なる規約です。
質問は古いですが、もっと簡単な方法を共有したいと思います。
ターゲットのリストを表す 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