How to make C/C++ compiler to look for headers in a user specified path

9.1k Views Asked by At

I'm using a library written by others which is kinda based on C for C++ usage -I think-. All inclusions used inside the headers or source files are in the form <> instead of "" even though they are not standard library files. My compiler doesn't recognize them and returns error "file not found"

An example of the problem is inside the following header:

#ifndef _ga_ga_h_
#define _ga_ga_h_

// Make sure that we get the configuration into each of the galib components
// that will be used.
#include <ga/gaconfig.h>

// These are the headers for all of the genetic algorithm classes.
#include <ga/GASimpleGA.h>
#include <ga/GASStateGA.h>
#include <ga/GAIncGA.h>
#include <ga/GADemeGA.h>
#include <ga/GADCrowdingGA.h>

// Here we include the headers for all of the various genome types.
#include <ga/GA1DBinStrGenome.h>
#include <ga/GA2DBinStrGenome.h>
#include <ga/GA3DBinStrGenome.h>
#include <ga/GABin2DecGenome.h>

I include that header inside my program using #include "ga.h" but it is very hard to change inside every header/source file in the library.

Is there a way to make the compiler use <> as if they were ""? I tried adding the paths to "Addition include directories"from Project properties (I'm using Visual Studio), Many inclusions' errors disappeared but around 30 persisted. The strange thing is that they are in a file called "c1xx" but i don't have that file!!

thanks,

4

There are 4 best solutions below

12
On

The definition is somewhat that <> is used for "system" header files, usually found in locations like /usr/include (on Unix-like systems) and "" is used for local header files. When you compile your code, you can indicate the location of additional directories containing header files e.g. using the -I option when using GCC. Check your compiler's documentation for the setting needed

So, e.g. on Linux and GCC, if your "ga" directory is in /usr/local/include/ga, you would use cc -I /usr/local/include.

5
On

If you do on the command line:

echo | gcc -v -E -x c++ -

You will get an output with the default include directories for C++. Those are the built in system's include search paths.

If you compile with g++ -I/some/dir -o foo foo.cpp, you are adding an additional include search path (/some/dir) to the compilation.

Headers in the above locations can be found by include directives like #include <header>. #include "header" directives can also find headers in those locations, but they are more relevant for the following case.

When you do #include "header", your compiler will first try to find "header" relative to the directory of foo.cpp if it includes it, despite foo.cpp directory being in search paths or not. If it doesn't find it there, it will try to look up in the include search paths. So this one is more relevant for headers that are more tied to a specific .cpp file and you don't want additional include search paths added to the compilation, or if you prefer to use include directives with relative paths.

So if you use #include <header>, header must be in some of the include search paths, system or /some/dir from -I flag. If header is relative to foo.cpp, but not in search paths, compilation will fail.

If you use #include "header" and header is not in any of the include search paths, it can still be found relative to foo.cpp location.

0
On

This indeed looks like a problem of telling the compiler where to look for the included header files. As mentioned in the other answers, when you do a #include <header.h>, header.h must be in one of the include search paths - either the system includes, or the additional paths that you are telling the compiler to look for headers. In Linux/g++ (as mentioned in the other answers here), you do that by passing in the the additional search paths in the -I flag. The compilation command would look something like:

g++ -I/additional/header/search/path -o a.out your_file.cpp

Since you are using visual studio and the MSVC compiler, the equivalent would be the /I flag, and the compilation command would look something like:

CL /I\additional\header\path your_file.cpp

I am assuming you are using Visual Studio - you can also configure that from the project properties. Go to Configuration Properties > C/C++ > General and modify Additional Include Directories. Refer these for more info:

Setting C++ compiler and build properties

Additional include directories

0
On

First about the difference between <header> and <file>. The standards (both C and C++) only specifies that

#include <header>

includes an header named header and that

#include "file"

includes a source file named file, if none is found an header named file is included instead.

What are headers and how they differ from source files is left to the implementation. In practice they are files as well. So #include <header> is looking for a file in some places, #include "file" is looking for a file in some other places and if not found at the same places as for #include <file>.

AFAIK all compilers

  • are able to search for source files in the directory of the file containing the include directive

  • are able to be given a list of directories to search for headers before their default search path.

ISTR that Visual C++ is also searching for a source file in the directories of files indirectly including it. (I can't confirm currently if my memory is good; that behavior is AFAIK unachievable with other compilers so I never relied on it and -- by luck? -- it never resulted in a different behavior for my programs).

Obviously that behavior is more or less customizable. For instance with g++ is possible to:

  • disable the search of a source file in the directory of the file containing the include directive (with -I-, note that -I- is deprecated since gcc 4.0 -- 2005 -- when -iquote has been introduced and there is no non-deprecated way to achieve this)

  • to add a list of directories to search for source files and not for headers (with -iquote and it's an effect of -I- as well)

  • to give a list of directories to search for headers after the default list of directories (with -idirafter)

  • to give a list of directories to search for headers which are processed specially (with -isystem; less warnings are given for constructs in those files which help when using the "treat warnings as errors" flags, they aren't considered as dependencies with -MM and -MMD which usually is a nuisance)


Now for your problem. The library has been visibly designed to be used by adding the directory containing the directory ga to the include path. That should be enough as I'm unaware of any compiler modifying its search path for headers depending on how the file including the header has been included.

Note that c1xx is probably the name of the compiler executable, not the name of a file trying to include another (again, I'm not in position to ensure that's the case now, but compare with cc1plus which is the name of the compiler for GCC -- g++ is a driver handling several things and executing cc1plus to handle the compilation of C++ code)