196

プロジェクト用に次のメイクファイルがあり、リリースおよびデバッグ ビルド用に構成したいと考えています。私のコードには多くの#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

4

7 に答える 7

214

ターゲット固有の変数値を使用できます。例:

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 をより簡潔にすることができます。

于 2009-07-03T17:07:52.857 に答える
43

リリース/ビルドを構成することによって、メイクファイルごとに構成が 1 つだけ必要な場合は、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.

于 2009-07-03T15:28:33.200 に答える
26

同時に、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 はどのルールがニーズを満たすことができるかを判断する作業を行います...

記録のために:

  • $@ターゲット ファイルの名前 (コロンの前のファイル)

  • $<最初の (または唯一の) 前提条件ファイルの名前 (コロンの後の最初のファイル)

  • $^すべての前提条件ファイルの名前 (スペース区切り)

  • $*ステム (%ルール定義のワイルドカードに一致するビット。

于 2009-07-03T16:18:07.530 に答える
3

変数を持つことができます

DEBUG = 0

次に、条件文を使用できます

  ifeq ($(DEBUG),1)

  else

  endif
于 2009-07-03T15:46:21.503 に答える
2

以前の回答を完成させています...コマンドで情報を定義する変数を参照する必要があります...

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
于 2009-07-03T15:59:06.230 に答える