I am attempting to compile this code:
#include <GLFW/glfw3.h>
int main() {
glfwInit();
glfwTerminate();
return 0;
}
Using this command in MSYS2 on Windows 10:
gcc -Wall runVulkan.c -o runVulkan
as well as this:
gcc -Wall -Llibs/glfw runVulkan.c -o runVulkan
libs/glfw is where I downloaded the library to.
For some reason I keep getting this:
runVulkan.c:1:10: fatal error: GLFW/glfw3.h: No such file or directory
1 | #include <GLFW/glfw3.h>
| ^~~~~~~~~~~~~~
compilation terminated.
It seems like I'm getting something very basic wrong.
I'm just getting started with C, I'm trying to import Vulkan libraries.
#include
are just headers, for declarations. gcc
, as any compilers, needs to know where those .h
should be searched.
You can specify that with -I
option (or C_INCLUDE_PATH
environment variable).
You'll also need -L
option, this times to provide the library itself (.h
does not contain the library. Just declarations that the compiler needs to know how to compile codes that use the library function's and types).
-L
option tells the compiler where to search for libraries.
But here, you haven't specify any libraries (just headers. And I know that it seems logical that they go together. But strictly speaking, there is no way to guess from #include <GLFW/glfw3.h>
which library that file contain headers for (that is not just theory. In practice, for example, the well known libc
declarations are in many different headers)
So, you will also have to specify a -l
option. In your case -lglfw
.
This seems over complicated, because in your case you compile and like in a single command (goes from .c
to executable directly). But that are two different operations done in one command.
Creation of an executable from .c
code source is done in two stage.
Compilation itself. Creating .o
from .c
(many .c
for big codes), so many compilation commands. Using command such as
gcc -I /path/where/to/find/headers -c mycode.c -o mycode.o
Those are not related to the library. So no -l
(and therefore no -L
) for that. What is compiled is your code, so just your code is needed at this stage. Plus the header files, because your code refers to unknown function and types, and the compiler needs to know, not their code, but at least declarations that they really exist, and what are the types expected and returned by the functions is the headers files.
Then, once all the .o
are compiled, you need to put together all compiled code, yours (the .o
) and the libraries (which are somehow a sort of .zip
of .o
) to create an executable. That is called linking. And is done with commands like
gcc -o myexec mycode1.o mycode2.o -L /path/where/to/search/for/libraries -lrary
(-lbla
is a compact way to include /path/where/to/search/for/libraries/libbla.so
or /path/where/to/search/for/libraries/libbla.a
)
At this stage, you no longer need -I
or anything related to headers. The code is already compiled, headers has no role left. But you need everything needed to find the compile code of the libraries.
So, tl;dr
-I
option so that the compiler knows where to find GLFW/glfw3.h
-lglfw
to specify that you want to use that library, and a -L
option so that the compiler knows where to find a libglfw.so