C 使用GNU Make同时构建调试和发布目标(扩展)

C 使用GNU Make同时构建调试和发布目标(扩展),c,gcc,makefile,gnu-make,C,Gcc,Makefile,Gnu Make,我想跟进。。。现在我可以构建两个不同的可执行文件了,我希望根据变量在不同的目录中构建可执行文件 我想从以下几点开始: EXEDIR = bin/release/ EXE = $(EXEDIR)AmiModRadio SOURCES = $(wildcard *.c) OBJECTSDIR = o/release/ OBJECTS = $(addprefix $(OBJECTSDIR), $(SOURCES:.c=.o)) CC = vbcc:bin/vc LD

我想跟进。。。现在我可以构建两个不同的可执行文件了,我希望根据变量在不同的目录中构建可执行文件

我想从以下几点开始:

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)
EXEDIR=bin/release/
EXE=$(EXEDIR)AmiModRadio
SOURCES=$(通配符*.c)
OBJECTSDIR=o/release/
OBJECTS=$(addprefix$(OBJECTSDIR),$(源:.c=.o))
CC=vbcc:bin/vc
LD=vbcc:bin/vc
发布:$(EXE)
$(对象):$(OBJECTSDIR)%.o:%.c
$(CC)$(shell vbccprefs)-c$<-o$@
$(EXE):$(对象)
$(LD)$(shell vbccprefs)-o$(EXE)$(对象)
例如:

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)
EXE=$(EXEDIR)AmiModRadio
SOURCES=$(通配符*.c)
OBJECTS=$(addprefix$(OBJECTSDIR),$(源:.c=.o))
CC=vbcc:bin/vc
LD=vbcc:bin/vc
释放:EXEDIR=bin/release/
发布:OBJECTSDIR=o/release/
发布:$(EXE)
发布:EXEDIR=bin/debug/
发布:OBJECTSDIR=o/debug/
发布:$(EXE)
$(对象):$(OBJECTSDIR)%.o:%.c
$(CC)$(shell vbccprefs)-c$<-o$@
$(EXE):$(对象)
$(LD)$(shell vbccprefs)-o$(EXE)$(对象)
上面的最后一个makefile不起作用,因为据我所知,在规则
release
debug
中设置变量
EXEDIR
OBJECTSDIR
太迟了


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

您可以调用以下Makefile:

make release
make debug
--或--

Makefile

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 $<
ifneq($(构建),发布)
构建=调试
恩迪夫
EXEDIR=bin/$(内部版本)/
OBJDIR=o/$(构建)/
EXE=$(EXEDIR)AmiModRadio
SOURCES=$(通配符*.c)
OBJECTS=$(addprefix$(OBJDIR),$(源代码:.c=.o))
CC=vbcc:bin/vc
LD=vbcc:bin/vc
CFLAGS=$(shell vbccprefs)
LDFLAGS=$(shell vbccprefs)
全部:$(EXE)
.PHONY:发布调试
发布调试:
$(制作)构建=$@
$(EXE):$(对象)
$(LD)$(LDFLAGS)-o$@$^
$(OBJDIR)%.o:%.c
$(CC)$(CFLAGS)-o$@-c$<

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

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
我在代码中看到的一个大问题是,您在发布和调试路径上都指定了发布目标。因此,gnumake使用它遇到的最后一个赋值。但是,使用我在这里拥有的应该可以工作,因为我对make文件做了类似的事情

在执行此操作时,不能同时在命令行上指定release和debug,因为它们是互斥的。strip函数从参数中去掉前导和尾随空格,这是filter函数的输出。filter函数接受字符串debug并在预定义变量MAKECMDGOALS中查找它。MAKECMDGOALS是在命令行上指定的所有目标的列表


希望这能有所帮助。

谢谢Ziffusion,在您的帮助和下面的Daniels的帮助下,我成功地使我的makefile完全按照我的意愿工作。我接受Daniel的回答,因为它不需要“BUILD=”(在执行
makerelease
makedebug
时,$(BUILD)是空的),这很好。但是请注意,
Makefile
不需要传入'BUILD='。我的第一个解决方案成功了,但我改变了它。在任何情况下,了解这两种方法都是很好的。谢谢Daniel的帮助,在您和Ziffusion的帮助下,我的makefile工作正常,并且对构建链的更改很少