Makefile ifeq:它们何时被评估?

时间:2012-08-16 19:20:17

标签: makefile gnu-make

以下是一个非常简单的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 个答案:

答案 0 :(得分:32)

make 在读取makefile时评估条件(如您所知,它使用2次传递),请参阅:Conditional Parts of Makefiles。您可以使用警告(这是调试makefile的好事)来检查这一点:

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

您应该使用shell命令,并将它们包含在规则中:

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

答案 1 :(得分:3)

这是一个更干净的(我想,无论如何)做你想要的方式:

all:
    $(MAKE) TEST=ON buildbegin

all_debug:
    $(MAKE) TEST=OFF buildbegin

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

答案 2 :(得分:1)

使用 make 变量参数化shell命令。这避免了递归make甚至是shell(如果命令不包含shell元字符(<>“&amp ;;等等),make将直接分叉命令而不是通过shell)。

类似的东西:

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

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

<...>只是表示某种间接的惯例。

答案 3 :(得分:0)

虽然这个问题很老,但我想分享一种更简单的方法。

使用代表目标列表的MAKECMDGOALS变量。

在您的情况下,解决方案可能是:

@Override
    public <T> T insert(T objectToInsert, WritePolicy policy) {
        Assert.notNull(objectToInsert, "Object to insert must not be null!");
        try {
            AerospikeData data = AerospikeData.forWrite(this.namespace);
            converter.write(objectToInsert, data);
            Key key = data.getKey();
            Bin[] bins = data.getBinsAsArray();
            client.put(policy == null ? this.insertPolicy : policy, key, bins);
        }
        catch (AerospikeException o_O) {
            DataAccessException translatedException = exceptionTranslator
                    .translateExceptionIfPossible(o_O);
            throw translatedException == null ? o_O : translatedException;
        }
        return null;
    }

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