2017-06-10 1 views
0

Je m'excuse pour le titre ambigu, je ne pouvais pas penser à un moyen simple de l'exprimer en raison de mon manque de connaissances dans GNU make.Comment puis-je faire dépendre une cible de fichier Makefile d'un chemin différent?

J'écris un Makefile simple pour un petit projet, et je suis en train de lui permettre de générer des objets individuels en utilisant leur nom de base (sans chemin) comme cible:

$(BASE_OBJS) : %.o : $(SRC_DIR)/%.c $(OBJDIR) $(INCLUDES)       
    @echo $(CC): [$(notdir $<)] '->' [$(notdir [email protected])]       
    @$(CC) -c $< $(CFLAGS) -o $(OBJDIR)/[email protected] 

Le problème est que l'application 'make' s'attend évidemment à ce que l'objet cible soit présent dans le dossier courant, mais il se trouve réellement dans le sous-dossier $ (OBJDIR). Les causes provoquent la reconstruction inutilement de ces cibles.

Sinon, cette règle ne vérifie pour l'existence de l'objet au bon endroit:

$(OBJS) : $(OBJDIR)/%.o: $(SRC_DIR)/%.c $(INCLUDES)  
    @echo $(CC): [$(notdir $<)] '->' [$(notdir [email protected])]       
    @$(CC) -c $< $(CFLAGS) -o [email protected] 

Mais il ne peut pas être utilisé pour des choses en cours d'exécution comme « faire main.o », comme (OBJS) $ comprend le chemin complet des objets, donc il ne permet que des choses comme 'make output/main.o'.

Si c'est un doublon alors je suis désolé, je cherchais un moment et ne pouvais pas trouver une question similaire.

Pour référence, ce sont les définitions de variables:

BASE_SRC=$(notdir $(SOURCES))              
BASE_OBJS = $(BASE_SRC:%.c=%.o)             
OBJS = $(BASE_OBJS:%.o=$(OBJDIR)/%.o) 
+0

« * et je suis en train de lui permettre de générer des objets individuels en utilisant leur nom de base (sans chemin) comme cible * » <- c'est une conceptionnelle mauvaise utilisation de 'make'. De toute façon, les cibles * devraient * être des fichiers, parce que c'est ainsi que 'make' fonctionne (et' make' détermine à partir de leur horodatage si ces fichiers doivent être reconstruits). Vous pouvez * avoir * quelques cibles "* phony *" (typiquement 'all',' clean', ...) mais vous ** ne voulez pas vraiment ** que vos fichiers d'objets intermédiaires soient créés via une cible * phony *, cela voudrait dire de les reconstruire * chaque fois que vous lancez make *, même si rien n'a changé. –

+0

Je suis conscient du fait que les cibles seraient reconstruites à chaque fois, j'ai posté ma question afin de savoir s'il y a moyen de l'empêcher. A propos de mésusage: C'était ma première pensée, mais je me suis souvenu que le système de compilation du noyau Linux permettait par exemple de construire des fichiers * .dtb à partir du dossier principal, sans reconstruction inutile, et je pensais que c'était possible ici. – Edwin

Répondre

1

Votre principal ensemble d'objectifs et conditions préalables doivent utiliser le chemin complet, parce que c'est comment faire des œuvres. Donc, vous devez avoir quelque chose comme:

$(OBJS) : $(OBJDIR)/%.o: $(SRC_DIR)/%.c $(INCLUDES)  
     @echo $(CC): [$(notdir $<)] '->' [$(notdir [email protected])]       
     @$(CC) -c $< $(CFLAGS) -o [email protected] 

Maintenant, si en plus vous voulez être en mesure d'exécuter un make foo.o simple, puis de le faire, vous devez définir des cibles « alias » supplémentaires pour les cibles réelles. Ces règles n'existent que pour la main courte, elles ne font rien. Quelque chose comme:

$(BASE_OBJS) : %.o : $(OBJDIR)/%.o