¿Cómo puedo configurar mi archivo MAKE para depurar y publicar versiones?

Resuelto samoz asked hace 15 años • 7 respuestas

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 DEBUGmacros implementadas, por lo que es simplemente una cuestión de configurar esta macro y agregar las -g3 -gdwarf2banderas 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 makey obtener una compilación de lanzamiento o make debuguna compilación de depuración, sin comentar manualmente las cosas en el archivo MAKE.

samoz avatar Jul 03 '09 22:07 samoz
Aceptado

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.

David Lin avatar Jul 03 '2009 17:07 David Lin

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)
ffhaddad avatar Dec 29 '2013 21:12 ffhaddad

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.

David Cournapeau avatar Jul 03 '2009 15:07 David Cournapeau