我试图建立一个可以通过指定一个目标,而不是一个变量(如建立发布和调试目标的Makefile的make debug=1
,不是很大),我这里有一个浓缩的简单的例子,它模拟什么,我想实现:
ifdef debug
BINARY=my_binary_debug
MODULE_1_BIN=abc_debug
MODULE_2_BIN=xyz_debug
export DBG=1
else
BINARY=my_binary
MODULE_1_BIN=abc
MODULE_2_BIN=xyz
endif
FLAG=something
.PHONY: all debug clean
all: bin/$(BINARY).bin
bin/$(BINARY).bin: module_1/$(MODULE_1_BIN).bin module_2/$(MODULE_2_BIN).bin
cat module_1/$(MODULE_1_BIN).bin $(FLAG) module_2/$(MODULE_2_BIN).bin > $@
module_1/$(MODULE_1_BIN).bin:
$(MAKE) -C module_1
module_2/$(MODULE_2_BIN).bin:
$(MAKE) -C module_2
clean:
rm bin/*.bin
$(MAKE) -C module_1 clean
$(MAKE) -C module_2 clean
这个例子要我用make debug=1
,但我真的不喜欢它,并认为这实施可能会更好。 一种方式是使用目标特定的变量,但我不完全知道如何使用它们时的依赖关系还需要在调试目标是建立以改变他们的名字。 就像是:
debug: export DBG:=1
debug: bin/$(BINARY)_debug.bin
debug: module_1/$(MODULE_1_BIN)_debug.bin
debug: module_2/$(MODULE_2_BIN)_debug.bin
bin/$(BINARY).bin bin/$(BINARY)_debug.bin: module_1/$(MODULE_1_BIN).bin module_2/$(MODULE_2_BIN).bin
cat module_1/$(MODULE_1_BIN).bin module_2/$(MODULE_2_BIN).bin > $@
这里,目标会好吗工作作为bin/$(BINARY).bin
目标不会需要时建立debug
正在built.But我不知道如何处理依赖性module_1/$(MODULE_1_BIN).bin
和module_2/$(MODULE_2_BIN).bin
建设时,在配方debug
这个答案的先前版本试图利用特定目标变量,但它们的用途有限,因为它们在配方中使用,但是当涉及到指定的目标和先决条件被忽略。
隐规则使用的模式,但两者拍摄my_binary
和my_binary_debug
与隐含的目标my_binary%
是不行的,因为这些模式不匹配空字符串。
然而,在这种情况下,潜规则的工作,因为你的目标和相关性具有共同的结局.bin
,这是空的。 匹配字符串%
是在自动变量avalaible $*
。 所以这是我的解决方案:
.PHONY: all debug clean
FLAG=something
# Maybe still needed by subdirectory makefiles
debug: export DBG:=1
all: bin/my_binary.bin
debug: bin/my_binary_debug.bin
# % will match both ".bin" and "_debug.bin"
# It won’t match the empty string.
bin/my_binary%: module_1/abc% module_2/xyz%
cat module_1/abc$* $(FLAG) module_2/xyz$* > $@
# Maybe, by specifying the target in the sub-make commandline,
# you can get rid of the DBG variable altogether.
module_1/abc%:
$(MAKE) -C module_1 $@
module_2/xyz%:
$(MAKE) -C module_2 $@
clean:
rm bin/*.bin
$(MAKE) -C module_1 clean
$(MAKE) -C module_2 clean
如果配方打造bin/my_binary.bin
可与所有模块一个又一个被改写$(FLAG)
之初,一些semplifications是可能的:
.PHONY: all debug clean
MODULES = module_1/abc module_2/xyz
FLAG = something
# Maybe still needed by subdirectory makefiles
debug: export DBG:=1
all: bin/my_binary.bin
debug: bin/my_binary_debug.bin
bin/my_binary%: $(addsuffix %,$(MODULES))
cat $(FLAG) $^ > $@
module_1/abc%:
$(MAKE) -C module_1 $@
module_2/xyz%:
$(MAKE) -C module_2 $@
clean:
rm bin/*.bin
for m in $(MODULES); do $(MAKE) -C $$(dirname $$m) clean; done
正如我以前说过,你可以不使用特定目标变量的先决条件为目标,只有在该目标和递归先决条件的食谱。 我认为你能做的最好的,根据你想要的东西,是这样的:
RELEASE_SUFFIX:=#
DEBUG_SUFFIX:=_debug
BINARY:=my_binary
MODULE_1_BIN:=abc
MODULE_2_BIN:=xyz
FLAG=-u
.PHONY: all debug
all: bin/$(BINARY).bin
debug: export DBG:=1
debug: BINARY+=$(DEBUG_SUFFIX)
debug: bin/$(BINARY).bin
define rules
bin/$(BINARY)$($(1)): module_1/$(MODULE_1_BIN)$($(1)).bin module_2/$(MODULE_2_BIN)$($(1)).bin
cat $(FLAG) $$^ > $$@
module_1/$(MODULE_1_BIN)$($(1)).bin:
$(MAKE) -C $$(@D)
module_2/$(MODULE_2_BIN)$($(1)).bin:
$(MAKE) -C $$(@D)
endef
$(foreach suffix, RELEASE_SUFFIX DEBUG_SUFFIX, $(eval $(call rules,$(suffix))))