用于发布和调试目标的Makefile [英] Makefile for release and debug targets

查看:75
本文介绍了用于发布和调试目标的Makefile的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过指定目标而不是变量(例如make debug=1,不是很好)来构建可以同时构建发行版和调试目标的Makefile,我在这里有一个简化的简化示例,它模仿了我正在尝试的目标实现:

I am trying to build a Makefile that can build both release and debug targets by specifying a target rather than a variable (such as make debug=1, not great) I have a condensed simplified example here that emulates what I am trying to achieve:

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,但我不太喜欢它,并认为此实现可能会更好.一种方法是使用特定于目标的变量,但是我不确定在构建调试目标时依赖项还需要更改其名称时如何使用它们.像这样:

This example would have me use make debug=1 but I don't really like it and feel this implementation could be better. One way is to use target specific variables , but I am not entirely sure how to use them when the dependencies also need to change their names when a debug target is built. Something like:

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 > $@

在这里目标可以正常工作,因为在构建debug时不需要构建bin/$(BINARY).bin目标.但是我不确定在构建时如何处理配方中的module_1/$(MODULE_1_BIN).binmodule_2/$(MODULE_2_BIN).bin依赖项debug

Here the target will work alright as the bin/$(BINARY).bin target wont need to be built when debug is being built.But I am not sure how to handle the dependencies module_1/$(MODULE_1_BIN).bin and module_2/$(MODULE_2_BIN).bin in the recipe when building debug

推荐答案

此答案的先前版本尝试使用特定于目标的变量,但它们的使用受到限制,因为它们用于配方中,但在配方中会被忽略关于指定目标和先决条件.

A previous version of this answer tried to use target-specific variables, but they are of limited use, because they are used in recipes, but are ignored when it comes to specifying targets and prerequisites.

隐式规则使用模式,但是使用隐式目标my_binary%捕获my_binarymy_binary_debug均无效,因为模式与空字符串不匹配.

Implicit rules make use of patterns, but capturing both my_binary and my_binary_debug with the implicit target my_binary% doesn’t work, because patterns don’t match the empty string.

但是,在这种情况下,隐式规则会起作用,因为您的所有目标和依赖项都具有公共结尾.bin,该结尾为非空.匹配%的字符串在自动变量$*中可用. 所以这是我的解决方案:

In this case however, implicit rules work, because all your targets and dependencies have the common ending .bin, which is nonempty. The string that matches % is avalaible in the automatic variable $*. So this is my solution:

.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)进行重写,则可以进行更多简化:

If the recipe to build bin/my_binary.bin can be rewritten with all modules one after another and $(FLAG) at the beginning, some more semplifications are possible:

.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

这篇关于用于发布和调试目标的Makefile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