gcc / g ++:“没有这样的文件或目录”


87

g++ 给我以下形式的错误:

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

使用编译C程序时相同gcc

这是为什么?


请注意:这个问题已经被问过很多次了,但是每次都针对询问者的情况。这个问题的目的是要提出一个问题,即其他人可以作为的复制品一劳永逸地关闭;一个常见问题


4
很好的常见问题解答。谢谢!
2012年

Answers:


117

您的编译器只是尝试编译名为的文件foo.cc。达到行号时line,编译器会发现:

#include "bar"

要么

#include <bar>

然后,编译器尝试查找该文件。为此,它使用一组目录进行查询,但是在该目录中没有file bar。有关include语句版本之间差异的解释,请参见此处

如何告诉编译器在哪里找到它

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

The priority with #include "bar" is leftmost:

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

As you see, when the compiler started looking through A/, B/ and C/, it stopped at the first or leftmost hit.

This is true of both forms, include <> and incude "".

Difference between #include <bar> and #include "bar"

Usually, the #include <xxx> makes it look into system folders first, the #include "xxx" makes it look into the current or custom folders first.

E.g.:

Imagine you have the following files in your project folder:

list
main.cc

with main.cc:

#include "list"
....

For this, your compiler will #include the file list in your project folder, because it currently compiles main.cc and there is that file list in the current folder.

But with main.cc:

#include <list>
....

and then g++ main.cc, your compiler will look into the system folders first, and because <list> is a standard header, it will #include the file named list that comes with your C++ platform as part of the standard library.

This is all a bit simplified, but should give you the basic idea.

Details on <>/""-priorities and -I

According to the gcc-documentation, the priority for include <> is, on a "normal Unix system", as follows:

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

For C++ programs, it will also look in /usr/include/c++/version, first. In the above, target is the canonical name of the system GCC was configured to compile code for; [...].

The documentation also states:

You can add to this list with the -Idir command line option. All the directories named by -I are searched, in left-to-right order, before the default directories. The only exception is when dir is already searched by default. In this case, the option is ignored and the search order for system directories remains unchanged.

To continue our #include<list> / #include"list" example (same code):

g++ -I. main.cc

and

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

and indeed, the -I. prioritizes the folder . over the system includes and we get a compiler error.


9
Just want to make you notice that it's kinda weird that you refer to your compiler as "your compiler" since the question and the answer has the same author.
Shoe

27
@Jeffrey: Maybe the author of the question intended to fit the general format here. Dunno, ask him.
Sebastian Mach

1
This answer is wrong, #include <> looks in the dirs listed with -I before default system dirs
Jonathan Wakely

5
"Imagine that your file bar is in a folder named frobnicate, relative to foo.cc" the dirs given with -I are relative to the dir where you run gcc, not relative to the file being compiled. The difference is significant if you do g++ -Ifrobnicate blah/foo.cc
Jonathan Wakely

3
Do the settings of your PATH environmental variable (on Linux systems) affect how the compiler searches for files at all?
Matt Phillips
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.