私のプロジェクトには次のメイクファイルがあり、リリースおよびデバッグビルド用に構成したいと思います。私のコードでは、たくさんの#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
を取得し、デバッグファイルを手動でコメントアウトせずに取得できるようにします。
ターゲット固有の変数値 を使用できます。例:
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つの構成のみが必要な場合、それは単に問題であり、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
両方の構成を同時に制御する必要がある場合は、ビルドディレクトリと1つのビルドディレクトリ/ configがある方が良いと思います。
この問題は、同様の問題を検索するときに頻繁に発生するため、完全に実装されたソリューションが必要であると感じています。特に、私(および他の人もそう思います)は、さまざまな答えをすべてつなぎ合わせるのに苦労しています。
以下は、別々のディレクトリで複数のビルドタイプをサポートするサンプル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)
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はどのルールがニーズを満たすことができるかを判断します...
記録のために:
$@
ターゲットファイルの名前(コロンの前のもの)
$<
最初の(または唯一の)前提条件ファイルの名前(コロンの後の最初のファイル)
$^
すべての前提条件ファイルの名前(スペース区切り)
$*
ステム(ルール定義の%
ワイルドカードに一致するビット。
あなたは変数を持つことができます
DEBUG = 0
その後、条件文を使用できます
ifeq ($(DEBUG),1)
else
endif
以前の回答を完了する...コマンドで情報を定義する変数を参照する必要があります...
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