我想做一些我认为在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
这其中有一些明显的问题:我到底做错了什么?
谢谢你的帮助:)
Make首先将所有的makefile解析成一个内部数据结构,然后运行规则。 ifeq
等在第一步就被评估了。 自动变量直到第二步才会被设置。
你不能使用make预处理语句,如 ifeq
,它们被解析为 当makefile被读入查询自动变量,如 $*
,这些都是未设置的 直到菜谱运行.
如果你需要测试每个规则的一些值,你将不得不使用shell条件,就像这样。
$(POSTBUILD_TARGET): postbuild_%:
if [ -z '$(NO_$(subst $(whitespace),.,$(wordlist 2,4,$(subst ., ,$*))))' ]; then \
[...]; \
else \
@echo Skipping $@; \
fi