2012-05-30 15 views
5

relacionadas: Target-specific Variables as Prerequisites in a Makefileobjetivo makefile variables específicas como requisitos previos

estoy tratando de diseñar un Makefile que utiliza un objetivo específico de variables para especificar el directorio de salida para los archivos objeto y el ejecutable final. La idea es mantener dos versiones binarias separadas, una versión 'versión' y una versión 'depuración' con información de depuración adicional.

Mi problema es que 'make' hace una compilación limpia cada vez, incluso si no he cambiado nada. Estoy bastante seguro de que es porque 'hacer' está evaluando los requisitos previos de las 'corewars' de destino antes de la declaración de la variable en los requisitos previos para el objetivo 'depurar' o 'liberar'.

El Makefile se presenta a continuación.

CXX=g++ 
LD=g++ 
LDFLAGS= 
CXXFLAGS=-Iinclude -Wall -Wextra 
OBJECTS=main.o Machine.o Core.o ProcessQueue.o Instruction.o 
OUTPUT_DIR:=Test/ 

.PHONY: default 
.PHONY: all 
.PHONY: release 
default: release 
all: release 
release: OUTPUT_DIR:=Release/ 
release: corewars 

.PHONY: debug 
debug: CXXFLAGS+=-DDEBUG -g 
debug: OUTPUT_DIR:=Debug/ 
debug: corewars 

corewars: $(OUTPUT_DIR) $(addprefix $(OUTPUT_DIR),$(OBJECTS)) 
    $(LD) -o $(addprefix $(OUTPUT_DIR),corewars) $(addprefix $(OUTPUT_DIR),$(OBJECTS)) 

Release: 
    mkdir -p [email protected] 
Debug: 
    mkdir -p [email protected] 

%.o: %.cpp include/%.h 
    $(CXX) -c $(CXXFLAGS) $< -o $(OUTPUT_DIR)[email protected] 


.PHONY: clean 
clean: 
    $(RM) -r Release 
    $(RM) -r Debug 

Respuesta

11

Al menos su regla de compilación está quebrada. A non-phony recipe must create a target, [email protected], not $(OUTPUT_DIR)[email protected].

Considere también la posibilidad de convertir dependencias de directorio en requisitos previos order-only.

Por último, para obtener el valor adecuado de $(OUTPUT_DIR) dentro de la lista de requisitos previos, usted tiene que utilizar secondary expansion, porque de lo contrario, la definición global OUTPUT_DIR:=Test/ se utiliza en lugar de un objetivo específico.

No sé cómo reparar su archivo MAKE sin expansión secundaria y vpath magic. Personalmente, primero configuraba el entorno (averigua el valor de OUTPUT_DIR, etc.) y luego vuelve a ejecutar Make con los valores adecuados.

ifndef OUTPUT_DIR 

.PHONY: default all release debug 

default all: release 

release: export OUTPUT_DIR := Release/ 
debug: export OUTPUT_DIR := Debug/ 
debug: export EXTRA_CXXFLAGS := -DDEBUG -g 

release debug: 
    @$(MAKE) 

else 

# ... 
CXXFLAGS := -Iinclude -Wall -Wextra $(EXTRA_CXXFLAGS) 

PROGRAM := $(OUTPUT_DIR)corewars 
OBJECTS := $(addprefix $(OUTPUT_DIR), \ 
    main.o Machine.o Core.o ProcessQueue.o Instruction.o) 

# Default target. 
$(PROGRAM): $(OBJECTS) | $(OUTPUT_DIR) 
    $(LD) -o [email protected] $< 

$(OUTPUT_DIR)%.o: %.cpp | $(OUTPUT_DIR) 
    $(CXX) -c $(CXXFLAGS) $< -o [email protected] 

$(OUTPUT_DIR): 
    mkdir -p [email protected] 

endif # OUTPUT_DIR 
+0

Esta es una excelente desinfección de mi sistema de construcción, gracias. Me pareció necesario agregar '| $ (OUTPUT_DIR) 'a la lista de requisitos previos para que la regla haga archivos' .o', y agregué un objetivo 'limpio', pero aparte de eso, esto funciona como se cita. Muchas gracias. –

+0

@Chris, oh, sí, tienes razón, me olvidé de eso (arreglado). ¡Y eres bienvenido! ;-) –

+0

¡Gracias por el aviso! Lo arreglaré ahora. –

Cuestiones relacionadas