2009-10-21 7 views
7

Notre fichier make compile .c fichiers source avec une règle de modèle statique comme ceci:Dans gnu make, peut les conditions préalables à une règle de modèle statique ont des suffixes différents

OBJECTS = foo.o bar.o baz.o 

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

Je dois changer un des .c fichiers dans un fichier Objective-C .m. L'invocation du compilateur est la même pour les deux types de sources, donc je voudrais utiliser la même règle et la modifier pour la rendre plus flexible. Je préfère ne pas modifier la variable OPTIONS car elle est également utilisée pour l'étape de liaison, etc.

Existe-t-il un moyen de rendre la règle ci-dessus plus flexible pour prendre en charge les fichiers .c et .m?

Merci

Répondre

1

Pas vraiment juste copier sur

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

Cela entraînera des erreurs. Pour la première instance, aucun fichier '% .m' ne sera trouvé (erreur!), Et pour la seconde - non'% .c' (une autre erreur!) –

+0

Désolé, ne regardez que ce qui est là s'il n'y en a pas. c fichier alors il n'appellera pas la règle% .c – Mark

-1

L'appel au même compilateur est juste une occasion heureuse. Normalement, vous ne compilez pas le code objectif-c avec $(CC). Cela me semble étrange.

Mais puisque vous allez de manière dure, je ne publierai pas de solution do-it-right, où vous séparez les objectifs C des cibles C en deux variables $(OBJECTS)-like différentes et faites deux règles (que vous devrait vraiment faire). Trop ennuyeux. Au lieu de cela, prenez un hack!

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] 

Et que Dieu aide ceux qui la maintiennent! Btw, cela ne fonctionnera évidemment pas si vos fichiers m sont générés.

7

Nous pouvons ajouter ceci soit-ou le comportement à la liste des choses que devrait pouvoir faire facilement, mais ne l'est pas. Voici une façon de le faire, en utilisant "eval" pour créer une règle séparée pour chaque objet.

 
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] 

Notez que cela dépend des fichiers sources déjà existantes avant de lancer make (foo.c ou foo.m, mais pas les deux). Si vous générez ces sources dans la même étape, cela ne fonctionnera pas.

Voici une méthode moins intelligente et plus robuste.

 
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: affectation OBJETS corrigée, grâce à Jonathan Leffler.

+1

Je suis d'accord avec la méthode plus robuste - je l'utiliserais. Mais la macro OBJECTS = a besoin de $ (...) sur le RHS. –

+0

Ack! Tu as raison, j'aurais dû être plus prudent. – Beta

+0

En faisant votre exemple (le second) seul le premier fichier foo.o est en cours de génération. Quel est le problème? – BogdanSikach

Questions connexes