Where are the C Language system header files stored in Linux?

  • Post author:
  • Post last modified:September 9, 2024
  • Reading time:4 mins read

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.

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

Karunesh Johri

Software developer, working with C and Linux.
0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments