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

2021-12-18 00:00:00 gcc c g++ c++ c++-faq

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

foo.cc::: 致命错误: : 没有那个文件或目录编译终止.

gcc编译C程序也是一样.

这是为什么?

<小时>

请注意:这个问题以前被问过很多次,但每次都是针对提问者的情况.这个问题的目的是提出一个问题,其他人可以一劳永逸地将其复制为;一个常见问题.

解决方案

您的编译器刚刚尝试编译名为 foo.cc 的文件.在点击行号 line 后,编译器发现:

#include "bar"

#include 

然后编译器尝试找到该文件.为此,它使用一组目录来查看,但在该组中,没有文件 bar.有关包含语句版本之间差异的解释,请查看 这里.

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

g++ 有一个选项 -I.它允许您向命令行添加包含搜索路径.假设您的文件 bar 位于名为 frobnicate 的文件夹中,相对于 foo.cc(假设您正在从 foo.cc 所在):

g++ -Ifrobnicate foo.cc

您可以添加更多包含路径;你给的每一个都是相对于当前目录的.Microsoft 的编译器有一个相关选项 /I 以相同的方式工作,或者在 Visual Studio 中,可以在项目的属性页中设置文件夹,在 Configuration Properties->C/C++->常规-> 其他包含目录.

现在假设您在不同的文件夹中有多个版本的 bar,给定:

<小时>

//A/bar#include<字符串>std::string which() { return "A/bar";}

<小时>

//B/bar#include<字符串>std::string which() { return "B/bar";}

<小时>

//C/bar#include<字符串>std::string which() { return "C/bar";}

<小时>

//foo.cc#包括酒吧"#include int主(){std::cout <<哪个()<

<小时>

#include "bar" 的优先级是最左边的:

$ g++ -IA -IB -IC foo.cc$ ./a.out一间酒吧

如您所见,当编译器开始查看 A/B/C/ 时,它停在第一个或最左边命中.

这两种形式都是如此,include <>incude "".

#include #include "bar" 的区别

通常,#include 使它首先查看系统文件夹,#include "xxx" 使它首先查看当前或自定义文件夹.

例如:

假设您的项目文件夹中有以下文件:

列表主文件

main.cc:

#include "list"....

为此,您的编译器将#include 文件list 在您的项目文件夹中,因为它当前编译main.cc 并且有该文件 list 在当前文件夹中.

但是使用 main.cc:

#include ....

然后是g++ main.cc,你的编译器会首先查看系统文件夹,因为是一个标准头文件,它会#include 名为 list 的文件,它作为标准库的一部分随您的 C++ 平台提供.

这有点简化,但应该给你基本的想法.

<>/""-priorities 和 -I

的详细信息

根据gcc-documentation,include <> 在普通 Unix 系统"上,如下所示:

/usr/local/includelibdir/gcc/target/version/include/usr/目标/包括/usr/包括

<块引用>

对于 C++ 程序,它也会首先在/usr/include/c++/version 中查找.在上面,target 是 GCC 被配置为编译代码的系统的规范名称;[...].

文档还指出:

<块引用>

您可以使用 -Idir 命令行选项添加到此列表中.所有以 -I 命名的目录都按从左到右的顺序搜索,在默认目录之前.唯一的例外是默认情况下已经搜索了 dir.在这种情况下,该选项将被忽略,系统目录的搜索顺序保持不变.

继续我们的#include/#include"list" 示例(代码相同):

g++ -I.主文件

#includeint main () { std::list升;}

事实上,-I. 将文件夹 . 优先于系统包含,我们得到一个编译器错误.

g++ gives me errors of the form:

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

It is the same when compiling C-programs with gcc.

Why is that?


Please note: This question has been asked many times before, but each time it was specific to the askers situation. This question's purpose is to have a question that others can be closed as duplicates of, once and for all; a FAQ.

解决方案

Your compiler just tried to compile the file named foo.cc. Upon hitting line number line, the compiler finds:

#include "bar"

or

#include <bar>

The compiler then tries to find that file. For this, it uses a set of directories to look into, but within this set, there is no file bar. For an explanation of the difference between the versions of the include statement look here.

How to tell the compiler where to find it

g++ has an option -I. It lets you add include search paths to the command line. Imagine that your file bar is in a folder named frobnicate, relative to foo.cc (assume you are compiling from the directory where foo.cc is located):

g++ -Ifrobnicate foo.cc

You can add more include-paths; each you give is relative to the current directory. Microsoft's compiler has a correlating option /I that works in the same way, or in Visual Studio, the folders can be set in the Property Pages of the Project, under Configuration Properties->C/C++->General->Additional Include Directories.

Now imagine you have multiple version of bar in different folders, given:


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

相关文章