g++
给我以下形式的错误:
foo.cc:<line>:<column>: fatal error: <bar>: No such file or directory
compilation terminated.
使用编译C程序时相同gcc
。
这是为什么?
请注意:这个问题已经被问过很多次了,但是每次都针对询问者的情况。这个问题的目的是要提出一个问题,即其他人可以作为的复制品一劳永逸地被关闭;一个常见问题。
你的编译器只是尝试编译名为的文件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;
}
的优先级#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>
它是标准标头,因此它将作为C ++平台随附的#include
名为list
标准库的一部分的文件。
这一切都得到了简化,但是应该给你基本的思想。
<>
/-""
优先级的详细信息和-I
根据gcc-documentation,在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.
优先级.
高于系统包含的文件夹,我们会遇到编译器错误。
只是想让您注意到,将问题的编译器称为“您的编译器”有点奇怪,因为问题和答案的作者相同。
@Jeffrey:也许是该问题的作者打算适合此处的一般格式。邓诺,问他。
这个答案是错误的,在默认系统目录之前
#include <>
查找目录中列出的-I
目录“假设您的文件栏位于相对于foo.cc的名为frobnicate的文件夹中, ”给出的目录
-I
是相对于运行gcc的目录,而不是相对于正在编译的文件。如果您这样做,差异是很明显的g++ -Ifrobnicate blah/foo.cc
PATH
(在Linux系统上)环境变量的设置是否会影响编译器搜索文件的方式?