我的项目有以下makefile,我想为发布和调试版本配置它。在我的代码中,我有很多#ifdef DEBUG
个宏,所以只需要设置这个宏并将-g3 -gdwarf2
标志添加到编译器中。我怎么能这样做?
$(CC) = g++ -g3 -gdwarf2
$(cc) = gcc -g3 -gdwarf2
all: executable
executable: CommandParser.tab.o CommandParser.yy.o Command.o
g++ -g -o output CommandParser.yy.o CommandParser.tab.o Command.o -lfl
CommandParser.yy.o: CommandParser.l
flex -o CommandParser.yy.c CommandParser.l
gcc -g -c CommandParser.yy.c
CommandParser.tab.o: CommandParser.y
bison -d CommandParser.y
g++ -g -c CommandParser.tab.c
Command.o: Command.cpp
g++ -g -c Command.cpp
clean:
rm -f CommandParser.tab.* CommandParser.yy.* output *.o
只是澄清一下,当我说发布/调试版本时,我希望能够只输入make
并获得发布版本或make debug
并获得调试版本,而无需手动注释掉事物在makefile中。
答案 0 :(得分:174)
您可以使用Target-specific Variable Values。例如:
CXXFLAGS = -g3 -gdwarf2
CCFLAGS = -g3 -gdwarf2
all: executable
debug: CXXFLAGS += -DDEBUG -g
debug: CCFLAGS += -DDEBUG -g
debug: executable
executable: CommandParser.tab.o CommandParser.yy.o Command.o
$(CXX) -o output CommandParser.yy.o CommandParser.tab.o Command.o -lfl
CommandParser.yy.o: CommandParser.l
flex -o CommandParser.yy.c CommandParser.l
$(CC) -c CommandParser.yy.c
请记住在所有编译命令中使用$(CXX)或$(CC)。
然后,'make debug'将有额外的标志,如-DDEBUG和-g,其中'make'不会。
另外,您可以像其他帖子建议的那样使您的Makefile更加简洁。
答案 1 :(得分:39)
如果通过configure release / build,你的意思是你只需要为每个makefile配置一个配置,那么它只是一个问题,并且解耦CC和CFLAGS:
CFLAGS=-DDEBUG
#CFLAGS=-O2 -DNDEBUG
CC=g++ -g3 -gdwarf2 $(CFLAGS)
根据您是否可以使用gnu makefile,您可以使用条件使其有点发烧,并从命令行控制它:
DEBUG ?= 1
ifeq ($(DEBUG), 1)
CFLAGS =-DDEBUG
else
CFLAGS=-DNDEBUG
endif
.o: .c
$(CC) -c $< -o $@ $(CFLAGS)
然后使用:
make DEBUG=0
make DEBUG=1
如果你需要同时控制两个配置,我认为最好有构建目录和一个构建目录/ config。
答案 2 :(得分:36)
在搜索类似问题时经常出现这个问题,所以我觉得有充分实施的解决方案是合理的。特别是因为我(我会假设其他人)一直在努力拼凑所有各种答案。
下面是一个示例Makefile,它在不同的目录中支持多种构建类型。图示的示例显示了调试和发布版本。
支持......
#
# Compiler flags
#
CC = gcc
CFLAGS = -Wall -Werror -Wextra
#
# Project files
#
SRCS = file1.c file2.c file3.c file4.c
OBJS = $(SRCS:.c=.o)
EXE = exefile
#
# Debug build settings
#
DBGDIR = debug
DBGEXE = $(DBGDIR)/$(EXE)
DBGOBJS = $(addprefix $(DBGDIR)/, $(OBJS))
DBGCFLAGS = -g -O0 -DDEBUG
#
# Release build settings
#
RELDIR = release
RELEXE = $(RELDIR)/$(EXE)
RELOBJS = $(addprefix $(RELDIR)/, $(OBJS))
RELCFLAGS = -O3 -DNDEBUG
.PHONY: all clean debug prep release remake
# Default build
all: prep release
#
# Debug rules
#
debug: $(DBGEXE)
$(DBGEXE): $(DBGOBJS)
$(CC) $(CFLAGS) $(DBGCFLAGS) -o $(DBGEXE) $^
$(DBGDIR)/%.o: %.c
$(CC) -c $(CFLAGS) $(DBGCFLAGS) -o $@ $<
#
# Release rules
#
release: $(RELEXE)
$(RELEXE): $(RELOBJS)
$(CC) $(CFLAGS) $(RELCFLAGS) -o $(RELEXE) $^
$(RELDIR)/%.o: %.c
$(CC) -c $(CFLAGS) $(RELCFLAGS) -o $@ $<
#
# Other rules
#
prep:
@mkdir -p $(DBGDIR) $(RELDIR)
remake: clean all
clean:
rm -f $(RELEXE) $(RELOBJS) $(DBGEXE) $(DBGOBJS)
答案 3 :(得分:23)
请注意,您还可以同时使Makefile更简单:
DEBUG ?= 1
ifeq (DEBUG, 1)
CFLAGS =-g3 -gdwarf2 -DDEBUG
else
CFLAGS=-DNDEBUG
endif
CXX = g++ $(CFLAGS)
CC = gcc $(CFLAGS)
EXECUTABLE = output
OBJECTS = CommandParser.tab.o CommandParser.yy.o Command.o
LIBRARIES = -lfl
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CXX) -o $@ $^ $(LIBRARIES)
%.yy.o: %.l
flex -o $*.yy.c $<
$(CC) -c $*.yy.c
%.tab.o: %.y
bison -d $<
$(CXX) -c $*.tab.c
%.o: %.cpp
$(CXX) -c $<
clean:
rm -f $(EXECUTABLE) $(OBJECTS) *.yy.c *.tab.c
现在您不必在整个地方重复文件名。任何.l文件都将通过flex和gcc传递,任何.y文件都将通过bison和g ++以及任何.cpp文件通过g ++传递。
只需列出您希望最终得到的.o文件,Make将负责确定哪些规则可以满足需求......
记录:
$@
目标文件的名称(冒号前的那个)
$<
第一个(或唯一的)先决条件文件的名称(冒号后的第一个)
$^
所有必备文件的名称(空格分隔)
$*
词干(与规则定义中的%
通配符匹配的位。
答案 4 :(得分:3)
你可以有一个变量
DEBUG = 0
然后你可以使用条件语句
ifeq ($(DEBUG),1)
else
endif
答案 5 :(得分:1)
完成之前的答案...您需要在命令中引用您定义信息的变量......
DEBUG ?= 1
ifeq (DEBUG, 1)
CFLAGS =-g3 -gdwarf2 -DDEBUG
else
CFLAGS=-DNDEBUG
endif
CXX = g++ $(CFLAGS)
CC = gcc $(CFLAGS)
all: executable
executable: CommandParser.tab.o CommandParser.yy.o Command.o
$(CXX) -o output CommandParser.yy.o CommandParser.tab.o Command.o -lfl
CommandParser.yy.o: CommandParser.l
flex -o CommandParser.yy.c CommandParser.l
$(CC) -c CommandParser.yy.c
CommandParser.tab.o: CommandParser.y
bison -d CommandParser.y
$(CXX) -c CommandParser.tab.c
Command.o: Command.cpp
$(CXX) -c Command.cpp
clean:
rm -f CommandParser.tab.* CommandParser.yy.* output *.o
答案 6 :(得分:0)
您还可以在Makefile中添加一些简单的内容,例如
ifeq ($(DEBUG),1)
OPTS = -g
endif
然后将其编译以进行调试
make DEBUG=1