89

When I write C programs in Linux, and then compile them using gcc, I am always curious about where those header files are. For example, where stdio.h is. More generally, where is stdbool.h?

What I want to know is not only where it is, but also how to get those places, for example, using shell command or using the C programming language.

0

10 Answers 10

97

gcc -H ... will print the full path of every include file as a side-effect of regular compilation. Use -fsyntax-only in addition to get it not to create any output (it will still tell you if your program has errors). Example (Linux, gcc-4.7):

$ cat > test.c
#include <stdbool.h>
#include <stdio.h>
^D
$ gcc -H -fsyntax-only test.c
. /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdbool.h
. /usr/include/stdio.h
.. /usr/include/features.h
... /usr/include/x86_64-linux-gnu/bits/predefs.h
... /usr/include/x86_64-linux-gnu/sys/cdefs.h
.... /usr/include/x86_64-linux-gnu/bits/wordsize.h
... /usr/include/x86_64-linux-gnu/gnu/stubs.h
.... /usr/include/x86_64-linux-gnu/bits/wordsize.h
.... /usr/include/x86_64-linux-gnu/gnu/stubs-64.h
.. /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h
.. /usr/include/x86_64-linux-gnu/bits/types.h
... /usr/include/x86_64-linux-gnu/bits/wordsize.h
... /usr/include/x86_64-linux-gnu/bits/typesizes.h
.. /usr/include/libio.h
... /usr/include/_G_config.h
.... /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h
.... /usr/include/wchar.h
... /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h
.. /usr/include/x86_64-linux-gnu/bits/stdio_lim.h
.. /usr/include/x86_64-linux-gnu/bits/sys_errlist.h

The dots at the beginning of each line count how deeply nested the #include is.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the great answer. I've been a little confused about the dots, so I want to share to help others: The files with n+1 dots in front are directly included by the next preceding file with n dots in front. So e.g. pick one with three dots, its included by next preceding file with two dots in front. HTH
More about those dots...Those are called transitive dependencies—a term borrowed from mathematics to describe the relationship of things on a metaphorical chain: a relates to b and b relates to c so a relates to c and so forth. Replace a with your program and relates with "includes".
Works on OS X as well
47

If you use gcc, you can check a specific file with something like:

echo '#include <stdbool.h>' | cpp -H -o /dev/null 2>&1 | head -n1

-H asks the preprocessor to print all included files recursively. head -n1 takes just the first line of output from that, to ignore any files included by the named header (though stdbool.h in particular probably doesn't).

On my computer, for example, the above outputs:

. /usr/lib/gcc/x86_64-linux-gnu/4.6/include/stdbool.h

1 Comment

For an equivalent with Clang, invoke the compiler like so (middle part of the pipeline): cpp -H -fsyntax-only - 2>&1 1>/dev/null Note the dash meaning stdin is your source file. I had do the redirects that way because -o was giving me a hard time.
34
locate stdio.h

or

mlocate stdio.h

but locate relies on a database, if you have never updated it

sudo updatedb

you can also enquire gcc to know what are the default directories that are scanned by gcc itself:

gcc -print-search-dirs

5 Comments

Um..I just tried locate but it doesn't give any result for me. Even after sudo locate update
@Jack on my distribution sudo locate update can do this, i just remember that what Dietrich Epp cab be true, try that command.
gcc -print-search-dirs only prints program and library locations. It doesn't print the header search path.
On what system is locate a standard built-in?
@user3467349 It's built into Ubuntu 16.04. It only runs once a day updating indexes so I changed it to update every 15 minutes using cron.
7

During the preprocessing all preprocessor directives will be replaced with the actuals. Like macro expansion, code comment removal, including the header file source code etc...

we can check it by using the cpp - C PreProcessor command.

For example in the command line:

cpp Filename.c

displays the preprocessed output.

Comments

6

One approach, if you know the name of the include file, would be to use find:

cd /
find . -name "stdio.h"
find . -name "std*.h"

That'll take a while as it goes through every directory.

1 Comment

It wouldn't hurt to restrict the find to /usr/include and /usr/lib, or use locate instead.
2

Use gcc -v and you can check the include path. Usually, the include files are in /usr/include or /usr/local/include depending on the library installation.

1 Comment

stdio.h can be found there, but stdbool.h can be found in /usr/lib/clang/.../include or /usr/lib/gcc/.../include.
1

Most standard headers are stored in /usr/include. It looks like stdbool.h is stored somewhere else, and depends on which compiler you are using. For example, g++ stores it in /usr/include/c++/4.7.2/tr1/stdbool.h whereas clang stores it at /usr/lib/clang/3.1/include/stdbool.h.

Comments

1

I think the generic path is:

/usr/lib/gcc/$(ls /usr/lib/gcc/)/$(gcc -v 2>&1 | tail -1 | awk '{print $3}')/include/stdbool.h

Comments

0

When I was looking for (on Fedora 25) I used "whereis stdio.h" For me, It was in /usr/include/stdio.h, /usr/shar/man/man3/stdio,3.gx. But when you are looking for the file, use whereis or locate

Comments

0

Use vim to open your source file and put the curses on stdio.h and in normal mode, command 'gf' will let vim open the stdio.h file for you.

'Ctr + g' will let vim display the absolute path of stdio.h

2 Comments

Please don't use code highlighting for regular text
Very useful - to return after gf enter ctrl - O

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.