Makefile、ifdef和计算变量。

问题描述 投票:0回答:1

我想做一些我认为在make中不可能实现的东西,我有一个普通的目标,它可以有几个先决条件,比如这个例子中的postbuild_%。

TARGET_NAMES = release.target.1.1 debug.target.1.1 release.target.2.4 debug.target.2.4
BUILD_TARGET := $(addprefix build_,$(TARGET_NAMES))    
.PHONY: $(BUILD_TARGET)
$(BUILD_TARGET): build_%: prebuild_% % postbuild_%

我为每个目标定义了一个变量(由另一个makefile导出,该makefile调用带有规则的变量)来决定编译的某种行为。由于每个目标的名字都是不同的(除了releaseebug这个东西),我为每个目标使用了不同的变量。例如

.PHONY: %.target.1.1
%.target.1.1:
ifndef NO_target.1.1
    [something specific for %.target.1.1]
else
    @echo nothing to do
endif

现在我的问题是,即使是在postbuild_%中,我也必须复制这个东西,但每个目标的配方总是一样的,所以我试图找到一种方法来使用计算变量来重新创建 "NO_$*"变量,以避免复制整个配方,就像这样。

POSTBUILD_TARGET := $(addprefix postbuild_,$(TARGET_NAMES))
.PHONY: $(POSTBUILD_TARGET)
$(POSTBUILD_TARGET): postbuild_%:
ifndef $(addprefix NO_,$(subst $(whitespace),.,$(wordlist 2,4,$(subst ., ,$*))))
    [...]
else
    @echo Skipping $@
endif

这其中有一些明显的问题:我到底做错了什么?

谢谢你的帮助:)

makefile gnu-make
1个回答
1
投票

Make首先将所有的makefile解析成一个内部数据结构,然后运行规则。 ifeq 等在第一步就被评估了。 自动变量直到第二步才会被设置。

你不能使用make预处理语句,如 ifeq,它们被解析为 当makefile被读入查询自动变量,如 $*,这些都是未设置的 直到菜谱运行.

如果你需要测试每个规则的一些值,你将不得不使用shell条件,就像这样。

$(POSTBUILD_TARGET): postbuild_%:
        if [ -z '$(NO_$(subst $(whitespace),.,$(wordlist 2,4,$(subst ., ,$*))))' ]; then \
            [...]; \
        else \
            @echo Skipping $@; \
        fi
© www.soinside.com 2019 - 2024. All rights reserved.