Multiple includes with #include in C++ - c++

I have a question regarding the #include preprocessor directive in C++.
In my program I would like to include a header file from another directory. For this I have used the full path, example:
#include "full/path/to/my/header.hpp"
Now it turns out that header.hpp itself has an include (let's say #include "otherheader.hpp". During compilation, the compiler complains that it cannot find this other header.
What is the best way to handle this problem, considering the fact that I also don't want to write the full path for every header file, especially including those that are only needed "further down the tree"?

You should use your compiler's -I option.
Example with g++:
g++ -I full/path/to/my/
Then in your code you can simply put:
#include "header.hpp"
More information on search path.

Most compilers allow you to specify the root for additional include directories when compiling. For example, in Visual C++ you specify the -I flag. It's also the same for gcc. For example:
compiler -Ipath/to/headers myfile.c

Don't specify full path to includes. Specify include directories to the compiler instead and then just #include <foo> knowing that foo will be found in /some/path/foo because you told the compiler to search /some/path/ for includes. For many compilers this is done with the -I option.

Related

Setting C++ include path via program code line

There are already many options listed of how to add a path to a C++ compiler so that the #include <...> command works on these paths. However, assume that I have a single file (not an entire project) and I want to add an include path just for this file alone. I'd like to do this via a line of code within the cpp-file (say, as very first line). How is this possible? Why? Because I need to include some header file from another directory which in turn depends also on other header files within that same directory (and I get error messages that these other files could not be found due to the fact that this path was not added to the include-list).
For example:
Let's assume I want to include file_a.h in directory
.../include/extra,
I can do that via
#include <extra/file_a.h>
However, if, e.g., I do not have the extra-directory directly as a sub-directory of include, or the file_a wants to include some other file from somewhere else (maybe even /extra, but it's not a sub directory of include e.g.), then I run into trouble, because then the tracking of directories/dependencies gets hard.
I thought it would be a bad habit to change those directories via compiler, so I thought better solution would be to integrate it into the program, so no matter which compiler I use, it would work anyway without even having to think about afterwards, once specified, which directories I have to add.
Per my understanding you did:
#include <absolute/path/to/header/header.h
or
#include <relative/path/to/header/header.h
But into the header.h some other include are included.
#include <header_1.h>
#include <header_2.h>
[...]
#include <header_n.h>
Those other headers haven't relative/absolute path, so compiler doesn't know how to find them.
To solve this you can use (using gcc) the -I compiler option:
-I dir
Add the directory dir to the list of directories to be searched for header files during preprocessing. [...]
Emphasis mine
So you can use
#include <header.h>
In your file and compile it using
gcc ... -I/path/to/headers ...
When you have to specify one or more include paths in the compile command, you can do it as follows:
g++ -I/path1/to/headers -I/path2/to/headers YourProgram.cpp
Include paths tell the compiler where it finds the files it actually shall include into other files. This is (usually) controlled via compiler options as LPs explained in this answer.
C++ standard does not provide any facilities to do this from within a C++ source file and I am not aware either of any compiler extension of any vendor that would allow doing so, so bad luck...
Now depending on the IDE you are using (hopefully you are using one...), though, you most likely can add include paths for files individually there (would be a strange IDE if it didn't allow...), e. g. with eclipse + GCC, right click the file, select "Properties" -> C/C++ Build -> Tool Settings -> GCC C++ Compiler -> Includes.
Alternatively you could use a make file instead (actually, eclipse in standard settings generates one for you automatically...), which again allows you to set compiler options for each file individually - either written directly by yourself or generated by some other tools facilitating this such as cmake.

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

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,
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.
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
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)
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.

are longer #include paths ever actually needed?

For example, if I had a file called foo.h, can I always just include it by doing:
#include "foo.h"
or do I sometimes have to do something like:
#include "bar/foobar/foo.h"
EDIT - are they simply used to make the compile time shorter by limiting the search for the file?
Basically, you can pass include paths as options to the C++ compiler, but it won't look for the file recursively. If you pass in the path /opt/include and do "#include "foo.h", it will _ only_ find /opt/include/foo.h, not /opt/include/dummy/foo.h.
In other words, either you pass every possible include path on the command line, or pass the root in and "navigate" by using the #include "dummy/foo.h"
Edit: #MatthieuM. made another good point below, #include "mylibrary/api.h"makes it much clearer which include file you're using than just #include "api.h", especially if you're using multiple libraries.
The compiler isn't going to recursively search your source directory. If you want to use #include "foo.h", you'll need to compile with -Ibar/foobar to tell the compiler it should look in bar/foobar for header files.
Otherwise, you'll have to use the full (relative) path. I tend to prefer this over -I, because it makes the source more independent from compiler flags (which you'll appreciate when changing between build systems).
There may be cases where there are multiple header files with the same name - in this case, a path helps to disambiguate.
I think it depends of your project settings, for example you have section like "Additional Include Directories" in Visual C++ so IDE will also search files in these directories.
The first statement #include "foo.h" will search for foo.h in the current working directory or in the directories mentioned under additional include directories.
If your header file is in some other path you need to explicitly mention it.

in include if i use "test.h" is the same with "path/test.h"?

I am working in ubuntu under c++ language.
I have a question: i use #include"header.h". Is this the same with /path/header.h? I ask you this question because as I've seen is not the same thing. Need some explications.
I ask you this question because I've downloaded and install gsoap on my computer. I added all the necessary dependencies in a folder and I've tried to run the app without installing gsoap ...on a different computer. I had some errors..i forgot to add stdsoap2.h file...I will add it today..in my folder..
The answer is it depends:
If you have "path/" added to your include path then including only "header.h" will work because then compiler already knows the path to lookup for your header files, if not
then you have to include entire path "path/header.h" so the compiler knows where to look for the header file.
If header.h is in the directory path/, then #include "header.h" will work for those header and source files (which #include header.h which happen to be in the same directory as header.h (path/).
On the other hand, if you are #include-ing header.h in a file that is in a different directory than path/, then the above way would not work. To make it work, you can try 2 different approaches:
#include the complete path to header.h. Your #include will look something like:
#include "path/header.h"
Include the path/ directory to the makefile. This will get g++ to look for header.h in those directories as well. This can be done like so (in the makefile):
g++ <some parameters> -Ipath/ -c main.cpp -o main.o (assuming header.h is called from within main.cpp). If you choose this way, then the #include will also change, like so:
#include <header.h>. Note the use of the -I flag as a parameter to g++. That flag tells g++ to look into additional directories as well.
No, they are not the same, conceptually. The results, however, could be the same. It depends on how you tell your compiler to find headers (the -I flag in g++). If you would compile with -I /path/, then you'd find /path/header.h with #include "header.h". If you do not use that include path flag, then you'd have to write #include "/path/header.h".

How does C++ handle multiple source files?

I'm studying C++ right now, coming from a background in Python, and I'm having some trouble understanding how C++ handles multiple source files. In Python, the import statement first checks the current working directory for the module you're trying to import and then it checks the directories in sys.path. In C++, where would I place a custom made .h file? Where would the compiler even look?
For example, I've got a program, foo.exe compiled from a single source file, foo.cpp, both in the same directory. I decide that I want to organize things a little better, so I create a new .h file, bar.h and dump stuff in there. Would I just need to #include to get to the stuff I put there? What if I want to use bar.h with another program (in a completely different directory)?
There are two include variants:
#include "path-spec"
#include <path-spec>
Quote notation:
This form instructs the preprocessor to look for include files in the same directory of the file that contains the #include statement, and then in the directories of any files that include (#include) that file.
The bracket notation looks for header files in certain defined locations.
With gcc you can get some information about these pathes via:
$ echo | gcc -v -x c++ -E -
Compilers accept
-I or /I
options to add additional pathes.
It (generally) looks in the include path if you use #include <foo>, else it uses relative paths if you use #include "../../foo/bar.h".
You set the include path with -I or /I on most compilers. Consult its manual for details.
Don't define any objects in headers though -- you will have multiple definition errors at link time if you do (and include the header in multiple source files).
It works in a similar way. The #include only is used by the compiler. In execution time the file bar.h doesn't gets used. But in compile time it is.
In compile time, the file could be in two places:
1.- The current directory (as in python)
2.- The directories configured in your include path. Where to configure that directories depends of the compiler you are using. Most of them let you define the include directories in the compile command line. And most IDEs let you configure it in some Options menu.
Hope it helps.
If your header files are in the same dir, you can include them like:
#include "bar.h"
If you want to include this header from another dir:
#include "../foobar/bar.h"
Basically quotations mean to search from current directory and brackets like in #include <abc.h> mean to search in standard header file directories. You can add custom directories to the standard search path by adding a -I /path/to/your/custom/headers in the compile command.
#include with angle brackets looks in the system include directories. Like this:
#include <iostream>
With double quotes it looks in the current directory and other directories given to the compiler to search.
#include "foo.h"
g++ -I../include foo.cpp
the thing you are missing in the python model is the linker.
in python you import code and its interpreted right there and then. in c/c++ you compile each source file into an object file. You then tell the linker to collect a bunch of object files into an executable
Typically the includes in c/c++ source files only contain descriptions of whast in the other C files (the names of functions, etc) not the function contents. This is enough for the compiler to compile a given file. Then the linker will combine your object files with libraries of 'well known' functions and make an executable