¿Cómo puedo configurar mi archivo MAKE para depurar y publicar versiones?
Tengo el siguiente archivo MAKE para mi proyecto y me gustaría configurarlo para versiones de lanzamiento y depuración. En mi código, tengo muchas #ifdef DEBUG
macros implementadas, por lo que es simplemente una cuestión de configurar esta macro y agregar las -g3 -gdwarf2
banderas a los compiladores. ¿Cómo puedo hacer esto?
$(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
Solo para aclarar, cuando digo compilaciones de lanzamiento/depuración, quiero poder simplemente escribir make
y obtener una compilación de lanzamiento o make debug
una compilación de depuración, sin comentar manualmente las cosas en el archivo MAKE.
Puede utilizar valores de variables específicos de destino . Ejemplo:
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
Recuerde usar $(CXX) o $(CC) en todos sus comandos de compilación.
Entonces, 'make debug' tendrá indicadores adicionales como -DDEBUG y -g, mientras que 'make' no los tendrá.
Como nota al margen, puedes hacer que tu Makefile sea mucho más conciso como lo sugirieron otras publicaciones.
Esta pregunta ha aparecido a menudo al buscar un problema similar, por lo que creo que se justifica una solución completamente implementada. Especialmente porque a mí (y supongo que a otros) nos ha costado unir todas las respuestas.
A continuación se muestra un Makefile de muestra que admite múltiples tipos de compilación en directorios separados. El ejemplo ilustrado muestra compilaciones de depuración y lanzamiento.
Soporta...
- directorios de proyectos separados para compilaciones específicas
- fácil selección de una compilación de destino predeterminada
- objetivo de preparación silenciosa para crear los directorios necesarios para construir el proyecto
- indicadores de configuración del compilador específicos de compilación
- El método natural de GNU Make para determinar si el proyecto requiere una reconstrucción
- reglas de patrón en lugar de las obsoletas reglas de sufijo
#
# 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)
Si por configurar lanzamiento/compilación quiere decir que solo necesita una configuración por archivo MAKE, entonces es simplemente una cuestión de desacoplar CC y CFLAGS:
CFLAGS=-DDEBUG
#CFLAGS=-O2 -DNDEBUG
CC=g++ -g3 -gdwarf2 $(CFLAGS)
Dependiendo de si puedes usar gnu makefile, puedes usar condicional para hacerlo un poco más elegante y controlarlo desde la línea de comando:
DEBUG ?= 1
ifeq ($(DEBUG), 1)
CFLAGS =-DDEBUG
else
CFLAGS=-DNDEBUG
endif
.o: .c
$(CC) -c $< -o $@ $(CFLAGS)
y luego usar:
make DEBUG=0
make DEBUG=1
Si necesita controlar ambas configuraciones al mismo tiempo, creo que es mejor tener directorios de compilación y un directorio de compilación/config.