Home > Back-end >  How do I use an external library with gcc?
How do I use an external library with gcc?

Time:12-22

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.

CodePudding user response:

Run pacman -S mingw-w64-x86_64-glfw to install GLFW.

Then build using gcc -Wall runVulkan.c -o runVulkan runVulkan.c `pkg-config --cflags --libs glfw3`.

The pkg-config command prints the flags necessary to use GLFW, and the ` backticks pass its output to GCC as flags. You can run it separately and manually pass any printed flags to GCC.

Note that any -l... flags (those are included in pkg-config output) must be specified after .c or .o files, otherwise they'll have no effect.


For me pkg-config prints -I/mingw64/include -L/mingw64/lib -lglfw3.

-I fixes No such file or directory. It specifies a directory where the compiler will look for #included headers. Though it's unnecessrary when installing GLFW via pacman, since /mingw64/include is always searched by default.

-l fixes undefined reference errors, which you'd get after fixing the previous error. -lglfw3 needs a file called libglfw3.a or libglfw3.dll.a (or some other variants).

-L specifies a directory where -l should search for the .a files, though it's unnecessrary when installing GLFW via pacman, since /mingw64/lib is always searched by default.

CodePudding user response:

#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

  • At compilation stage (the stage that raises the error you have for now), you need -I option so that the compiler knows where to find GLFW/glfw3.h
  • But that alone wont avoid you the next error that will occur at linking stage. At this stage, you need -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
  • Related