171

When I compile a very simple source file with gcc I don't have to specify the path to standard include files such as stdio or stdlib.

How does GCC know how to find these files?

Does it have the /usr/include path hardwired inside, or it will get the paths from other OS components?

activedecay
  • 9,178
  • 3
  • 42
  • 65
Raxvan
  • 6,002
  • 2
  • 24
  • 46

5 Answers5

254

In order to figure out the default paths used by gcc/g++, as well as their priorities, you need to examine the output of the following commands:

  1. For C:
    gcc -xc -E -v -
  1. For C++:
    gcc -xc++ -E -v -

The credit goes to Qt Creator team.

Edwin Pratt
  • 745
  • 9
  • 19
Ihor Kaharlichenko
  • 5,634
  • 1
  • 26
  • 30
  • 17
    `cpp -v /dev/null -o /dev/null` – Nehal J Wani Mar 17 '17 at 12:07
  • @NehalJWani - good advice, but it doesn't work for Renesas's rx-elf-gcc cross-compiler. `rx-elf-cpp.exe: error: /dev/null: No such file or directory` – AJM Mar 11 '22 at 12:08
  • @Ihor - what does the - at the end of the command line do? I've seen questions about these dashes elesewhere on Stack Overflow, but their meaning varies by command. As far as I can tell when experimenting with Cygwin, it means gcc will do nothing and ignore all input except Ctrl-C. But gcc in an actual Bash shell might behave very differently. – AJM Mar 11 '22 at 13:43
  • `-` refers to `stdin` here. So you could also do: `echo | gcc -xc++ -E -v -` and `echo | gcc -xc++ -E -v -` – Nehal J Wani Mar 11 '22 at 16:10
51

There is a command with a shorter output, which allows to automatically cut the include pathes from lines, starting with a single space:

$ echo | gcc -Wp,-v -x c++ - -fsyntax-only
ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../x86_64-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../include/c++/4.8.2
 /usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../include/c++/4.8.2/x86_64-redhat-linux
 /usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../include/c++/4.8.2/backward
 /usr/lib/gcc/x86_64-redhat-linux/4.8.2/include
 /usr/local/include
 /usr/include
End of search list.

The credit goes to the libc++ front-page.

abyss.7
  • 13,132
  • 11
  • 49
  • 98
3

To summarise the other answers:

For C++:

c++ -xc++ /dev/null -E -Wp,-v 2>&1 | sed -n 's,^ ,,p'

For C:

cc -xc /dev/null -E -Wp,-v 2>&1 | sed -n 's,^ ,,p'

Johan Boulé
  • 1,746
  • 13
  • 17
2

Though I agree with Ihor Kaharlichenko’s answer for considering C++ and with abyss.7’s answer for the compactness of its output, they are still incomplete for the multi-arch versions of gcc because input processing depends on the command line parameters and macros.

Example:

echo | /opt/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-g++ -specs=nano.specs -mcpu=cortex-m4 -march=armv7e-m -mthumb -mfloat-abi=soft -x c++ -E -Wp,-v\ - -fsyntax-only yields

⋮
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../arm-none-eabi/include/newlib-nano                                                                                                              
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/include/c++/9.2.1                                                                        
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/include/c++/9.2.1/arm-none-eabi/thumb/v7e-m/nofp                                         
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/include/c++/9.2.1/backward                                                               
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/include                                                                                                            
 /opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/include-fixed                                                                                                      
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/include                                                                                  
⋮

whereas echo | /opt/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-g++ -x c++ -E -Wp,-v - -fsyntax-only yields

⋮
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/include/c++/9.2.1                                                                        
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/include/c++/9.2.1/arm-none-eabi                                                          
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/include/c++/9.2.1/backward                                                               
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/include                                                                                                            
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/include-fixed                                                                                                      
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/include                                                                                  
⋮

The former invocation utilizes newlib (see lines 1 and 3 of the output), the latter goes with the standard includes. The common files at the end of the list are an example for the usage of include_next.

Bottom line: Always consider all macros and compiler options when printing the include directories.

hermannk
  • 675
  • 7
  • 12
0

Just run the following to list the default search paths:

$(gcc -print-prog-name=cc1) -v
Laurenz Albe
  • 167,868
  • 16
  • 137
  • 184
Daniele Testa
  • 1,202
  • 3
  • 13
  • 29
  • 1
    This doesn't list the include paths. Only programs path and libraries path – kayahr Jun 20 '19 at 09:56
  • `cc1` usually can't be called directly because it is an internal command which is not on the PATH. Maybe you want to edit your answer to describe where to find the file. – kayahr Jun 21 '19 at 09:31
  • bash: syntax error near unexpected token `-v' – mireazma Mar 09 '21 at 16:54