196

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.

MD XF
  • 7,062
  • 7
  • 34
  • 64
Bill the Lizard
  • 369,957
  • 201
  • 546
  • 842

9 Answers9

233
`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
Drew Dormann
  • 50,103
  • 11
  • 109
  • 162
  • 2
    What do the `s mean? I'm finding it difficult to search for this. – mijiturka Mar 23 '16 at 12:35
  • 8
    @mijiturka [What does ` (backquote/backtick) mean in bash?](http://unix.stackexchange.com/questions/27428/what-does-backquote-backtick-mean-in-bash) – Drew Dormann Mar 23 '16 at 18:13
  • 5
    I guess the C **preprocessor** is `cpp` instead of `cc1`? On my debian jessie `$(gcc -print-prog-name=cpp) -v` (correctly) gives one more path, which is `/usr/include/x86_64-linux-gnu` – wlnirvana May 06 '16 at 15:10
  • 4
    If you want that to not hang waiting for input, redirect input from `/dev/null`, so `\`gcc -print-prog-name=cc1\` -v < /dev/null` . – Steve Jorgensen Oct 09 '16 at 08:44
  • @SteveJorgensen yep! Or press `Ctrl`+`D`, which sends "end of file" in Unix-talk. – Drew Dormann Oct 09 '16 at 18:20
  • …but you can't press Ctrl+D from within a shell script. – Steve Jorgensen Oct 09 '16 at 19:20
  • This may give a misleading answer on operating systems where the "compiler driver" (the `gcc` or `g++` program) overrides the search paths compiled into the preprocessor. For instance, on the computer I'm typing this, this recipe omits `/usr/include/x86_64-linux-gnu` from the search path. – zwol Mar 13 '19 at 13:53
  • When I run "gcc -print-prog-name=cc1" it just outputs "cc1". No path at all. Seems the path is only printed if cc1 is found. I want to know the path where gcc is LOOKING for cc1. How can I do that? – Daniele Testa Jun 19 '19 at 05:03
43

In addition, gcc will look in the directories specified after the -I option.


Kalin
  • 1,441
  • 1
  • 13
  • 20
robert
  • 1,180
  • 9
  • 3
32

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
Jonathan Leffler
  • 666,971
  • 126
  • 813
  • 1,185
diciu
  • 28,395
  • 4
  • 48
  • 68
  • 4
    I think this would be more helpful if you just said "use the -v option". – Jay Conrod Dec 05 '08 at 16:51
  • Well if you use "-v" without a C file that includes a non-existent system header you will not cause gcc to iterate through all the include paths. The key to my answer is bogus.h listed as a system header. – diciu Dec 05 '08 at 16:53
  • @Jay - you're right, it was too vague - I've explained what I was doing in the shell script. – diciu Dec 05 '08 at 16:58
  • @Jay: The -v option by itself gives output that doesn't include system path. – Bill the Lizard Dec 05 '08 at 17:01
  • 10
    without temporary files: `echo "#include " | gcc -v -x c -` – thejoshwolfe Sep 04 '12 at 22:57
  • 2
    `gcc -v -E - < /dev/null` or `cpp -v < /dev/null` are enough. You just have to get the preprocessor to *run*, it doesn't matter what input it sees. (The search paths are printed during startup, before it even looks at its input.) – zwol Apr 05 '14 at 03:00
  • @zwol Thanks for that, it's a lot more straight forward, and imho deserves to be a separate answer on its own. – Etheryte Jun 07 '15 at 17:47
17

The CPP Section of the GCC Manual indicates that header files may be located in the following directories:

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.

Bill the Lizard
  • 369,957
  • 201
  • 546
  • 842
10

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

zwol
  • 121,956
  • 33
  • 219
  • 328
9
g++ -print-search-dirs
gcc -print-search-dirs
user292283
  • 115
  • 1
  • 3
  • 4
    These commands print the default search paths for link libraries and internal components of the compiler; they don't tell you anything about header files. – zwol Mar 13 '19 at 13:49
7

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

Suhas Chikkanna
  • 697
  • 2
  • 12
  • 27
1

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
Johannes Kuhn
  • 12,878
  • 3
  • 41
  • 66
1

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.