gcc / g ++: "Nessun file o directory di questo tipo"


88

g++ mi da errori del modulo:

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

È lo stesso quando si compilano programmi C con gcc.

Perché?


Nota: questa domanda è stata posta molte volte in passato, ma ogni volta era specifica per la situazione di chi chiedeva. Lo scopo di questa domanda è di avere una domanda di cui altre possano essere chiuse come duplicati , una volta per tutte; una FAQ .


4
Bella aggiunta alle FAQ. Grazie!
sbi

Risposte:


119

Il tuo compilatore ha appena provato a compilare il file denominato foo.cc. Dopo aver premuto il numero di riga line, il compilatore trova:

#include "bar"

o

#include <bar>

Il compilatore quindi tenta di trovare quel file. Per questo, utilizza un set di directory in cui esaminare, ma all'interno di questo set non c'è alcun file bar. Per una spiegazione della differenza tra le versioni dell'istruzione include guarda qui .

Come dire al compilatore dove trovarlo

g++ha un'opzione -I. Ti consente di aggiungere percorsi di ricerca di inclusione alla riga di comando. Immagina che il tuo file barsi trovi in ​​una cartella denominata frobnicate, relativa a foo.cc(supponi di compilare dalla directory in cui foo.ccsi trova):

g++ -Ifrobnicate foo.cc

Puoi aggiungere più percorsi di inclusione; ogni dato è relativo alla directory corrente. Il compilatore di Microsoft ha un'opzione di correlazione /Iche funziona allo stesso modo, oppure in Visual Studio le cartelle possono essere impostate nelle pagine delle proprietà del progetto, in Proprietà di configurazione-> C / C ++ -> Generale-> Directory di inclusione aggiuntive.

Ora immagina di avere più versioni di barin cartelle diverse, dato:


// 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à con #include "bar"è quella più a sinistra:

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

Come vedi, quando il compilatore ha iniziato a guardare A/, B/e C/, si è fermato al primo o al colpo più a sinistra.

Questo è vero per entrambe le forme include <>e incude "".

Differenza tra #include <bar> e#include "bar"

Di solito, il file #include <xxx> fa guardare prima nelle cartelle di sistema, poi lo #include "xxx"fa guardare prima nelle cartelle correnti o personalizzate.

Per esempio:

Immagina di avere i seguenti file nella cartella del tuo progetto:

list
main.cc

con main.cc:

#include "list"
....

Per questo, il tuo compilatore inserirà #includeil file listnella cartella del tuo progetto, perché attualmente si compilamain.cc e c'è quel file listnella cartella corrente.

Ma con main.cc:

#include <list>
....

quindi g++ main.cc, il compilatore esaminerà prima le cartelle di sistema e, poiché <list>è un'intestazione standard, lo farà#include il file denominato listfornito con la piattaforma C ++ come parte della libreria standard.

È tutto un po 'semplificato, ma dovrebbe darti l'idea di base.

Dettagli su <>/ ""-priorità e-I

Secondo la documentazione di gcc , la priorità include <>è, su un "normale sistema Unix", la seguente:

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

Per i programmi C ++, cercherà prima anche in / usr / include / c ++ / version. In quanto sopra, target è il nome canonico del sistema per cui GCC è stato configurato per compilare il codice; [...].

La documentazione afferma inoltre:

È possibile aggiungere a questo elenco con l'opzione della riga di comando -Idir. Tutte le directory nominate da -I vengono cercate, in ordine da sinistra a destra, prima delle directory predefinite . L'unica eccezione è quando dir è già cercato per impostazione predefinita. In questo caso, l'opzione viene ignorata e l'ordine di ricerca per le directory di sistema rimane invariato.

Per continuare il nostro #include<list> / #include"list"esempio (stesso codice):

g++ -I. main.cc

e

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

e in effetti, la -I.priorità della cartella .sul sistema include e otteniamo un errore del compilatore.


9
Voglio solo farti notare che è piuttosto strano che ti riferisci al tuo compilatore come "il tuo compilatore" poiché la domanda e la risposta hanno lo stesso autore.
Scarpa

28
@ Jeffrey: Forse l'autore della domanda intendeva adattarsi al formato generale qui. Non lo so, chiediglielo.
Sebastian Mach

1
Questa risposta è sbagliata, #include <>guarda nelle directory elencate con -Iprima delle directory di sistema predefinite
Jonathan Wakely

5
" Immagina che la tua barra dei file sia in una cartella chiamata frobnicate, relativa a foo.cc " le directory fornite con -Isono relative alla directory in cui esegui gcc, non relative al file che viene compilato. La differenza è significativa se lo faig++ -Ifrobnicate blah/foo.cc
Jonathan Wakely

3
Le impostazioni della PATHvariabile d'ambiente (su sistemi Linux) influenzano il modo in cui il compilatore cerca i file?
Matt Phillips

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.