tutorial make makefile gnu-make

makefile - tutorial - Usando GNU Make para construir tanto los objetivos de debug como los de release al mismo tiempo



makefile ubuntu (2)

Estoy trabajando en un proyecto de tamaño mediano que contiene varias bibliotecas con interdependencias que he convertido recientemente para compilar utilizando un archivo make no recursivo. Mi próximo objetivo es habilitar la creación de compilaciones tanto de depuración como de liberación desde el mismo árbol de origen al mismo tiempo (hacer depuración; realizar liberación). Mi primer paso fue hacer objetivos de depuración y lanzamiento que contenían las marcas de compilación correctas. Hice esto usando variables específicas de destino, como esto: 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

Esto funcionó bien, pero solo puedes compilar depuración o lanzamiento, no ambos al mismo tiempo. Y, al mismo tiempo, no me refiero a que durante la misma compilación me refiero a unir en el mismo árbol de origen (debug; make release). Para hacer esto, necesito colocar los archivos de objeto en un directorio específico de depuración / lanzamiento para que no se sobrescriban unos a otros y necesito modificar el nombre binario de destino de depuración con una ''D''. Pensé que esto sería fácil, ya que podría usar variables específicas de nuevo, como esto: 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)

Los expertos que leen esto ya saben que esto no funcionará porque no puede usar variables específicas del objetivo para crear objetivos reales. Funcionaron bien para mi var CXXFLAGS porque la variable no se utilizó en un nombre de destino.

¿Existe un patrón de diseño y / o mejores prácticas para administrar las construcciones de depuración / lanzamiento utilizando archivos make no recursivos? Específicamente, ¿cómo compilo la ruta del directorio del archivo de objetos y el nombre de destino (construyo un destino basado en un objetivo)?


Uno de los problemas más persistentes de Make es su incapacidad para manejar más de un comodín a la vez. No hay una manera realmente limpia de hacer lo que pides (sin recurrir a la recursión, lo que no creo que sea realmente tan malo). Aquí hay un enfoque razonable:

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''s 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)


Use VPATH para hacer que las VPATH de depuración y lanzamiento usen el mismo conjunto de archivos de origen. La compilación de debug y release puede tener su propio directorio, lo que significa que tendrán sus archivos de objetos separados.

Alternativamente, use una herramienta de compilación que admita construcciones fuera de la fuente de forma nativa, como automake o (ugh) cmake.

Si habilita los subdir-objects de AM_INIT_AUTOMAKE([foreign subdir-objects]) opción automake (como en AM_INIT_AUTOMAKE([foreign subdir-objects]) subdir-objects de AM_INIT_AUTOMAKE([foreign subdir-objects]) ), puede escribir un Makefile.am no recursivo.