gcc / g ++: "Böyle bir dosya veya dizin yok"


88

g++ bana şu biçimde hatalar veriyor:

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

C programları ile derlerken de aynıdır gcc.

Neden?


Lütfen dikkat: Bu soru daha önce birçok kez sorulmuştu, ancak her seferinde soran kişinin durumuna özeldi. Bu sorunun amacı, başkalarının bir kerede ve tamamen kopyaları olarak kapatılabileceği bir soru sormaktır ; bir SSS .


4
SSS'ye güzel bir ek. Teşekkürler!
sbi

Yanıtlar:


119

Derleyiciniz adlı dosyayı derlemeye çalıştı foo.cc. Satır numarasına lineulaşıldığında derleyici şunları bulur:

#include "bar"

veya

#include <bar>

Derleyici daha sonra bu dosyayı bulmaya çalışır. Bunun için, bakmak için bir dizi dizin kullanır, ancak bu kümede dosya yoktur bar. İnclude ifadesinin sürümleri arasındaki farkın açıklaması için buraya bakın .

Derleyiciye onu nerede bulacağını söyleme

g++bir seçeneği var -I. Komut satırına dahil arama yolları eklemenizi sağlar. Dosyanızın (bulunduğu dizinden derlediğinizi varsayın) şuna göre baradlı bir klasörde olduğunu hayal edin :frobnicatefoo.ccfoo.cc

g++ -Ifrobnicate foo.cc

Daha fazla içerme yolu ekleyebilirsiniz; verdiğiniz her biri o anki dizine bağlıdır. Microsoft'un derleyicisinin /Iaynı şekilde çalışan bir ilişkilendirme seçeneği vardır veya Visual Studio'da klasörler, Konfigürasyon Özellikleri-> C / C ++ -> Genel-> Ek Dahil Etme Dizinleri altında Projenin Özellik Sayfalarında ayarlanabilir.

Şimdi bar, farklı klasörlerde birden çok sürümünüzün olduğunu düşünün :


// 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;
}

#include "bar"İle öncelik en soldadır:

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

Gördüğünüz gibi, derleyici başladığında bakarak A/, B/ve C/, ilk veya en soldaki hit durdu.

Bu her iki form için de geçerlidir include <>ve incude "".

Fark arasında #include <bar>ve#include "bar"

Genellikle, önce #include <xxx>sistem klasörlerine #include "xxx"bakmasını sağlar, önce geçerli veya özel klasörlere bakmasını sağlar.

Örneğin:

Proje klasörünüzde aşağıdaki dosyaların bulunduğunu hayal edin:

list
main.cc

ile main.cc:

#include "list"
....

Bunun için derleyiciniz proje klasörünüzdeki #includedosyayı olacaktır list, çünkü şu anda derlenmektedir main.ccve bu dosya listmevcut klasörde bulunmaktadır.

Ancak şu şekilde main.cc:

#include <list>
....

ve daha sonra g++ main.cc, derleyiciniz önce sistem klasörlerine bakacak ve <list>standart bir başlık olduğu için , standart kitaplığın bir parçası olarak C ++ platformunuzla birlikte gelen #includeadlı dosya olacaktır list.

Bunların hepsi biraz basitleştirilmiştir, ancak size temel fikri vermelidir.

İlgili ayrıntılar <>/ ""-priorities ve-I

Göre gcc-dokümantasyon için öncelik include <>"normal Unix sisteminde" olduğundan, aşağıdaki gibi:

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

C ++ programları için, önce / usr / include / c ++ / version dizinine de bakacaktır. Yukarıda, hedef, GCC'nin kod derlemek için yapılandırıldığı sistemin kanonik adıdır; [...].

Belgelerde ayrıca şunlar belirtilmektedir:

-Idir komut satırı seçeneği ile bu listeye ekleyebilirsiniz. Varsayılan dizinlerden önce -I ile adlandırılan tüm dizinler soldan sağa sırayla aranır . Tek istisna, dir zaten varsayılan olarak aranmış olmasıdır. Bu durumda, seçenek göz ardı edilir ve sistem dizinleri için arama sırası değişmeden kalır.

#include<list> / #include"list"Örneğimize devam etmek için (aynı kod):

g++ -I. main.cc

ve

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

ve gerçekten, sistem içerir ve -I.klasöre öncelik verir .ve derleyici hatası alırız.


9
Soru ve yanıt aynı yazara sahip olduğu için derleyicinize "derleyiciniz" olarak başvurmanızın biraz tuhaf olduğunu fark etmenizi sağlamak istiyorum.
Ayakkabı

28
@Jeffrey: Belki de sorunun yazarı buradaki genel formata uymayı amaçlamıştır. Dunno, sor ona.
Sebastian Mach

1
Bu cevap yanlış, varsayılan sistem dizinlerinden önce #include <>listelenen dizinlere bakar-I
Jonathan Wakely

5
" Dosya çubuğunuzun foo.cc'ye göre frobnicate adlı bir klasörde olduğunu hayal edin " ile verilen dizinler -I, derlenen dosyaya göre değil, gcc'yi çalıştırdığınız dizine göredir . Eğer yaparsanız fark önemlig++ -Ifrobnicate blah/foo.cc
Jonathan Wakely

3
PATHÇevresel değişkeninizin ayarları (Linux sistemlerinde) derleyicinin dosyaları arama şeklini etkiliyor mu?
Matt Phillips

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.