gcc / g ++:“ ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว”


88

g++ ทำให้ฉันมีข้อผิดพลาดของแบบฟอร์ม:

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

จะเหมือนกันเมื่อคอมไพล์โปรแกรม C ด้วยgcc.

ทำไมถึงเป็นเช่นนั้น?


โปรดทราบ:คำถามนี้ถูกถามหลายครั้งก่อนหน้านี้ แต่ทุกครั้งจะเฉพาะเจาะจงสำหรับสถานการณ์ของผู้ถาม จุดประสงค์ของคำถามนี้คือการมีคำถามที่ผู้อื่นสามารถปิดเป็นรายการที่ซ้ำกันได้ทุกครั้ง คำถามที่พบบ่อย


4
นอกจากนี้ยังมีคำถามที่พบบ่อย ขอบคุณ!
sbi

คำตอบ:


119

คอมไพเลอร์ของคุณเพิ่งพยายามรวบรวมไฟล์ชื่อfoo.cc. เมื่อกดปุ่มหมายเลขบรรทัดlineคอมไพเลอร์จะพบ:

#include "bar"

หรือ

#include <bar>

จากนั้นคอมไพเลอร์จะพยายามค้นหาไฟล์นั้น สำหรับเรื่องนี้มันจะใช้ชุดของไดเรกทอรีที่จะเข้าไปดู barแต่ภายในชุดนี้ไม่มีแฟ้ม สำหรับคำอธิบายของความแตกต่างระหว่างรุ่นของ ๆ รวมถึงการดูคำสั่งที่นี่

จะบอกคอมไพเลอร์ได้อย่างไรว่าจะหาได้ที่ไหน

g++-Iมีตัวเลือก ช่วยให้คุณเพิ่มรวมเส้นทางการค้นหาลงในบรรทัดคำสั่ง ลองนึกภาพว่าไฟล์ของคุณbarอยู่ในโฟลเดอร์ที่มีชื่อfrobnicateสัมพันธ์กับfoo.cc(สมมติว่าคุณกำลังรวบรวมจากไดเร็กทอรีที่foo.ccอยู่):

g++ -Ifrobnicate foo.cc

คุณสามารถเพิ่มเส้นทางรวมเพิ่มเติมได้ แต่ละรายการที่คุณให้นั้นสัมพันธ์กับไดเร็กทอรีปัจจุบัน คอมไพเลอร์ของ Microsoft มีตัวเลือกที่สัมพันธ์กัน/Iซึ่งทำงานในลักษณะเดียวกันหรือใน Visual Studio สามารถตั้งค่าโฟลเดอร์ในหน้าคุณสมบัติของโครงการภายใต้คุณสมบัติการกำหนดค่า -> C / C ++ -> ทั่วไป -> ไดเรกทอรีรวมเพิ่มเติม

ตอนนี้ลองนึกภาพคุณมีหลายเวอร์ชันbarในโฟลเดอร์ต่างๆโดยให้:


// 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"ซ้ายสุด:

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

ในขณะที่คุณเห็นเมื่อคอมไพเลอร์เริ่มมองผ่านA/, B/และC/ก็หยุดที่ตีครั้งแรกหรือซ้ายสุด

นี่คือความจริงของทั้งสองรูปแบบและinclude <>incude ""

ความแตกต่างระหว่าง#include <bar>และ#include "bar"

โดยปกติแล้วสิ่งที่#include <xxx>ทำให้ดูเป็นโฟลเดอร์ระบบก่อน#include "xxx"ทำให้ดูเป็นโฟลเดอร์ปัจจุบันหรือโฟลเดอร์ที่กำหนดเองก่อน

เช่น:

สมมติว่าคุณมีไฟล์ต่อไปนี้ในโฟลเดอร์โครงการของคุณ:

list
main.cc

กับmain.cc:

#include "list"
....

สำหรับสิ่งนี้คอมไพลเลอร์ของคุณจะ#includeเก็บไฟล์listไว้ในโฟลเดอร์โปรเจ็กต์ของคุณเนื่องจากคอมไพเลอร์ในปัจจุบันmain.ccและมีไฟล์นั้นlistอยู่ในโฟลเดอร์ปัจจุบัน

