In short, -I
tells the compiler where to look for the headers.
Some paths are already searched by the compiler, such as /usr/include
. For those headers, you don't -I
(e.g. the standard headers or installed libraries). For headers in a location unknown to the compiler, such as your own program or a library whose source you have downloaded, you need to specify the include path (via -I
) otherwise the compiler has no idea where to find the include file.
Note that when you include with "file"
instead of <file>
, the compiler first searches the directory where the including file itself is. For example, let's say you have a directory structure like this:
project
|
+- include
| |
| +- header1.h
| |
| `- header2.h
|
`- src
|
+- funcs1.c
|
+- funcs2.c
|
`- internal.h
Now let's see some examples:
funcs1.c:
#include "internal.h"
Compiling this doesn't need -I
because internal.h
is in the same location as funcs1.c
.
funcs1.c:
#include <internal.h>
This needs -I/path/to/project/src
(or -I.
if you are calling the compiler in the same directory as funcs1.c
) because #include <...>
doesn't search in the directory of the source file.
funcs2.c:
#include <header1.h>
/* or */
#include "header1.h"
This needs -I/path/to/project/include
(or -I../include
if you are calling the compiler in the same direcotry as funcs2.c
) because the location of header1.h
is unknown to the compiler in either case. Note that this is regardless of where you call the compiler since the compiler doesn't look at the directory it is being called from, but in the directory the source file is.
funcs1.c:
#include "internal.h"
internal.h:
#include "header2.h"
This still needs -I/path/to/project/include
because even though internal.h
is found to be included in funcs1.c
, it tries to include header2.h
whose path needs to be told to the compiler.