Où gcc recherche-t-il les fichiers d'en-tête C et C ++?

186

Sur un système Unix, où gcc recherche-t-il les fichiers d'en-tête?

J'ai passé un peu de temps ce matin à chercher des fichiers d'en-tête système, alors j'ai pensé que ce serait une bonne information à avoir ici.

Bill le lézard
la source

Réponses:

227
`gcc -print-prog-name=cc1plus` -v

Cette commande demande à gcc quel préprocesseur C ++ il utilise, puis demande à ce préprocesseur où il recherche les inclusions.

Vous obtiendrez une réponse fiable pour votre configuration spécifique.

De même, pour le préprocesseur C :

`gcc -print-prog-name=cpp` -v
Drew Dormann
la source
2
Que signifient les `s? J'ai du mal à rechercher cela.
mijiturka
5
Je suppose que le préprocesseur C est cppau lieu de cc1? Sur mon debian jessie $(gcc -print-prog-name=cpp) -v(correctement) donne un autre chemin, qui est/usr/include/x86_64-linux-gnu
wlnirvana
3
Si vous voulez que cela ne se bloque pas en attendant l'entrée, redirigez l'entrée de /dev/null, donc `gcc -print-prog-name=cc1` -v < /dev/null.
Steve Jorgensen
@SteveJorgensen ouais! Ou appuyez sur Ctrl+ D, qui envoie "fin de fichier" dans Unix-talk.
Drew Dormann
40

De plus, gcc cherchera dans les répertoires spécifiés après l' -Ioption.


Robert
la source
4
@totaam: Vérifiez votre police! Cette réponse utilise "-I" ("œil" en majuscule) et non "-l" ("ell" en minuscule).
3
-I est pour <anglebracketed.h> alors que -iquote est pour "quotedfiles.h"
jcomeau_ictx
28

Vous pouvez créer un fichier qui tente d'inclure un faux en-tête système. Si vous exécutez gcc en mode détaillé sur une telle source, il listera tous les emplacements d'inclusion du système pendant qu'il recherche l'en-tête faux.

$ echo "#include <bogus.h>" > t.c; gcc -v t.c; rm t.c

[..]

#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/gcc/i686-apple-darwin9/4.0.1/include
 /usr/include
 /System/Library/Frameworks (framework directory)
 /Library/Frameworks (framework directory)
End of search list.

[..]

t.c:1:32: error: bogus.h: No such file or directory
diciu
la source
3
Je pense que ce serait plus utile si vous disiez simplement "utiliser l'option -v".
Jay Conrod
Eh bien, si vous utilisez "-v" sans un fichier C qui inclut un en-tête système inexistant, vous ne forcerez pas gcc à parcourir tous les chemins d'inclusion. La clé de ma réponse est bogus.h répertorié comme un en-tête système.
décédé
@Jay - vous avez raison, c'était trop vague - j'ai expliqué ce que je faisais dans le script shell.
décédé
9
sans fichiers temporaires:echo "#include <bogus.h>" | gcc -v -x c -
thejoshwolfe
2
gcc -v -E - < /dev/null ou cpp -v < /dev/null suffisent. Il vous suffit d'obtenir le préprocesseur courir , il n'a pas d' importance ce que l' entrée qu'il voit. (Les chemins de recherche sont imprimés au démarrage, avant même qu'il ne regarde son entrée.)
zwol
17

La section CPP du manuel GCC indique que les fichiers d'en-tête peuvent être situés dans les répertoires suivants:

GCC recherche les en-têtes à plusieurs endroits différents. Sur un système Unix normal, si vous ne lui demandez pas le contraire, il recherchera les en-têtes demandés avec #include dans:

 /usr/local/include
 libdir/gcc/target/version/include
 /usr/target/include
 /usr/include

Pour les programmes C ++, il cherchera également dans / usr / include / g ++ - v3, en premier.

Bill le lézard
la source
C'est parfait pour votre version actuelle de gcc. Les répertoires réels dans lesquels il recherche dépend des options spécifiées lors de la construction de gcc. Voir la réponse Shmoopty pour une meilleure solution.
Martin York
PS: Mes fichiers d'en-tête C ++ sont dans: /usr/include/c++/4.0.0
Martin York
3
@Martin: Vous êtes de la vieille école. Les miens sont dans /usr/include/c++/4.2 :)
Bill the Lizard
10

Pour que GCC affiche l'ensemble complet des répertoires où il recherchera les en-têtes système, appelez-le comme ceci:

$ LC_ALL=C gcc -v -E -xc - < /dev/null 2>&1 | 
  LC_ALL=C sed -ne '/starts here/,/End of/p'

qui produira la sortie du formulaire

#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/5/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.

Si tu as -I options -family sur la ligne de commande, elles affecteront ce qui est imprimé.

(La sedcommande consiste à se débarrasser de tous les autres fichiers indésirables que cette invocation imprime, et LC_ALL=Cà s'assurer que la sedcommande fonctionne - les expressions «commence ici» et «Fin de la liste de recherche» sont traduites par IIRC.)

zwol
la source
9
g++ -print-search-dirs
gcc -print-search-dirs
user292283
la source
3
Ces commandes impriment les chemins de recherche par défaut pour les bibliothèques de liens et les composants internes du compilateur; ils ne vous disent rien sur les fichiers d'en-tête.
zwol
6

L'ensemble des chemins où le compilateur recherche les fichiers d'en-tête peut être vérifié par la commande: -

cpp -v

Si vous déclarez #include "" , le compilateur recherche d'abord dans le répertoire courant du fichier source et s'il n'est pas trouvé, continue de chercher dans les répertoires récupérés ci-dessus.

Si vous déclarez #include <> , le compilateur recherche directement dans les répertoires obtenus à partir de la commande ci-dessus.

Source: - http://commandlinefanatic.com/cgi-bin/showarticle.cgi?article=art026

Suhas Chikkanna
la source
1

On pourrait afficher le chemin d'inclusion (supplémentaire) pour un programme C à partir de bash en vérifiant ce qui suit:

echo $C_INCLUDE_PATH

Si ce champ est vide, il peut être modifié pour ajouter des emplacements d'inclusion par défaut, en:

export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/include
user2844647
la source
1

Ce sont les répertoires dans lesquels gcc recherche par défaut les fichiers d'en-tête spécifiés (étant donné que les fichiers d'en-tête sont inclus dans les chevrons <>); 1. / usr / local / include / - utilisé pour les fichiers d'en-tête tiers. 2. / usr / include / - utilisé pour les fichiers d'en-tête système.

Si vous décidez de placer votre fichier d'en-tête personnalisé dans un endroit autre que les répertoires mentionnés ci-dessus, vous pouvez les inclure comme suit: 1. en utilisant des guillemets ("./custom_header_files/foo.h") avec le chemin des fichiers, au lieu des chevrons dans l'instruction include. 2. en utilisant le commutateur -I lors de la compilation du code. gcc -I / home / user / en-têtes_personnalisés / -c foo.c -p foo.o Fondamentalement, le commutateur -I indique au compilateur de regarder d'abord dans le répertoire spécifié avec le commutateur -I (avant de vérifier les répertoires standard). en utilisant le commutateur -I, les fichiers d'en-tête peuvent être inclus en utilisant des chevrons.

akhil tiwari
la source