Where does gcc look for C and C++ header files?

Viewed 136666

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.

10 Answers
`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.

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.

Related