Question

J'utilise GCC pour générer un fichier de dépendance, mais mes règles de construction placent la sortie dans un sous-répertoire. Y a-t-il un moyen de dire à GCC de mettre mon préfixe de sous-répertoire dans le fichier de dépendance qu'il génère pour moi?

gcc $(INCLUDES) -E -MM $(CFLAGS) $(SRC) >>$(DEP)
Était-ce utile?

La solution

La réponse se trouve dans le manuel GCC . : utilisez le -MT drapeau.

  

-MT target

     

Modifiez la cible de la règle émise par la génération de dépendance. Par défaut, CPP prend le nom du fichier d'entrée principal, supprime tous les composants du répertoire et tout suffixe de fichier tel que .c, puis ajoute le suffixe d'objet habituel de la plateforme. Le résultat est la cible.

     

Une option -MT '$(objpfx)foo.o' définit la cible comme étant exactement la chaîne que vous spécifiez. Si vous souhaitez plusieurs cibles, vous pouvez les spécifier en tant qu'argument unique pour <=> ou utiliser plusieurs <=> options.

     

Par exemple, <=> peut donner

$(objpfx)foo.o: foo.c

Autres conseils

Je suppose que vous utilisez GNU Make et GCC. Commencez par ajouter une variable pour contenir votre liste de fichiers de dépendance. En supposant que vous en ayez déjà une qui répertorie toutes nos sources:

SRCS = \
        main.c \
        foo.c \
        stuff/bar.c

DEPS = $(SRCS:.c=.d)

Ensuite, incluez les dépendances générées dans le fichier makefile:

include $(DEPS)

Ajoutez ensuite cette règle de modèle:

# automatically generate dependency rules

%.d : %.c
        $(CC) $(CCFLAGS) -MF"$@" -MG -MM -MP -MT"$@" -MT"$(<:.c=.o)" "$<"

# -MF  write the generated dependency rule to a file
# -MG  assume missing headers will be generated and don't stop with an error
# -MM  generate dependency rule for prerequisite, skipping system headers
# -MP  add phony target for each header to prevent errors when header is missing
# -MT  add a target to the generated dependency

" $ @ " est la cible (la chose à gauche du:), " $ < " est la condition préalable (la chose sur le côté droit de la:). L'expression & Quot; $ (& Lt;:. C = .o) & Quot; remplace l'extension .c par .o.

Le truc ici est de générer la règle avec deux cibles en ajoutant deux fois -MT; cela fait que le fichier .o et le fichier .d dépendent du fichier source et de ses en-têtes; De cette façon, le fichier de dépendance est automatiquement régénéré chaque fois que l’un des fichiers .c ou .h correspondants est modifié.

Les options -MG et -MP empêchent make de paniquer s’il manque un fichier d’en-tête.

Vous pourriez aimer cette version plus brève du de Don McCaughey répondre :

SRCS = \
    main.c \
    foo.c \
    stuff/bar.c

DEPS = $(SRCS:.c=.d)

Ajoutez -include $(DEPS) notez le préfixe -, qui supprime les erreurs si les fichiers .d n'existent pas encore.

Il n'est pas nécessaire de définir une règle de modèle distincte pour générer les fichiers de dépendance. Ajoutez simplement -MD ou -MMD à votre ligne de compilation normale et les fichiers <=> sont générés en même temps que vos fichiers source sont compilés. Par exemple:

%.o: %.c
     gcc $(INCLUDE) -MMD -c $< -o $@

# -MD can be used to generate a dependency output file as a side-effect of the compilation process.

Informations détaillées sur le Réponse de DGentry , cela a bien fonctionné pour moi:

.depend: $(SOURCES)
    $(CC) $(CFLAGS) -MM $(SOURCES) | sed 's|[a-zA-Z0-9_-]*\.o|$(OBJDIR)/&|' > ./.depend

Ceci fonctionne également dans le cas où il n'y a qu'un seul fichier de dépendance contenant les règles de dépendance pour tous les fichiers source.

Ok, je veux juste m'assurer que j'ai bien compris la question: je suppose que vous avez test.c qui inclut test.h et que vous souhaitez générer subdir/test.d (tant que pas générer subdir/test.o) où .d contient

subdir/test.o: test.c test.h

plutôt que

test.o: test.c test.h

qui est ce que vous obtenez en ce moment. Est-ce vrai?

Je n'ai pas été en mesure de trouver un moyen facile de faire exactement ce que vous demandez. Cependant, Améliorations apportées à la génération de dépendances , si vous souhaitez créer le fichier SRC=test.c pendant que vous générez le fichier .o, vous pouvez utiliser:

gcc $(INCLUDES) -MMD $(CFLAGS) $(SRC) -o $(SUBDIR)/$(OBJ)

(Étant donné SUBDIR=subdir, OBJ=test.o et <=>.) Ceci créera les sous-répertoires / test.o et les sous-répertoires / test.d, où <=> contient la sortie souhaitée, comme ci-dessus.

Si GCC se dispute pour le faire, je ne sais pas ce que c'est. Nous finissons par canaliser la sortie de dépendance via sed pour réécrire toutes les occurrences de < blah > ; .o sous la forme $ {OBJDIR} / .o .

  1. [GNU] se met en colère si vous ne placez pas la sortie dans le répertoire en cours. Vous devriez vraiment lancer make à partir du répertoire de construction et utiliser la variable make de VPATH pour localiser le code source. Si vous mentez à un compilateur, il prendra tôt ou tard sa revanche.

  2. Si vous insistez pour générer vos objets et dépendances dans un autre répertoire, vous devez utiliser l'argument -o , sous la forme répondu par Emile .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top