The system header files are located in multiple directories. The header files give precise information about the capabilities and interfaces of a library component. The location of C language system header files for the GNU Compiler Collection (GCC) is explained.
Table of Contents
1. The Problem
A C program contained the following #include’s
#include <stdio.h> #include <stdlib.h> #include <stdatomic.h> #include <pthread.h>
GCC compiled the program with the above #include’s. So, obviously, these files are present somewhere in the file system. But, in which directory are these files located?
In the early days of C programming the system header files used to be located in /usr/include directory. But, with time, things have become more involved. For example, the stdatomic.h file is not there in the /usr/include directory.
user1@host1:~$ cd /usr/include user1@host1:/usr/include$ ls -ls stdatomic.h ls: cannot access 'stdatomic.h': No such file or directory user1@host1:/usr/include$ find . -name "stdatomic.h" user1@host1:/usr/include$
2 Target
There is the concept of “target” in GCC. The term target refers to the CPU architecture and the operating system. For an x86_64 based system running Linux, the target is “x86_64-linux-gnu”. The text of “target” is used in the path of some of the include directories. We can see the “target” value from the “gcc -v” command,
$ gcc -v Using built-in specs. COLLECT_GCC=gcc ... Target: x86_64-linux-gnu ...
3. Include system directories
The compiler looks for the system header files in the following directories listed in sequence,
/usr/lib/gcc/x86_64-linux-gnu/11/include /usr/local/include /usr/include/x86_64-linux-gnu /usr/include
4. Bash script for finding header files
Using the above include directories we can write a shell script, find-include-file, to find the four above-mentioned system header files.
#!/bin/bash include_files=(stdio.h stdlib.h stdatomic.h pthread.h) include_dirs=( /usr/lib/gcc/x86_64-linux-gnu/11/include /usr/local/include /usr/include/x86_64-linux-gnu /usr/include ) for header_file in "${include_files[@]}"; do for include_dir in "${include_dirs[@]}"; do if [ -e ${include_dir}/${header_file} ]; then ls ${include_dir}/${header_file}; fi done done
Running the above script, we get the location of the four header files.
$ ./find-include-file /usr/include/stdio.h /usr/include/stdlib.h /usr/lib/gcc/x86_64-linux-gnu/11/include/stdatomic.h /usr/include/pthread.h
5.0 Finding the header file directories
An easy way to find the system header file directories is to give the command, “gcc -v -E – < /dev/null“. The “-E” option stops the compiler after the pre-processing stage, i.e., only the pre-processor is run, not the compiler proper. The output is in the form of pre-processed code, which is written on the standard output. For example,
$ gcc -v -E - < /dev/null Using built-in specs. COLLECT_GCC=gcc ... COLLECT_GCC_OPTIONS='-v' '-E' '-mtune=generic' '-march=x86-64' /usr/lib/gcc/x86_64-linux-gnu/11/cc1 -E -quiet -v -imultiarch x86_64-linux-gnu - -mtune=generic -march=x86-64 -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -dumpbase - ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/11/include-fixed" ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /usr/lib/gcc/x86_64-linux-gnu/11/include /usr/local/include /usr/include/x86_64-linux-gnu /usr/include End of search list. ...