2009-10-21 9 views
7

Nuestra marca archivo .c compila archivos de origen con una regla de patrón estático como sigue:maquillaje GNU, pueden los requisitos previos en una regla patrón estático tener diferentes sufijos

OBJECTS = foo.o bar.o baz.o 

$(OBJECTS): %.o: %.c 
    $(CC) $< $(C_OPTIONS) -c -o [email protected] 

Necesito cambiar una de las .c archivos a un archivo Objective-C .m Invocar el compilador es el mismo para ambos tipos de fuente, por lo que me gustaría usar la misma regla y simplemente modificarla para que sea más flexible. Prefiero no cambiar la variable OPTIONS porque también se usa para el paso de vinculación, etc.

¿Hay alguna manera de flexibilizar la regla anterior para acomodar los archivos .c y .m?

Gracias

Respuesta

1

En realidad, no sólo tienes que copiar a

$(OBJECTS): %.o: %.m 
    $(CC) $< $(C_OPTIONS) -c -o [email protected] 
+0

Produce errores. Para la primera instancia no se encontrarán archivos '% .m' (¡error!), Y para el segundo - no'% .c' (¡otro error!) –

+0

Lo sentimos, solo miramos lo que hay si no hay. c archivo, entonces no invocará la regla% .c – Mark

-1

La llamada al mismo compilador es sólo una ocasión feliz. Normalmente no compila el código objetivo-c con $(CC). Eso solo se siente extraño.

Pero ya vas en una forma dura, no voy a publicar solución do-it-derecha, donde se separan los objetivos de Objective-C de C en dos objetivos diferentes $(OBJECTS) -como las variables y hacer dos reglas (que se debería realmente hacer). Muy aburrido. En su lugar, toma un truco!

OBJC_FILES:=$(subst $(wildcard *.m)) 

real_name = `(test -h $(1) && readlink $(1)) || echo $(1)` 

$(OBJECTS): %.o: %.c 
    $(GCC) $< $(C_OPTIONS) -c -o $(call real_name,[email protected]) 

$(OBJC_FILES): %.c: %.m 
    ln -s $< [email protected] 

¡Y Dios ayude a quienes lo mantengan!

Por cierto, esto obviamente no funcionará si se generan sus archivos-m.

7

Podemos agregar este comportamiento cualquiera o a la lista de cosas que Make debería poder hacer fácilmente, pero no es así. Aquí hay una manera de hacerlo, usando "eval" para crear una regla separada para cada objeto.

 
define RULE_template 
$(1): $(wildcard $(basename $(1)).[cm]) 
endef 

OBJECTS = foo.o bar.o baz.o 

$(foreach obj,$(OBJECTS),$(eval $(call RULE_template,$(obj)))) 

$(OBJECTS): 
    $(CC) $< $(C_OPTIONS) -c -o [email protected] 

Tenga en cuenta que esto depende de los archivos de origen ya existentes antes de ejecutar Marca (foo.c o foo.m, pero no ambos). Si está generando esas fuentes en el mismo paso, esto no funcionará.

Aquí hay un método menos inteligente, más robusto.

 
CPP_OBJECTS = foo.o bar.o 
OBJECTIVE_OBJECTS = baz.o 
OBJECTS = $(CPP_OBJECTS) $(OBJECTIVE_OBJECTS) 

$(CPP_OBJECTS): %.o: %.c 

$(OBJECTIVE_OBJECTS): %.o: %.m 

$(OBJECTS): 
    $(CC) $< $(C_OPTIONS) -c -o [email protected] 

EDIT: corregido objetos de imputación, gracias a Jonathan Leffler.

+1

Estoy de acuerdo con el método más robusto. Lo usaría. Pero la macro OBJECTS = necesita unos $ (...) en el RHS. –

+0

¡Ack! Tienes razón, debería haber sido más cuidadoso. – Beta

+0

Haciendo su ejemplo (el segundo) solo se está generando el primer archivo foo.o. ¿Cuál es el problema? – BogdanSikach

Cuestiones relacionadas