Jak mogę skonfigurować plik makefile dla wersji debugowania i Wydania?
Mam następujący plik makefile dla mojego projektu i chciałbym go skonfigurować do wydania i debugowania kompilacji. W kodzie mam mnóstwo makr #ifdef DEBUG
, więc jest to po prostu kwestia ustawienia tego makra i dodania Flag -g3 -gdwarf2
do kompilatorów. Jak mogę to zrobić?
$(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
Dla jasności, kiedy mówię release / debug builds, chcę być w stanie po prostu wpisać make
i uzyskać release build lub make debug
i uzyskać debug build, bez ręcznego komentowania rzeczy w pliku makefile.
6 answers
Możesz użyć wartości zmiennych specyficznych dla Celu . Przykład:
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
Pamiętaj, aby używać $(CXX) lub $(CC) we wszystkich komend kompilacji.
Wtedy 'make debug' będzie miał dodatkowe flagi, takie jak-DDEBUG i-g, gdzie jako 'make' nie będzie.
Na marginesie, możesz uczynić swój plik Makefile o wiele bardziej zwięzłym, jak sugerowały inne posty.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-15 05:26:40
Jeśli przez configure release / build masz na myśli tylko jedną konfigurację na makefile, to jest to po prostu sprawa i oddzielenie CC i CFLAGS:
CFLAGS=-DDEBUG
#CFLAGS=-O2 -DNDEBUG
CC=g++ -g3 -gdwarf2 $(CFLAGS)
W zależności od tego, czy możesz użyć gnu makefile, możesz użyć warunkowego, aby uczynić to nieco bardziej fantazyjnym i sterować nim z linii poleceń:
DEBUG ?= 1
ifeq ($(DEBUG), 1)
CFLAGS =-DDEBUG
else
CFLAGS=-DNDEBUG
endif
.o: .c
$(CC) -c $< -o $@ $(CFLAGS)
A następnie użyj:
make DEBUG=0
make DEBUG=1
Jeśli chcesz kontrolować obie konfiguracje jednocześnie, myślę, że lepiej mieć katalogi build i jeden katalog build / config.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-30 15:06:03
To pytanie pojawiało się często podczas poszukiwania podobnego problemu, więc uważam, że w pełni wdrożone rozwiązanie jest uzasadnione. Zwłaszcza, że ja (i zakładam, że inni) walczyłem składając wszystkie różne odpowiedzi razem.
Poniżej znajduje się przykładowy plik Makefile, który obsługuje wiele typów kompilacji w oddzielnych katalogach. Ilustrowany przykład pokazuje Debug i release builds.
Podpory ...
- oddzielne katalogi projektów dla konkretnych budów
- easy wybór domyślnej budowy celu
- silent Prep cel do tworzenia katalogów potrzebnych do budowy projektu
- flagi konfiguracji kompilatora specyficzne dla kompilatora
- naturalna metoda GNU Make określająca, czy projekt wymaga przebudowy
- reguły wzorca zamiast przestarzałych reguł sufiksu
#
# 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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-29 22:14:36
Zauważ, że możesz również uprościć swój Makefile, w tym samym czasie:
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
Teraz nie musisz powtarzać nazw plików w każdym miejscu. Każdy .pliki l będą przekazywane przez flex i gcc, dowolne .pliki y będą przekazywane przez bison i g++ i dowolne .pliki cpp poprzez g++.
Po prostu wymień .o pliki, które spodziewasz się skończyć z, I Make zrobi pracę zastanawiając się, które zasady mogą zaspokoić potrzeby...
Dla przypomnienia:
-
$@
Na nazwa pliku docelowego (tego przed dwukropkiem) -
$<
Nazwa pierwszego (lub jedynego) pliku warunkowego (pierwszego po dwukropku) -
$^
nazwy wszystkich plików warunkowych (rozdzielone spacjami) $*
Rdzeń (bit, który pasuje do symbolu%
w definicji reguły.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-05 23:49:21
Możesz mieć zmienną
DEBUG = 0
Wtedy możesz użyć instrukcji warunkowej
ifeq ($(DEBUG),1)
else
endif
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-03 15:54:42
Uzupełnianie odpowiedzi z wcześniejszych... Musisz odwoływać się do zmiennych, które definiujesz w poleceniach...
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-03 16:05:01