Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gcc/g++: "No such file or directory"

Tags:

c++

c

c++-faq

gcc

g++

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.

like image 779
Sebastian Mach Avatar asked Oct 16 '12 16:10

Sebastian Mach


People also ask

How do I fix G ++ EXE error?

The easy fix for this is to rename the file to remove the space. I highly recommend avoiding spaces in paths or file names with c or c++ regardless of how you build to avoid issues like this.

How do I fix No such file or directory in VS code?

Try reinstalling mingw. Basically, the problem is with header files. I think you should try reinstalling mingw, adding it to system path again or try installing the extension in vscode. Hope this helped.


1 Answers

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.

like image 167
Sebastian Mach Avatar answered Sep 20 '22 17:09

Sebastian Mach