แต่ด้วยmain.cc:

#include <list>
....

จากนั้นg++ main.ccคอมไพเลอร์ของคุณจะมองเข้าไปในโฟลเดอร์ระบบก่อนและเนื่องจาก<list>เป็นส่วนหัวมาตรฐาน#includeไฟล์listที่มาพร้อมกับแพลตฟอร์ม C ++ ของคุณจะเป็นส่วนหนึ่งของไลบรารีมาตรฐาน

ทั้งหมดนี้ง่ายขึ้นเล็กน้อย แต่ควรให้แนวคิดพื้นฐานแก่คุณ

รายละเอียดเกี่ยวกับ<>/ - ""ลำดับความสำคัญและ-I

ตามเอกสาร gccลำดับความสำคัญสำหรับinclude <>"ระบบ Unix ปกติ" ดังต่อไปนี้:

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

สำหรับโปรแกรม C ++ จะมีลักษณะใน / usr / include / c ++ / version ก่อนเช่นกัน ในข้างต้นเป้าหมายคือชื่อมาตรฐานของระบบ GCC ถูกกำหนดค่าให้คอมไพล์โค้ดสำหรับ; [... ].

เอกสารยังระบุ:

คุณสามารถเพิ่มในรายการนี้ด้วยตัวเลือกบรรทัดคำสั่ง -Idir ไดเรกทอรีทั้งหมดตั้งชื่อโดย -I จะค้นหาในซ้ายไปขวาสั่งซื้อก่อนที่จะเริ่มต้นไดเรกทอรี ข้อยกเว้นเพียงอย่างเดียวคือเมื่อ dir ถูกค้นหาตามค่าเริ่มต้นแล้ว ในกรณีนี้อ็อพชันจะถูกละเว้นและลำดับการค้นหาไดเร็กทอรีระบบจะไม่เปลี่ยนแปลง

เพื่อดำเนินการต่อ#include<list> / #include"list"ตัวอย่างของเรา(รหัสเดียวกัน):

g++ -I. main.cc

และ

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

และแน่นอนว่าการ-I.จัดลำดับความสำคัญของโฟลเดอร์.เหนือระบบรวมถึงและเราได้รับข้อผิดพลาดของคอมไพเลอร์


9
แค่อยากให้คุณสังเกตว่ามันแปลกมากที่คุณอ้างถึงคอมไพเลอร์ของคุณว่า "คอมไพเลอร์ของคุณ" เนื่องจากคำถามและคำตอบมีผู้เขียนคนเดียวกัน
รองเท้า

28
@ เจฟฟรีย์: บางทีผู้เขียนคำถามตั้งใจให้พอดีกับรูปแบบทั่วไปที่นี่ Dunno ถามเขา
Sebastian Mach

1
คำตอบนี้ไม่ถูกต้อง#include <>ดูใน dirs ที่ระบุไว้-Iก่อนระบบเริ่มต้น
Jonathan Wakely

5
" ลองนึกภาพว่าแถบไฟล์ของคุณอยู่ในโฟลเดอร์ชื่อ frobnicate ซึ่งสัมพันธ์กับ foo.cc " dirs ที่ให้มา-Iนั้นสัมพันธ์กับ dir ที่คุณเรียกใช้ gcc ไม่สัมพันธ์กับไฟล์ที่กำลังคอมไพล์ ความแตกต่างมีความสำคัญถ้าคุณทำg++ -Ifrobnicate blah/foo.cc
Jonathan Wakely

3
การตั้งค่าPATHตัวแปรสภาพแวดล้อมของคุณ(บนระบบ Linux) มีผลต่อการที่คอมไพลเลอร์ค้นหาไฟล์หรือไม่?
Matt Phillips

-1

สิ่งนี้ใช้ได้กับฉัน sudo apt-get install libx11-dev


สิ่งนี้ไม่ได้ให้คำตอบสำหรับคำถาม เมื่อคุณมีเพียงพอชื่อเสียงคุณจะสามารถที่จะแสดงความคิดเห็นในโพสต์ใด ๆ ; แทนที่จะให้คำตอบที่ไม่จำเป็นต้องชี้แจงจากผู้ถาม - จากรีวิว
Cartucho
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.