Reputation: 6515
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?
Upvotes: 206
Views: 159107
Reputation: 6270
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:
echo | gcc -xc -E -v -
echo | gcc -xc++ -E -v -
The credit goes to Qt Creator team.
Here's a breakdown of the flags:
-x
selects the language, C
or C++
respectively
-E
makes gcc to run the preprocessor only, so no compilation takes place
-v
prints all the commands run, which is the key to dumping the standard paths
-
is the "input file" to preprocess, as a convention -
stands for stdin (or stdout, depending on the context);
echo |
feeds an empty string to gcc
so effectively we preprocess an empty file generated on the fly
Here's a nice explaining it in more detail: https://explainshell.com/explain?cmd=echo+%7C+gcc+-xc+-E+-v+-
Upvotes: 307
Reputation: 2089
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'
Upvotes: 16
Reputation: 1667
Just run the following to list the default search paths:
$(gcc -print-prog-name=cc1) -v
Upvotes: 2
Reputation: 785
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.
Upvotes: 6
Reputation: 14462
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.
Upvotes: 53