Makefile文件发布和调试目标(Makefile for release and debug t

2019-09-28 13:15发布

我试图建立一个可以通过指定一个目标,而不是一个变量(如建立发布和调试目标的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).binmodule_2/$(MODULE_2_BIN).bin建设时,在配方debug

Answer 1:

这个答案的先前版本试图利用特定目标变量,但它们的用途有限,因为它们在配方中使用,但是当涉及到指定的目标和先决条件被忽略。

隐规则使用的模式,但两者拍摄my_binarymy_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


Answer 2:

正如我以前说过,你可以不使用特定目标变量的先决条件为目标,只有在该目标和递归先决条件的食谱。 我认为你能做的最好的,根据你想要的东西,是这样的:

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))))


文章来源: Makefile for release and debug targets