2010-07-16 6 views
12

No soy experto en makefiles, pero estoy acostumbrado a los simples. En este momento, tengo una tarea a mano.Makefile - cambia el valor de la variable en función de un objetivo

Necesito compilar y vincular una aplicación de prueba con una biblioteca diferente y diferentes rutas de acceso basadas en el objetivo dado. Si el objetivo es TARGET1, enlace con LIB1 e incluya INCLUDEPATH1 durante la compilación. De forma similar, si el objetivo dado es TARGET2, compile con INCLUDEPATH2 en CFLAGS y enlace con LIB2.

%.o: %.c 
    @echo [CC] $< ... 
    $(CC) $(CFLAGS) -o $*.o $< 

Ahora tengo una regla como la anterior que compila mi aplicación de prueba. Ahora, ¿cómo se puede cambiar CFLAGS en función del objetivo?

Respuesta

27

Si está usando GNU Make, puede utilizar target-specific variables:

target1: CFLAGS = -IINCLUDEPATH1 
target1: LDLIBS = -lLIB1 

target2: CFLAGS = -IINCLUDEPATH2 
target2: LDLIBS = -lLIB2 

all: target1 target2 

target1: target1.o misc.o 
target2: target2.o 

Sin embargo esto no funciona tan bien como desee: si TARGET1 y TARGET2 compartir algunos archivos de origen , deberá organizar que cada uno de ellos se compile dos veces y en archivos .o con nombres diferentes, lo que complicará bastante su archivo MAKE.

Además, si escribe a continuación make target1-IINCLUDEPATH1 se propagará a la compilación de misc.c, según se desee. Sin embargo, si escribe make misc.o no tiene forma de saber que esto está destinado a target1 y la compilación de misc.c no obtendrá ningún valor especial de $ CFLAGS (aunque obtendrá el global, si hay uno))

Esto realmente solo es útil en casos simples. Pero tal vez tu caso sea lo suficientemente simple.

+1

¡Guau, no sabía que las variables específicas del destino se propagan a reglas implícitas! –

+0

Un gran consejo. A pesar de que he estado escribiendo Makefiles por mucho tiempo, de alguna manera nunca fui consciente de esta característica. –

1

No creo que pueda modificar la variable en función de un objetivo. Supongamos que usted invoca

make TARGET1 TARGET2 

¿Qué valor tendría el CFLAGS tener entonces?

En este caso, puede usar reglas que no sean patrones para distinguir objetivos.

TARGET1: a.c 
    @echo [CC] $< ... 
    $(CC) -I INCLUDEPATH1 ... 

TARGET2: a.c 
    @echo [CC] $< ... 
    $(CC) -I INCLUDEPATH2 ... 

Para disminuir la repetición, también puede utilizar variables y "functions". Entonces, podrías reutilizar lo que sería el cuerpo de tu regla de patrón en diferentes reglas.

define compile_cmd 
    @echo [CC] $< ... 
    $(CC) -I $1 -l$2 $(CFLAGS) 
endef 

TARGET1: a.c 
    $(call compile_cmd,INCLUDEPATH1,LIB1) -o [email protected] $< 

TARGET2: a.c 
    $(call compile_cmd,INCLUDEPATH2,LIB2) -o [email protected] $< 

%.o: %.c 
    $(call compile_cmd,INCLUDEPATH_DEFAULT,LIB_DEFAULT) -o [email protected] $< 

Eso sería un makefile lo suficientemente agradable y flexible que se adapte a sus necesidades.

Cuestiones relacionadas