Comment savoir d'où est inclus un fichier d'en-tête?

97

Comment puis-je savoir où g ++ a pu trouver un fichier d'inclusion? Fondamentalement, si je

#include <foo.h>

g ++ analysera le chemin de recherche, en utilisant toutes les options d'inclusion pour ajouter ou modifier le chemin. Mais, à la fin des jours, y a-t-il un moyen de savoir le chemin absolu de foo.h que g ++ a choisi de compiler? Particulièrement pertinent s'il y a plus d'un foo.h dans la myriade de chemins de recherche.

À court d'un moyen d'accomplir cela ... y a-t-il un moyen pour que g ++ me dise quel est son chemin de recherche final après avoir inclus les valeurs par défaut et toutes les options incluses?

harschware
la source
1
Connexes: existe-t-il un moyen de savoir de quel (s) fichier (s) d'inclusion parent un fichier d'inclusion enfant a été inclus? Ie pour montrer le graphique inclus-à partir de (Indice: gcc -E n'est pas tout à fait là ... pourrait être traité pour le produire.)
Krazy Glew

Réponses:

78

Cela donnera des dépendances make qui listent les chemins absolus des fichiers d'inclusion:

gcc  -M showtime.c

Si vous ne voulez pas que le système inclue (c'est-à-dire #include <something.h>), utilisez:

gcc  -MM showtime.c
Sodved
la source
18
Il est à noter que si vous utilisez en conjonction avec "-o myObj.o", la sortie, et non le binaire compilé, va dans "myObj.o". -M a un -E implicite, donc la compilation n'est pas effectuée. J'ai trouvé que -MD est une option très utile à la place, il effectue la compilation et place la sortie dans myObj.d à la place. Faire un paramètre approprié pour juste ajouter à votre ligne de compilation sans effets étranges comme * .o contient maintenant la sortie au lieu du binaire. Merci de votre aide.
harschware
Toutes les options gcc associées sont décrites ici .
akhan le
106
g++ -H ...

affichera également le chemin complet des fichiers d'inclusion dans un format qui montre quel en-tête inclut lequel

Aimant de balle
la source
7
Cela semble être plus utile que -M dans mon expérience. J'aime l'affichage hiérarchique de ce qui inclut quoi.
Brian Minton
Bien, c'est utile à des fins de débogage.
1
C'est la meilleure réponse. Vous pouvez l'ajouter à votre processus de construction sans rien changer d'autre.
Timmmm
4
Cela répond vraiment à la question plus qu'à la réponse acceptée. Le seul problème regrettable est que je n'ai pas réussi à empêcher Clang d'essayer de compiler le fichier normalement, alors j'ai fini par utiliser clang++ -MM -H(ce qui est une combinaison légèrement utile).
rookie1024
@ rookie1024 À utiliser clang++ -H -fsyntax-only ...si vous souhaitez éviter de générer des fichiers de sortie (fonctionne gccaussi pour ).
Lekensteyn
8

Utilisation sûre

g++ -E -dI  ... (whatever the original command arguments were)
marcher
la source
2
Il y a plusieurs avantages à cette solution: 1. Vous pouvez découvrir plusieurs inclusions d'un même fichier d'en-tête (-H et -M n'impriment chaque fichier inclus qu'une seule fois) 2. Vous pouvez voir où il est inclus (nom et numéro de ligne de l'original inclure des instructions). 3. Ainsi, vous pouvez de manière fiable (!) Distinguer si un en-tête est inclus directement ou indirectement ou les deux (Ceci est important pour les nettoyages.)
hagello
5

Si vous utilisez -MMou l'une des options associées ( -M, etc.), vous obtenez uniquement la liste des en-têtes inclus sans avoir toutes les autres sorties du préprocesseur (que vous semblez obtenir avec la g++ -E -dIsolution suggérée ).

Jonathan Leffler
la source
g++ -MM t.ccne montre aucune inclusion du tout, juste t.o: t.cc. A-t-il besoin d'autre chose?
wallyk
3
Bien - pour être complet, vous pouvez obtenir la même chose avec MSVC en utilisant l' /showIncludesoption. MSVC mettra même en retrait pour vous montrer l'imbrication des en-têtes (je ne vois pas cela avec -Msur GCC).
Michael Burr