What are the GCC default include directories?
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?
5 Answers 5
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:
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
@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.
@palapapa, I suppose it depends on the version of GCC. I tried omitting some of the flags from the above set, and even though there was some output each time, none of them contained the include . search starts here piece which is the one we are looking for. Running on Ubuntu 22.04, GCC 11.3.0
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.
To summarise the other answers:
c++ -xc++ /dev/null -E -Wp,-v 2>&1 | sed -n ‘s,^ ,,p’
cc -xc /dev/null -E -Wp,-v 2>&1 | sed -n ‘s,^ ,,p’
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.
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.
linux include all directories
how would I type a file path in ubuntu terminal to include all files in all sub-directories? If I had a main directory called «books» but had a ton of subdirectories with all sorts of different names containing files, how would I type a path to include all files in all subdirectories? /books/.
in what context? in a scripting language or at the command line as input to a shell command? some more info would be useful..
Typically, if a tool supports this, there will be a flag that can be passed to the tool to recurse subdirectories.
3 Answers 3
From within the books top directory, you can use the command:
Then, if you wanted to, say run each file through cat, you could use the xargs command:
For more info, use commands:
This is the correct way to traverse a hierarchy of subdirectories. Some shells offer a wildcard syntax **/* for this but Bash v2 is not amongst them.
Any Ubuntu version that is yet supported uses bash version 3 or higher for the terminal (as far as I know).
It is unclear what you actually want . Probably you will get a better solution to your problem, if you ask directly for it, not for one other problem you’ve come accross trying to circumvent the original problem.
do you mean something like the following?
where the first * expands for all subdirectories and the second * for all contained files ?
I have chosen the file command arbitrarily. You can choose whatever command you want to run on the files you get shell-expanded. Also note that directories will also be included (if not excluded by name, e.g. *.png or *.txt ). The wildcard * is not exactly the file path to include all files in all subdirectories but it expands to all files (or directories) matching the wildcard expression as a list, e.g. file1 file2 file3 file4 . See also this tutorial on shell expansion.
Note that there may be easy solutions to related problems. Like to copy all files in all subdirectories ( cp -a for example, see man cp ).
I also like find very much. It’s quite easy to generate more flexible search patterns in combination with grep . To provide a random example:
du `find . | grep some_pattern_to_occur | grep -v some_pattern_to_not_occur`
How To Include Files From Multiple Directories In C on Linux?
Now I am trying to run main.c which contains #include directive to include header files from include directory and function calls to .c files in both common and src directories. I am using -I option but it is useful only for one directory path indication. How does the compiler will look in all src, common and include directories to resolve the calls. Kindly suggest me a command or make file to provide path of multiple directories while compiling with gcc.
1 Answer 1
Multiple -I options are permitted. The description of the -I option from Options for Directory Search states:
Add the directory dir to the head of the list of directories to be searched for header files. This can be used to override a system header file, substituting your own version, since these directories are searched before the system header file directories. However, you should not use this option to add directories that contain vendor-supplied system header files (use -isystem for that). If you use more than one -I option, the directories are scanned in left-to-right order; the standard system directories come after.
gcc main.c -o main -Iinclude -Isrc/include -Icommon/include
Note that if main.c is using functions implemented in another .c file(s) then the other .c files will also need compiled and linked into the final program binary. For example:
gcc main.c src/another.c -o main -Iinclude -Isrc/include -Icommon/include
Where are include files stored — Ubuntu Linux, GCC
the compiler, GCC in my case, knows where that stdio.h (and even the object file) are located on my hard drive. It just utilizes the files with no interaction from me. I think that on my Ubuntu Linux machine the files are stored at /usr/include/ . How does the compiler know where to look for these files? Is this configurable or is this just the expected default? Where would I look for this configuration? Since I’m asking a question on these include files, what are the source of the files? I know this might be fuzzy in the Linux community but who manages these? Who would provide and manage the same files for a Windows compiler. I was always under the impression that they come with the compiler but that was an assumption.
4 Answers 4
When the include file is in brackets the preprocessor first searches in paths specified via the -I flag. Then it searches the standard include paths (see the above link, and use the -v flag to test on your system).
When the include file is in quotes the preprocessor first searches in the current directory, then paths specified by -iquote, then -I paths, then the standard paths.
-nostdinc can be used to prevent the preprocessor from searching the standard paths at all.
Environment variables can also be used to add search paths.
When compiling if you use the -v flag you can see the search paths used.
gcc is a rich and complex «orchestrating» program that calls many other programs to perform its duties. For the specific purpose of seeing where #include «goo» and #include will search on your system, I recommend:
$ touch a.c $ gcc -v -E a.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. # 1 "a.c"
This is one way to see the search lists for included files, including (if any) directories into which #include «. » will look but #include <. >won’t. This specific list I’m showing is actually on Mac OS X (aka Darwin) but the commands I recommend will show you the search lists (as well as interesting configuration details that I’ve replaced with . here;-) on any system on which gcc runs properly.