我的项目有以下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并获得发布构建或进行调试并获得调试构建,而不需要手动注释makefile中的内容。


当前回答

完成前面的答案。你需要引用你在命令中定义的变量info…

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

其他回答

如果通过配置发布/构建,你的意思是每个makefile只需要一个配置,那么这只是一个解耦CC和CFLAGS的问题:

CFLAGS=-DDEBUG
#CFLAGS=-O2 -DNDEBUG
CC=g++ -g3 -gdwarf2 $(CFLAGS)

取决于你是否可以使用gnu makefile,你可以使用conditional来使它更漂亮,并从命令行控制它:

DEBUG ?= 1
ifeq ($(DEBUG), 1)
    CFLAGS =-DDEBUG
else
    CFLAGS=-DNDEBUG
endif

.o: .c
    $(CC) -c $< -o $@ $(CFLAGS)

然后使用:

make DEBUG=0
make DEBUG=1

如果您需要同时控制两个配置,我认为最好有一个构建目录和一个构建目录/ config。

你可以有一个变量

DEBUG = 0

然后你可以使用条件语句

  ifeq ($(DEBUG),1)

  else

  endif

完成前面的答案。你需要引用你在命令中定义的变量info…

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

注意,你也可以让你的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将负责找出哪些规则可以满足需求……

郑重声明:

$@目标文件的名称(冒号之前的那个) $<第一个(或唯一的)先决条件文件的名称(冒号后的第一个文件) $^所有先决条件文件的名称(空格分隔) $*词干(与规则定义中的%通配符匹配的位。

您还可以向Makefile中添加一些简单的内容,例如

ifeq ($(DEBUG),1)
   OPTS = -g
endif

然后编译它进行调试

使调试= 1