I have never used a package manager for C++ packages until today. I finally got one to semi work, called cget. I'm trying to use a package called nlohmann/json and from their documentation I just need to run cget install nlohmann/json. The issue is that this puts the include header files in the directory /cget/include/nlohmann which (I assume) the g++ compiler doesn't look in for headers. So I manually moved the nlohmann directory into the /usr/include directory. When I compile with g++ test.cpp -o test it fails with the error "No such file of directory". I clearly see the file in the include path, so what am I missing?
// test.cpp
#include <nlohmann/json.hpp>
I've tried using the Include flag g++ -I /usr/include test.cpp -o test and it still fails.
The path to the json.hpp file is /usr/include/nlohmann/json.hpp
When I run `g++ -print-prog-name=cc1plus` -v it gives:
#include "..." search starts here:
#include <...> search starts here:
/usr/include/c++/9
/usr/include/x86_64-linux-gnu/c++/9
/usr/include/c++/9/backward
/usr/lib/gcc/x86_64-linux-gnu/9/include
/usr/local/include
/usr/include
End of search list.
What is causing this error to persist?
Is there a way to tell gcc/g++/clang where to look for headers that are included via angle brackets ("<", ">")?
I don't use the angle bracket convention for non-system files, but the problem is that when I try using the headers from some packages I download, I get errors for all of the included files.
For example, say I want to include headers from a module called Foo that I download:
/foo-v1.0/include/DependencyA.hpp:
#ifndef DEP_A_HPP
#define DEP_A_HPP
class DependencyA
{
...
};
#endif
/foo-v1.0/include/Api.hpp:
#ifndef FOO_HPP
#define FOO_HPP
#include <Foo/DependencyA.hpp>
void doSomething(DependencyA* da);
#endif
Then, in my own code:
/mycode.cpp:
#include "/foo-v1.0/include/Api.hpp"
DependencyA* da = new DependencyA();
doSomething(da);
I get a compile error:
fatal error: 'Foo/DependencyA.hpp' file not found
I've tried building with:
clang -c mycode.cpp -isystem./foo-v1.0/include -o mycode.o
clang -c mycode.cpp -isystem./foo-v1.0/include/ -o mycode.o
clang -c mycode.cpp -I./foo-v1.0/include -o mycode.o
clang -c mycode.cpp -I./foo-v1.0/include/ -o mycode.o
and so on, to no avail.
How do I tell the compiler to resolve <Foo/**/*> to a particular root directory for every included file?
The answer is already in the comments.
To check include dirs one can use the method described here: What are the GCC default include directories? , preferably with - replaced with /dev/null:
clang -xc -E -v /dev/null
On my machine for clang it gives
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/lib/clang/11.0.0/include
/usr/include
End of search list.
To discover how to manipulate this list, it suffices to read the gcc (or clang) manual (man clang or find it in the Internet, for example, https://man7.org/linux/man-pages/man1/gcc.1.html ). For gcc this reads:
Options for Directory Search
These options specify directories to search for header files, for
libraries and for parts of the compiler:
-I dir
-iquote dir
-isystem dir
-idirafter dir
Add the directory dir to the list of directories to be searched
for header files during preprocessing. If dir begins with = or
$SYSROOT, then the = or $SYSROOT is replaced by the sysroot
prefix; see --sysroot and -isysroot.
Directories specified with -iquote apply only to the quote form
of the directive, "#include "file"". Directories specified with
-I, -isystem, or -idirafter apply to lookup for both the
"#include "file"" and "#include <file>" directives.
This description is followed by a detailed description of the order in which header files are searched and by some recommendations as to which option to use for which purpose. You'll find it in the manual. Search for "Options for Directory Search".
What I really don't like in your code is this line:
#include "/foo-v1.0/include/Api.hpp"
It seems to contain the absolute path to the header and I've never seen anything like this. I would change it to
#include "Api.hpp"
with /foo-v1.0/include being added to the search list via the usual compiler -I command-line option.
I'm getting the error
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\cstdlib:75:25: fatal error: stdlib.h: No such file or directory
#include_next <stdlib.h>
when adding C:\MinGW\include to the compiler include search path:
echo "#include <cstdlib>" | g++ -x c++ - -isystem C:/MinGW/include -o /dev/nul
But CMake does this because some libraries (libcurl e.g.) are installed into C:\MinGW hence the curl include dir is C:\MinGW\include
Am I doing something wrong or is this a bug in MinGW?
I'm using MinGW 5.0.1.
What works: echo "#include <cstdlib>" | g++ -x c++ - -IC:/MinGW/include -o /dev/nul but I don't want to include the curl include dirs etc. as non-system includes.
Related to mingw/include/c++/cstdlib: stdlib.h: No such file or directory
Background: I'm using cmake to generate the makefiles. So there is a find_package(Curl) and a include_directories(SYSTEM CURL_INCLUDE_DIRS) in the CMakelists.txt. As libcurl is installed to C:/MinGW the CURL_INCLUDE_DIRS will be C:/MinGW/include and hence the -isystem include. I don't want to omit the SYSTEM because this might cause warnings to be generated for the libcurl headers. Of course there are more libraries that are also installed in the same way and I want to keep the cmake files portable.
The problem lies in the use of include_next of the C++ standard header. According to https://gcc.gnu.org/onlinedocs/cpp/Wrapper-Headers.html it will include the header searching the list of header file directories after the directory in which the current file was found. The standard include directories (using g++ -v) are (corrected):
c:\mingw\lib/gcc/mingw32/6.3.0/include/c++
c:\mingw\lib/gcc/mingw32/6.3.0/include/c++/mingw32
c:\mingw\lib/gcc/mingw32/6.3.0/include/c++/backward
c:\mingw\lib/gcc/mingw32/6.3.0/include
c:\mingw\include
c:\mingw\lib/gcc/mingw32/6.3.0/include-fixed
c:\mingw\mingw32/include
Hence the cstdlib will be found in c:\mingw\lib/gcc/mingw32/6.3.0/include/c++ and include_next "stdlib.h" will go further down this list and will find it in c:\mingw\include.
Now the problem: Installing the libraries into C:\mingw (using the lib, bin and include folders from the library) will make CMake correctly find them there and add the C:\mingw\include folder explicitly to the include list. The 2 cases work out as following:
Adding as -I: This will be ignored by g++ with ignoring ... as it is a non-system directory that duplicates a system directory
Adding as -isystem: This will prepend the directory to the list above and remove it from the rest as a duplicate (verified with the -v option). This means that when cstdlib is found and include_next is evaluated it will search only downward the list. But the directory containing the stdlib.h is not down the list anymore but upwards and therefore not searched. Hence the error.
Note: I found another definition of include_next which only discards the directory containing the header. That would work in this case but can lead to loops and was changed to the described behaviour.
Solution so far is simply installing or copying the libraries to C:\mingw\mingw32 instead.
I'm trying to build a third party tool. I'm not very familiar with the C++ build tools, and I'm not sure how this should be resolved.
dcp2icc.src/dcp2icc.cpp line 6 is:
#include "dng_camera_profile.h"
dng_sdk_1_2/dng_sdk/source/dng_camera_profile.h line 39:
#include "dng_hue_sat_map.h"
There are two dng_hue_sat_map.h files:
$ ls -l dng_sdk_1_2/dng_sdk/source/dng_hue_sat_map.h fixes/dng_sdk/dng_hue_sat_map.h
-r--r--r-- 1 user users 3141 Apr 9 2008 dng_sdk_1_2/dng_sdk/source/dng_hue_sat_map.h
-rw-r--r-- 1 user users 3124 Oct 31 2015 fixes/dng_sdk/dng_hue_sat_map.h
Finally, this is the command which gets run:
g++ -o build/dcp2icc/dcp2icc.o -c -m32 -O2 -iquote- -DUNIX_ENV=1 -D_FILE_OFFSET_BITS=64 -DkBigEndianHost=0 -Idcp2icc.src -Ifixes/dng_sdk -Idng_sdk_1_2/dng_sdk/source -INone dcp2icc.src/dcp2icc.cpp
I expected that because -Ifixes/dng_sdk comes before -Idng_sdk_1_2/dng_sdk/source, fixes/dng_sdk/dng_hue_sat_map.h would be used, but this is not the case:
In file included from dng_sdk_1_2/dng_sdk/source/dng_camera_profile.h:39:0,
from dcp2icc.src/dcp2icc.cpp:6:
dng_sdk_1_2/dng_sdk/source/dng_hue_sat_map.h:129:8: error: extra qualification 'dng_hue_sat_map::' on member 'operator==' [-fpermissive]
bool dng_hue_sat_map::operator== (const dng_hue_sat_map &rhs) const;
^~~~~~~~~~~~~~~
How does g++ choose which file to use when the header file exists in two include locations? Does it matter which sequence the includes are in, and if so, how?
man g++ simply has this to say:
-I dir
Add the directory dir to the list of directories to be searched for header files. Directories named by -I are searched before the standard system include directories. If the directory dir is a standard system include directory, the option is ignored to ensure that the default search order for system directories and the special treatment of system headers are not defeated . If dir begins with "=", then the "=" will be replaced by the sysroot prefix; see --sysroot and -isysroot.
The GCC spec says the following, which as far as I can tell is the opposite of what I'm seeing:
You can specify multiple -I options on the command line, in which case the directories are searched in left-to-right order.
You're using the #include "..." form, rather than the #include <...> form.
The file dng_sdk_1_2/dng_sdk/source/dng_camera_profile.h is including "dng_hue_sat_map.h". #include "..." first searches relative to the file doing the including, so it first searches in dng_sdk_1_2/dng_sdk/source, regardless of -I options.
On a Unix system, where does gcc look for header files?
I spent a little time this morning looking for some system header files, so I thought this would be good information to have here.
`gcc -print-prog-name=cc1plus` -v
This command asks gcc which C++ preprocessor it is using, and then asks that preprocessor where it looks for includes.
You will get a reliable answer for your specific setup.
Likewise, for the C preprocessor:
`gcc -print-prog-name=cpp` -v
In addition, gcc will look in the directories specified after the -I option.
You can create a file that attempts to include a bogus system header.
If you run gcc in verbose mode on such a source, it will list all the system include locations as it looks for the bogus header.
$ echo "#include <bogus.h>" > t.c; gcc -v t.c; rm t.c
[..]
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/lib/gcc/i686-apple-darwin9/4.0.1/include
/usr/include
/System/Library/Frameworks (framework directory)
/Library/Frameworks (framework directory)
End of search list.
[..]
t.c:1:32: error: bogus.h: No such file or directory
The CPP Section of the GCC Manual indicates that header files may be located in the following directories. From the Search Path page:
GCC looks in several different places for headers. On a normal Unix system, if you do not instruct it otherwise, it will look for headers requested with #include in:
/usr/local/include
libdir/gcc/target/version/include
/usr/target/include
/usr/include
For C++ programs, it will also look in /usr/include/g++-v3, first.
To get GCC to print out the complete set of directories where it will look for system headers, invoke it like this:
$ LC_ALL=C gcc -v -E -xc - < /dev/null 2>&1 |
LC_ALL=C sed -ne '/starts here/,/End of/p'
which will produce output of the form
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/5/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
If you have -I-family options on the command line they will affect what is printed out.
(The sed command is to get rid of all the other junk this invocation prints, and the LC_ALL=C is to ensure that the sed command works -- the "starts here" and "End of search list" phrases are translated IIRC.)
g++ -print-search-dirs
gcc -print-search-dirs
The set of paths where the compiler looks for the header files can be checked by the command:-
cpp -v
If you declare #include "" , the compiler first searches in current directory of source file and if not found, continues to search in the above retrieved directories.
If you declare #include <> , the compiler searches directly in those directories obtained from the above command.
Source:- http://commandlinefanatic.com/cgi-bin/showarticle.cgi?article=art026
One could view the (additional) include path for a C program from bash by checking out the following:
echo $C_INCLUDE_PATH
If this is empty, it could be modified to add default include locations, by:
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/include
These are the directories that gcc looks in by default for the specified header files ( given that the header files are included in chevrons <>);
1. /usr/local/include/ --used for 3rd party header files.
2. /usr/include/ -- used for system header files.
If in case you decide to put your custom header file in a place other than the above mentioned directories, you can include them as follows:
1. using quotes ("./custom_header_files/foo.h") with files path, instead of chevrons in the include statement.
2. using the -I switch when compiling the code.
gcc -I /home/user/custom_headers/ -c foo.c -p foo.o
Basically the -I switch tells the compiler to first look in the directory specified with the -I switch ( before it checks the standard directories).When using the -I switch the header files may be included using chevrons.
My system has gcc9 by default and I have built a gcc12 from source and I think the accepted answer is not correct, that is gcc -print-prog-name=cc1plus -v doesn't give the real include search path.
My build configuration is
Configured with: /home/tian/playground/gcc_build_play/objdir/../gcc-12.1.0/configure --prefix=/home/tian/GCC-12.1.0 --disable-multilib
And no matter where I mv the gcc12 directoy in my machine. It can always include its own c++ header files correctly.
If I type ./gcc -print-prog-name=cc1plus -v, in the original installed directory, it gives:
tian#tian-B250M-Wind:~/GCC-12.1.0/bin$ `./gcc -print-prog-name=cc1plus` -v
ignoring nonexistent directory "/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../x86_64-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0
/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/x86_64-pc-linux-gnu
/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/backward
/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/include
/usr/local/include
/home/tian/GCC-12.1.0/include
/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/include-fixed
/usr/include
End of search list.
mv my gcc12 to ~/Desktop/, run again, gives:
tian#tian-B250M-Wind:~/Desktop/GCC-12.1.0/bin$ `./gcc -print-prog-name=cc1plus` -v
ignoring nonexistent directory "/home/tian/GCC-12.1.0/include/c++/12.1.0"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/include/c++/12.1.0/x86_64-pc-linux-gnu"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/include/c++/12.1.0/backward"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/include"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/include"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/include-fixed"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/x86_64-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/include
End of search list.
If that's true, then I compile a program with ./g++, it should use c++ header files in /usr/include or /usr/local/include. But it's not.
Experiment is omitted here. You can try using mv to rename any header file of gcc12 your test program use or add some garbage code to the header file. Then you will see the gcc12 ./g++ is complaining about the gcc12 c++ header file, not my system gcc9's c++ header files in /usr/include or /usr/local/include.
So in both places ./g++ can find its gcc12 c++ headers files correctly.
So I guess gcc and g++ are finding headers in relative directory, relative to /path_to_gcc12/bin/gcc.
Try./g++ -g -Wall --verbose -o test test.cpp gives the real include path:
tian#tian-B250M-Wind:~/Desktop/GCC-12.1.0/bin$ ./g++ -g -Wall --verbose -o test test.cpp
Using built-in specs.
COLLECT_GCC=./g++
COLLECT_LTO_WRAPPER=/home/tian/Desktop/GCC-12.1.0/bin/../libexec/gcc/x86_64-pc-linux-gnu/12.1.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /home/tian/playground/gcc_build_play/objdir/../gcc-12.1.0/configure --prefix=/home/tian/GCC-12.1.0 --disable-multilib
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 12.1.0 (GCC)
COLLECT_GCC_OPTIONS='-g' '-Wall' '-v' '-o' 'test' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
/home/tian/Desktop/GCC-12.1.0/bin/../libexec/gcc/x86_64-pc-linux-gnu/12.1.0/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -iprefix /home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/ -D_GNU_SOURCE test.cpp -quiet -dumpbase test.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -g -Wall -version -o /tmp/ccrg0qhG.s
GNU C++17 (GCC) version 12.1.0 (x86_64-pc-linux-gnu)
compiled by GNU C version 12.1.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../x86_64-pc-linux-gnu/include"
ignoring duplicate directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0"
ignoring duplicate directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/x86_64-pc-linux-gnu"
ignoring duplicate directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/backward"
ignoring duplicate directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/include"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring duplicate directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/include-fixed"
ignoring nonexistent directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../x86_64-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/x86_64-pc-linux-gnu
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/backward
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/include
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/include-fixed
/usr/local/include
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
So I think my guess is correct.