@Override в интерфейсах на самом деле полезны, потому что Вы получите предупреждения при изменении интерфейса.
Вы можете использовать Целевые значения переменных . Пример:
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 намного более кратким, как предлагалось в других сообщениях.
Если при настройке выпуска / сборки вы имеете в виду, что вам нужна только одна конфигурация для каждого make-файла, то это просто вопрос и разделение CC и CFLAGS:
CFLAGS=-DDEBUG
#CFLAGS=-O2 -DNDEBUG
CC=g++ -g3 -gdwarf2 $(CFLAGS)
В зависимости от того, можете ли вы использовать make-файл gnu , вы можете использовать условное выражение, чтобы сделать это немного интереснее, и управлять им из командной строки:
DEBUG ?= 1
ifeq ($(DEBUG), 1)
CFLAGS =-DDEBUG
else
CFLAGS=-DNDEBUG
endif
.o: .c
$(CC) -c $< -o $@ $(CFLAGS)
, а затем использовать:
make DEBUG=0
make DEBUG=1
Если вам нужно управлять обеими конфигурациями одновременно, я думаю, что лучше иметь сборку каталоги и один каталог сборки / config.
Обратите внимание, что вы также можете упростить свой 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