119 votes

gcc/g++ : "No such file or directory" (pas de fichier ou de répertoire tel)

g++ me donne des erreurs de la forme :

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

Il en est de même lorsque l'on compile des programmes C avec gcc .

Pourquoi ça ?


Veuillez noter : Cette question a déjà été posée à plusieurs reprises, mais à chaque fois, elle était spécifique à la situation du demandeur. Le but de cette question est d'avoir une question que d'autres peuvent être fermées comme des doublons de une fois pour toutes ; un FAQ .

4 votes

Bel ajout à la FAQ. Merci à vous !

156voto

phresnel Points 20082

Votre compilateur vient d'essayer de compiler le fichier nommé foo.cc . En frappant le numéro de ligne line le compilateur trouve :

#include "bar"

o

#include <bar>

Le compilateur essaie alors de trouver ce fichier. Pour cela, il utilise un ensemble de répertoires à consulter, mais dans cet ensemble, il n'existe pas de fichier bar . Pour une explication des différences entre les versions de l'instruction include, voir aquí .

Comment indiquer au compilateur où le trouver ?

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

g++ -Ifrobnicate foo.cc

Vous pouvez ajouter plus de chemins d'inclusion ; chacun que vous donnez est relatif au répertoire courant. Le compilateur de Microsoft a une option correspondante /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 Configuration Properties->C/C++->General->Additional Include Directories.

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


// 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 le plus à gauche :

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

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

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

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

Habituellement, le #include <xxx> fait en sorte qu'il regarde d'abord dans les dossiers du système, l'option #include "xxx" permet de regarder d'abord dans le dossier actuel ou dans le dossier personnalisé.

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>
....

et ensuite g++ main.cc votre compilateur regardera d'abord dans les dossiers du système, et parce que <list> est un en-tête standard, il #include le fichier nommé list qui fait partie de la bibliothèque standard de votre plate-forme C++.

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

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

Selon le Documentation gcc la priorité pour include <> est, sur un "système Unix normal", le suivant :

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

Pour les programmes C++, il cherchera également dans /usr/include/c++/version, en premier lieu. Dans l'exemple ci-dessus, target est le nom canonique du système pour lequel GCC a été configuré pour compiler du code ; [...].

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 les répertoires par défaut . 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 poursuivre notre #include<list> / #include"list" exemple (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 les inclusions du système et nous obtenons une erreur de compilation.

12 votes

Je veux juste vous faire remarquer que c'est un peu bizarre que vous fassiez référence à votre compilateur comme "votre compilateur" puisque la question et la réponse ont le même auteur.

36 votes

@Jeffrey : Peut-être que l'auteur de la question avait l'intention de s'adapter au format général ici. N'hésitez pas à lui demander.

1 votes

Cette réponse est fausse, #include <> regarde dans les répertoires listés avec -I avant les répertoires système par défaut

0voto

De plus, il semble qu'il y ait un bogue dans le compilateur : si vous incluez les caractères "struct" ou "Struct" dans le nom de votre fichier d'en-tête, le compilateur affichera la même erreur "no such file or directory".

-5voto

JavierQuispe Points 1

Ceci fonctionne pour moi, sudo apt-get install libx11-dev

0 votes

Cela ne permet pas de répondre à la question. Une fois que vous avez suffisamment réputation vous serez en mesure de commenter un article ; au lieu de cela, fournir des réponses qui ne nécessitent pas de clarification de la part de l'auteur de la question . - De la revue

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X