如何实现依赖于调用或不调用其他makefile目标的makefile目标

时间:2017-11-20 01:02:34

标签: bash unix makefile

我的原始用例相当复杂,但可以提炼为以下内容:

a:
    export AAA=true

b:
    echo ${AAA}
ifdef AAA 
    echo "AAA mode is on."
else
    echo "AAA mode is off."
endif

我想要实现的是条件b目标取决于是否调用a

然而,行为不直观,而AAA=true make b确实有效make a b无效(我更喜欢后者)。

任何有用的建议将不胜感激!

4 个答案:

答案 0 :(得分:2)

如果您愿意将自己限制为GNU make,则可以使用eval功能。我一般认为这不是一个好主意,我同意Beta,这可能是一个XY问题,但是:

AAA = false

a:
        $(eval AAA = true)

b:
        echo ${AAA}

请注意,你肯定不能使用make预处理器语句,如ifeqifdef:那些在解析makefile时被评估,甚至是那些包含在配方中,显然在调用任何可能设置AAA等的配方之前就会发生这种情况。

ETA:

以上是上述makefile的示例,以显示它的工作原理:

$ make b
false

$ make b a
false

$ make a b
true

如其他地方的评论中所述,AAA的值已在b IFF 的配方中重置a的配方已被调用。这就是我解释你的请求的方式我想要实现的目标是条件b目标取决于是否调用a ,但也许你有不同的行为

答案 1 :(得分:2)

好吧,我试图玩evals(没有工作)和文件标记(不理想,因为我有makefile的层次结构,其中一些调用了两次因此$(shell rm -f .target-marker)多次调用)和我想想我的用例,最好是探索当前引用的目标:

a:
    #market target

b:
    @if [[ "${MAKECMDGOALS}" = a* ]]; then \
        echo "AAA mode is on"; \
    else \
        echo "AAA mode is off"; \
    fi; 

MAKECMDGOALS包含所有目标,我只是可以检查某个目标是否在列表中。

答案 2 :(得分:1)

您不能将一个shell的环境暴露给另一个shell,但您可以使用标记文件。

# Kludge: Force removal when make starts
$(shell rm -f .done-a)

a:
    : things
    touch .done-a

b:
    if [ -e .done-a ]; then : stuff ...;  \
    else : other stuff ...; \
    fi

答案 3 :(得分:1)

主题的两个变体,只有一个定义。正如@tripleee所说,你不能传递externs,但你可以在makefile中有一个共同的定义。我还尽可能避免空shell变量。在这种情况下,可以使用直线向上的真/假值。

#last definition "wins"
AAA=false
AAA=true

a:
    export AAA=$(AAA)

b:
    export AAA=$(AAA)
    echo $${AAA};        #note double dollar within shell commands
    $$AAA && echo "AAA mode is on." || echo "AAA mode is off."

nested_c:
    $(MAKE) AAA=$(AAA) c