Подтвердить что ты не робот

Использование GNU Make для одновременного создания целей отладки и выпуска

Я работаю над проектом среднего размера, который содержит несколько библиотек с взаимозависимостью, которые я недавно переделал для создания с использованием нерекурсивного make файла. Моя следующая цель - обеспечить одновременное создание как отладочных, так и релизных сборок из одного и того же исходного дерева (сделать debug; make release). Мой первый шаг состоял в том, чтобы отлаживать и выпускать цели, содержащие правильные флаги сборки. Я сделал это с использованием целевых переменных, например:   CXXFLAGS = -Wall -Wextra -Werror -DLINUX

CXX_DEBUG_FLAGS=-g3 -DDEBUG_ALL
CXX_RELEASE_FLAGS=-O3

.PHONY: debug 
debug: CXXFLAGS+=$(CXX_DEBUG_FLAGS) 
debug: build

.PHONY: release 
release: CXXFLAGS+=$(CXX_RELEASE_FLAGS) 
release: build

Это сработало хорошо, но вы можете создавать debug или release, а не одновременно. И к тому же, я не имею в виду, что во время одной и той же сборки я подразумеваю "спина к спине" в том же исходном дереве (make debug; make release). Для этого мне нужно разместить объектные файлы в специальном каталоге отладки/выпуска, чтобы они не перезаписывали друг друга, и мне нужно отменить целевое двоичное имя отладки с помощью "D". Я, хотя это было бы легко, поскольку я мог бы просто использовать целевые переменные снова, например:   CXXFLAGS = -Wall -Wextra -Werror -DLINUX

CXX_DEBUG_FLAGS=-g3 -DDEBUG_ALL
CXX_RELEASE_FLAGS=-O3

.PHONY: debug 
debug: CXXFLAGS+=$(CXX_DEBUG_FLAGS) 
debug: MODULE_BLD_TYPE=D
debug: OUT_DIR=debug_obj
debug: build

.PHONY: release 
release: CXXFLAGS+=$(CXX_RELEASE_FLAGS) 
release: MODULE_BLD_TYPE:=
release: OUT_DIR=release_obj
release: build

.PHONY: build
build: TARGET_NAME=HelloWorld$(MODULE_BLD_TYPE)
build: TARGET_BUILD_DIR=$(PROJECT_ROOT_DIR)/$(OUT_DIR)
build: TARGET_BUILD_OBJS=$(addprefix $(TARGET_BUILD_DIR)/,$(SOURCES:.cpp=.o))
build: $(TARGET_NAME)

Вы делаете экспертов, читающих это уже знаете, это не сработает, потому что вы не можете использовать целевые переменные для создания реальных целей. Они отлично работали для моего CXXFLAGS var, потому что переменная не использовалась в целевом имени.

Существует ли шаблон дизайна или наилучшая практика управления сборками debug/release с использованием нерекурсивных make файлов? Конкретно, как мне создать путь к каталогу объектного файла и целевое имя (построить цель на основе цели)?

4b9b3361

Ответ 1

Одной из наиболее постоянных проблем с Make является его неспособность обрабатывать более одного шаблона за раз. Не существует действительно чистого способа делать то, что вы просите (не прибегая к рекурсии, и я не думаю, что это действительно так плохо). Вот разумный подход:

CXXFLAGS=-Wall -Wextra -Werror -DLINUX
CXX_DEBUG_FLAGS=-g3 -DDEBUG_ALL 
CXX_RELEASE_FLAGS=-O3 

.PHONY: debug  
debug: CXXFLAGS+=$(CXX_DEBUG_FLAGS)  
debug: HelloWorldD

.PHONY: release  
release: CXXFLAGS+=$(CXX_RELEASE_FLAGS)
release: HelloWorld

DEBUG_OBJECTS = $(addprefix $(PROJECT_ROOT_DIR)/debug_obj/,$(SOURCES:.cpp=.o))
RELEASE_OBJECTS = $(addprefix $(PROJECT_ROOT_DIR)/release_obj/,$(SOURCES:.cpp=.o))

HelloWorldD: $(DEBUG_OBJECTS)
HelloWorld: $(RELEASE_OBJECTS)

# And let add three lines just to ensure that the flags will be correct in case
# someone tries to make an object without going through "debug" or "release":

CXX_BASE_FLAGS=-Wall -Wextra -Werror -DLINUX
$(DEBUG_OBJECTS): CXXFLAGS=$(CXX_BASE_FLAGS) $(CXX_DEBUG_FLAGS)
$(RELEASE_OBJECTS): CXXFLAGS=$(CXX_BASE_FLAGS) $(CXX_RELEASE_FLAGS)

Ответ 2

Используйте VPATH, чтобы создавать отладочные и выпускные сборки, используя тот же набор исходных файлов. В сборке отладки и выпуска может быть свой собственный каталог, что означает, что они будут разделены объектными файлами.

В качестве альтернативы используйте инструмент построения, который поддерживает исходные сборки изначально, например automake или (ugh) cmake.

Если вы включите опцию automake subdir-objects (как в AM_INIT_AUTOMAKE([foreign subdir-objects])), вы можете написать нерекурсивный Makefile.am.