the include path and the library path
To use a library you do two separate things, and each needs the toolchain to find something on disk. First, the compiler must find the library's header so it knows what functions exist; second, the linker must find the library's compiled file so it can attach the code. The include path is the list of directories searched for header files, and the library path is the list of directories searched for library files — two different searches, at two different stages of the build.
When the compiler sees #include <foo.h>, it looks for foo.h by walking the include path: a built-in set of standard directories (like /usr/include) plus any extra directories you add with the -I flag, for example gcc -I/opt/foo/include. When the linker is told to link a library with -lfoo, it looks for a file named libfoo.a or libfoo.so by walking the library path: standard directories like /usr/lib plus any you add with -L, for example gcc -L/opt/foo/lib -lfoo. So a typical build of a non-standard library passes both: -I to find the header, -L plus -l to find and link the library.
Why it matters: 'fatal error: foo.h: No such file or directory' is the compiler telling you the header is not on the include path; 'cannot find -lfoo' or 'undefined reference' at link time is the linker telling you the library is not on the library path (or was not requested). Recognizing which of the two searches failed tells you exactly which flag to add. And remember a third, separate path: even after a successful build, a shared library must also be found at run time via the shared-library search path.
Use a library installed outside the standard directories: gcc -I/opt/foo/include main.c -L/opt/foo/lib -lfoo -o app ^ include path (headers) ^ library path ^ link Missing -I -> 'foo.h: No such file or directory' Missing -L -> 'cannot find -lfoo'
-I points the compiler at headers; -L points the linker at libraries; -l names the library to link.
The include path (compile time) and the library path (link time) are both build-time searches and are separate from the run-time shared-library search path. A build can succeed yet the program still fail to start if the shared library is not on that third, run-time path.