Pergunta

Eu tenho o seguinte makefile para o meu projeto, e eu gostaria de configurá-lo para a liberação e compilações de depuração. No meu código, eu tenho um monte de macros #ifdef DEBUG no lugar, por isso é simplesmente uma questão de definir esta macro e adicionando as bandeiras -g3 -gdwarf2 para os compiladores. Como posso fazer isso?

$(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

Só para esclarecer, quando eu digo liberação / compilações de depuração, eu quero ser capaz de tipo apenas make e obter uma compilação de lançamento ou make debug e obter uma compilação de depuração, sem comentar manualmente as coisas no makefile.

Foi útil?

Solução

Você pode usar valores de variáveis ??específicas-alvo . Exemplo:

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

Lembre-se de usar $ (CXX) ou $ (CC) em todos os seus comandos de compilação.

Em seguida, 'make debug' terá bandeiras extras, como -DDEBUG e -g onde como 'make' não vai.

Em uma nota lateral, você pode fazer o seu Makefile muito mais concisa como outras mensagens tinha sugerido.

Outras dicas

Se por liberação configure / compilação, você significa que você só precisa de uma configuração por makefile, então é simplesmente uma questão e desacoplamento CC e CFLAGS:

CFLAGS=-DDEBUG
#CFLAGS=-O2 -DNDEBUG
CC=g++ -g3 -gdwarf2 $(CFLAGS)

Dependendo se você pode usar o GNU makefile, você pode usar condicional para tornar este um apreciador pouco, e controlá-lo a partir da linha de comando:

DEBUG ?= 1
ifeq ($(DEBUG), 1)
    CFLAGS =-DDEBUG
else
    CFLAGS=-DNDEBUG
endif

.o: .c
    $(CC) -c $< -o $@ $(CFLAGS)

e, em seguida, use:

make DEBUG=0
make DEBUG=1

Se você precisa controlar ambas as configurações, ao mesmo tempo, eu acho que é melhor ter diretórios construir, e um diretório de compilação / config.

Esta questão tem aparecido muitas vezes na busca de um problema semelhante, então eu sinto uma solução totalmente implementado se justifica. Especialmente desde que eu (e eu assumiria outros) têm lutado montando todas as várias respostas juntos.

Abaixo está uma amostra Makefile que suporta vários tipos de compilação em diretórios separados. A mostras de depuração e libertação exemplo ilustrado constrói.

Apoia ...

  • diretórios do projeto separados para específico constrói
  • fácil selecção de uma compilação de destino padrão
  • alvo de preparação silenciosa para criar os diretórios necessários para a construção do projeto
  • bandeiras de configuração do compilador específico da construção
  • método natural do GNU make de determinar se o projeto requer uma reconstrução
  • regras padrão, em vez das regras de sufixo obsoletos

#
# 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)

Note que você também pode fazer o seu Makefile simples, ao mesmo tempo:

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

Agora você não tem que repetir nomes de arquivos em todo o lugar. Quaisquer arquivos .L serão passados ??através de flex e gcc, todos os arquivos Y. serão passados ??através de bisões e g ++, e quaisquer arquivos .cpp através de apenas g ++.

lista apenas os arquivos .o que você espera acabar com, e fazer vai fazer o trabalho de descobrir que as regras podem satisfazer as necessidades ...

para o registro:

  • $@ O nome do arquivo de destino (aquele antes dos dois pontos)

  • $< O nome do primeiro (ou único) ficheiro pré-requisito (o primeiro após os dois pontos)

  • $^ Os nomes de todos os arquivos de pré-requisitos (espaço)

  • $* O caule (o pouco que combina o curinga % na definição da regra.

Você pode ter uma variável

DEBUG = 0

então você pode usar uma instrução condicional

  ifeq ($(DEBUG),1)

  else

  endif

Completando as respostas de mais cedo ... você precisa referenciar as variáveis ??que definem informação em seus comandos ...

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top