gcc / g ++: «Pas de tel fichier ou répertoire»

g++ me donne des erreurs de la forme:

 foo.cc::: fatal error: : No such file or directory compilation terminated. 

Il en va de même lors de la compilation de programmes C avec gcc .

Pourquoi donc?


Remarque: cette question a déjà été posée à plusieurs resockets, mais à chaque fois, elle était spécifique à la situation du demandeur. Le but de cette question est d’avoir une question à laquelle d’autres peuvent être fermés en double , une fois pour toutes; une FAQ

Votre compilateur a juste essayé de comstackr le fichier nommé foo.cc En tapant sur la ligne du numéro de line , le compilateur trouve:

 #include "bar" 

ou

 #include  

Le compilateur tente ensuite de trouver ce fichier. Pour cela, il utilise un ensemble de répertoires à rechercher, mais dans cet ensemble, il n’y a pas de bar fichiers. Pour une explication de la différence entre les versions de la déclaration d’inclusion, regardez ici .

Comment dire au compilateur où le trouver

g++ a une option -I . Il vous permet d’append des chemins de recherche inclus à la ligne de commande. Imaginez que votre bar fichiers se trouve dans un dossier nommé frobnicate , relatif à foo.cc (supposez que vous comstackz à partir du répertoire où se trouve foo.cc ):

 g++ -Ifrobnicate foo.cc 

Vous pouvez append d’autres chemins d’inclusion. chacun vous donne est relatif au répertoire actuel. Le compilateur de Microsoft a une option de corrélation /I qui fonctionne de la même manière ou, dans Visual Studio, les dossiers peuvent être définis dans les pages de propriétés du projet, sous Propriétés de configuration-> C / C ++ -> Général-> Répertoires d’inclusion supplémentaires.

Maintenant, imaginez que vous avez plusieurs versions de bar dans différents dossiers, à condition:


 // A/bar #include std::ssortingng which() { return "A/bar"; } 

 // B/bar #include std::ssortingng which() { return "B/bar"; } 

 // C/bar #include std::ssortingng which() { return "C/bar"; } 

 // foo.cc #include "bar" #include  int main () { std::cout << which() << std::endl; } 

La priorité avec #include "bar" est la plus à gauche:

 $ g++ -IA -IB -IC foo.cc $ ./a.out A/bar 

Comme vous le voyez, lorsque le compilateur a commencé à regarder A/ , B/ et C/ , il s'est arrêté au premier ou au plus à gauche.

Cela est vrai pour les deux formes, y include <> et incude "" .

Différence entre #include et #include "bar"

Habituellement, le #include place d'abord dans les dossiers du système, le #include "xxx" fait apparaître dans les dossiers actuels ou personnalisés.

Par exemple:

Imaginez que vous avez les fichiers suivants dans votre dossier de projet:

 list main.cc 

avec main.cc :

 #include "list" .... 

Pour cela, votre compilateur inclura la list fichiers dans votre dossier de projet, car il comstack actuellement main.cc et il y a cette list fichiers dans le dossier actuel.

Mais avec main.cc :

 #include  .... 

et ensuite g++ main.cc , votre compilateur examinera d'abord les dossiers système, et comme est un en-tête standard, il #include inclura la list nommée fournie avec votre plateforme C ++ dans la bibliothèque standard.

Tout cela est un peu simplifié, mais devrait vous donner l’idée de base.

Détails sur les priorités <> / "" et -I

Selon la documentation de gcc , la priorité pour include <> est, sur un "système Unix normal", comme suit:

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

Pour les programmes C ++, il faudra d'abord regarder dans / usr / include / c ++ / version. Dans ce qui précède, target est le nom canonique du système sur lequel GCC a été configuré pour comstackr le code; [...].

La documentation indique également:

Vous pouvez append à cette liste avec l'option de ligne de commande -Idir. Tous les répertoires nommés par -I sont recherchés dans l'ordre de gauche à droite avant les répertoires par défaut . La seule exception est lorsque le répertoire est déjà recherché par défaut. Dans ce cas, l'option est ignorée et l'ordre de recherche pour les répertoires système rest inchangé.

Pour continuer notre exemple #include / #include"list" (même code):

 g++ -I. main.cc 

et

 #include int main () { std::list l; } 

et en effet, le -I. priorise le dossier . sur le système comprend et nous obtenons une erreur de compilation.