118

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.

Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130

3 Answers3

153

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.

Community
  • 1
  • 1
Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130
  • 12
    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 Oct 16 '12 at 16:31
  • 36
    @Jeffrey: Maybe the author of the question intended to fit the general format here. Dunno, ask him. – Sebastian Mach Oct 16 '12 at 16:33
  • 1
    This answer is wrong, `#include <>` looks in the dirs listed with `-I` before default system dirs – Jonathan Wakely Oct 17 '12 at 23:42
  • 6
    "_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 Oct 17 '12 at 23:46
  • @JonathanWakely: Thanks for pointing those out, I changed the answer accordingly. Seems like I exercised the `-I`/`<>`-test wrongly. – Sebastian Mach Oct 18 '12 at 05:45
  • 3
    Do the settings of your `PATH` environmental variable (on Linux systems) affect how the compiler searches for files at all? – Matt Phillips Nov 11 '12 at 03:27
  • when using `#include "bar"` the compiler will look in the current directory _first_, before searching any other paths. Where the compiler looks for `#include ` is implementation defined (you mentioned the gcc implementation). Some implementations may search the current directory, but only `#include "bar"` is obligated to. Similarly, `#include "bar"` is not obligated to search all the compiler-defined directories that `#include ` does. The best advice is to use `"bar"` for user headers and `` for system headers (what constitutes a system header may be project-dependent) – jwm Oct 14 '21 at 20:03
0

Also, there apprears to be a compiler bug in that if you include the characters "struct" or "Struct" in your header filename, the compiler will throw the same "no such file or directory" error.

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 25 '21 at 20:54
  • If you have a new question, please ask it by clicking the [Ask Question](https://stackoverflow.com/questions/ask) button. Include a link to this question if it helps provide context. - [From Review](/review/late-answers/30174997) – Yang Yushi Oct 25 '21 at 23:54
-5

this works for me, sudo apt-get install libx11-dev