【问题标题】:Using GNU Make to build both debug and release targets at the same time (Extended)使用 GNU Make 同时构建调试和发布目标(扩展)
【发布时间】:2016-01-03 05:22:51
【问题描述】:

我想跟进this question and its answers... 现在我可以构建两个不同的可执行文件,我想根据变量在不同的目录中构建可执行文件。

我想从这样的地方出发:

EXEDIR     = bin/release/
EXE        = $(EXEDIR)AmiModRadio
SOURCES    = $(wildcard *.c)
OBJECTSDIR = o/release/
OBJECTS    = $(addprefix $(OBJECTSDIR), $(SOURCES:.c=.o))

CC = vbcc:bin/vc
LD = vbcc:bin/vc

release : $(EXE) 
$(OBJECTS) : $(OBJECTSDIR)%.o : %.c
    $(CC) $(shell vbccprefs) -c $< -o $@
$(EXE) : $(OBJECTS)
    $(LD) $(shell vbccprefs) -o $(EXE) $(OBJECTS)

类似于:

EXE        = $(EXEDIR)AmiModRadio
SOURCES    = $(wildcard *.c)
OBJECTS    = $(addprefix $(OBJECTSDIR), $(SOURCES:.c=.o))

CC = vbcc:bin/vc
LD = vbcc:bin/vc

release : EXEDIR = bin/release/
release : OBJECTSDIR = o/release/
release : $(EXE) 

release : EXEDIR = bin/debug/
release : OBJECTSDIR = o/debug/
release : $(EXE) 

$(OBJECTS) : $(OBJECTSDIR)%.o : %.c
    $(CC) $(shell vbccprefs) -c $< -o $@
$(EXE) : $(OBJECTS)
    $(LD) $(shell vbccprefs) -o $(EXE) $(OBJECTS)

上面的最后一个makefile不起作用,因为据我了解,在规则releasedebug中设置变量EXEDIROBJECTSDIR为时已晚。

那么,我在这里遗漏了一些简单的东西吗?有没有办法让releasedebug 这两条规则使用相同的规则,但在两组不同的目录中生成文件,包括作为主要目标的可执行文件?

【问题讨论】:

    标签: c gcc makefile gnu-make


    【解决方案1】:

    您可以调用以下 Makefile:

    make release
    make debug
    

    -- 或者--

    make BUILD=release
    make BUILD=debug
    

    生成文件

    ifneq ($(BUILD),release)
        BUILD = debug
    endif
    
    EXEDIR      = bin/$(BUILD)/
    OBJDIR      = o/$(BUILD)/
    
    EXE         = $(EXEDIR)AmiModRadio
    SOURCES     = $(wildcard *.c)
    OBJECTS     = $(addprefix $(OBJDIR), $(SOURCES:.c=.o))
    
    CC = vbcc:bin/vc
    LD = vbcc:bin/vc
    
    CFLAGS  = $(shell vbccprefs)
    LDFLAGS = $(shell vbccprefs)
    
    all : $(EXE)
    
    .PHONY : release debug    
    release debug :
        $(MAKE) BUILD=$@
    
    $(EXE) : $(OBJECTS)
        $(LD) $(LDFLAGS) -o $@ $^
    
    $(OBJDIR)%.o : %.c
        $(CC) $(CFLAGS) -o $@ -c $<
    

    【讨论】:

    • 谢谢 Ziffusion,在您的帮助和 Daniels 下面的帮助下,我设法让我的 makefile 完全按照我的意愿工作。我接受丹尼尔的回答,因为它不需要“BUILD=”(在执行make releasemake debug 时,$(BUILD) 为空)
    • 没关系。但请注意,Makefile 不需要传入 `BUILD='。我的第一个解决方案是,但我改变了它。无论如何,了解这两种方法是件好事。
    【解决方案2】:

    我会使用条件来确定目标是什么并相应地设置变量。

    ifeq "$(strip $(filter debug,$(MAKECMDGOALS)))" "debug"
    EXEDIR = bin/release/
    OBJECTSDIR = o/release/
    endif
    ifeq "$(strip $(filter release,$(MAKECMDGOALS)))" "release"
    EXEDIR = bin/debug/
    OBJECTSDIR = o/debug/
    endif
    

    我在您的代码中看到的一个大问题是您在发布和调试路径上都指定了发布目标。所以 GNU Make 使用它遇到的最后一个赋值。但是,使用我在这里的东西应该可以工作,因为我对我的 make 文件做类似的事情。

    这样做时,您不能同时在命令行上指定发布和调试,因为它们是互斥的。 strip 函数从参数中去除前导和尾随空格,这是过滤器函数的输出。 filter 函数接受字符串 debug 并在预定义变量 MAKECMDGOALS 中查找它。 MAKECMDGOALS 是在命令行中指定的所有目标(目标)的列表。

    希望这会有所帮助。

    【讨论】:

    • 感谢 Daniel 的帮助,在您的帮助和 Ziffusion 的帮助下,我的 makefile 可以正常工作,并且对我的构建链的改动很小
    猜你喜欢
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-01
    • 1970-01-01
    • 2010-12-17
    • 2013-10-05
    • 2020-11-17
    相关资源
    最近更新 更多