gcc / g++: "aucun fichier ou répertoire de ce type"

g++ donne-moi les erreurs de la forme:

foo.cc:<line>:<column>: fatal error: <bar>: No such file or directory
compilation terminated.

C'est la même chose lors de la compilation de programmes C avec gcc.

Pourquoi est-ce?


Veuillez noter: cette question a été posée plusieurs fois auparavant, mais chaque fois elle était spécifique à la situation des askers. Le but de cette question Est d'avoir une question que d'autres peuvent être fermées en tant que doublons de, Une fois pour Toutes; a FAQ .

59
demandé sur Sebastian Mach 2012-10-16 20:17:04

1 réponses

Votre compilateur juste essayé de compiler le fichier nommé foo.cc. En appuyant sur le numéro de ligne line, le compilateur trouve:

#include "bar"

Ou

#include <bar>

Le compilateur essaie alors de trouver ce fichier. Pour cela, il utilise un ensemble de répertoires à examiner, mais dans cet ensemble, il n'y a pas de fichier bar. Pour une explication de la différence entre les versions de l'instruction include, regardez ici .

Comment dire au compilateur où le trouver

g++ a un option -I. Il vous permet d'ajouter inclure des chemins de recherche à la ligne de commande. Imaginez que votre fichier bar se trouve dans un dossier nommé frobnicate, par rapport à foo.cc (supposons que vous compilez à partir du répertoire où se trouve foo.cc):

g++ -Ifrobnicate foo.cc

Vous pouvez ajouter d'autres include-paths; chacun d'eux est relatif au répertoire courant. 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 Include Supplémentaires.

Imaginez maintenant que vous avez plusieurs versions de bar dans différents dossiers, étant donné:


// A/bar
#include<string>
std::string which() { return "A/bar"; }

// B/bar
#include<string>
std::string which() { return "B/bar"; }

// C/bar
#include<string>
std::string which() { return "C/bar"; }

// foo.cc
#include "bar"
#include <iostream>

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 à travers A/, B/ et C/, Il s'est arrêté au premier coup ou au plus à gauche.

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

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

Habituellement, le {[33] } le fait regarder dans les dossiers système en premier, le #include "xxx" le fait regarder dans les dossiers actuels ou personnalisés en premier.

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 #include le fichier list dans votre dossier de projet, car il compile actuellement main.cc et il y a ce fichier list dans le dossier en cours.

, Mais avec main.cc:

#include <list>
....

Puis g++ main.cc, votre compilateur examinera d'abord les dossiers système, et comme <list> est un en-tête standard, il #include le fichier nommé list fourni avec votre plate-forme C++ dans le cadre de la bibliothèque standard.

C'est un peu simplifié, mais devrait vous donner l'idée de base.

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

Selon la gcc-documentation, 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 regardera également dans /usr / include/C++ / version, en premier. Dans ce qui précède, target est le nom canonique du système GCC a été configuré pour compiler le code pour; [...].

La documentation indique également:

Vous pouvez ajouter à 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 la valeur par défaut répertoires. La seule exception est lorsque dir est déjà recherché par défaut. Dans ce cas, l'option est ignorée et l'ordre de recherche des répertoires système reste inchangé.

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

g++ -I. main.cc

Et

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

Et en effet, le -I. donne la priorité au dossier . sur le système inclut et nous obtenons une erreur de compilateur.

77
répondu Sebastian Mach 2017-05-23 12:18:34