g++
给我以下形式的错误:
foo.cc:<line>:<column>: fatal error: <bar>: No such file or directory
compilation terminated.
使用编译C程序时相同gcc
。
这是为什么?
请注意:这个问题已经被问过很多次了,但是每次都针对询问者的情况。这个问题的目的是要提出一个问题,即其他人可以作为的复制品一劳永逸地关闭;一个常见问题。
Answers:
您的编译器只是尝试编译名为的文件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 ""
.
#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.
<>
/""
-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.
#include <>
looks in the dirs listed with -I
before default system dirs
-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
PATH
environmental variable (on Linux systems) affect how the compiler searches for files at all?