Undefined reference errors when linking GLFW on MinGW
Asked Answered
F

1

7

I am trying to develop an openGL application with GLEW and GLFW on Windows using minGW. In the current directory, project/, I have the directories src/, bin/, and glfw-3.0.4.bin.WIN64/. I have the files test.cpp, glew.h, glew.c, and wglew.h in the src/ directory.

The directory ./glfw-3.0.4.bin.WIN64/include/ contains the GLFW/glfw3.h header file.

The directory ./glfw-3.0.4.bin.WIN64/lib-mingw/ contains glfw3.dll, glfw3dll.a, and libglfw3.a.

My main file, test.cpp contains,

#include "glew.h"
#include "GLFW/glfw3.h"

#include <stdio.h>

int main(int argc, char** argv) {
    printf("Hello, World!\n");

    glewInit();
    glfwInit();
}

I am compiling the program from the project/ directory by running (split into two lines for readability)

gcc -DGLEW_STATIC -DGLFW_DLL -o ./bin/test ./src/*.cpp ./src/glew.c 
-I ./glfw-3.0.4.bin.WIN64/include/ -L ./glfw-3.0.4.bin.WIN64/lib-mingw/ -lglfw3 -lopengl32

and I am getting the following error:

undefined reference to `_imp_glfwInit'

I think the problem has to do with me linking the GLFW library incorrectly. From what I understand, including the compiler option -lglfw3 will tell gcc to link ./glfw-3.0.4.bin.WIN64/lib-mingw/glfw3.dll, which contains the definition for glfwInit().

I've looked at solutions to other problems similar to mine and they suggest things such as copying the dll file to the source/binary directories and changing the order of the -l options, but none have seemed to solve the problem for me.

Favin answered 25/3, 2014 at 0:9 Comment(6)
Your gcc command split into two lines. Is it for sake if readability here? Or that is your actual command (in that case, it is wrong)? Also, as I recall, -Ipath and -Lpath must be written without space.Mitchum
Yeah, sorry, I should have noted that the gcc command was split for readability. Running the command without spaces still produces the same error.Favin
Can't say for sure, but I guess something is wrong with your libraries. Are you sure they're mingw-compatible and supposed to be 64bit? Can you get it running with 32bit version?Mitchum
Ah, I really thought that would have fixed the problem. I've been using mingw for 32bit systems. I switched to using glfw-3.0.4.bin.WIN32 but I still get the same compile time error.Favin
Could you assemble minimal example (with all required sources and libraries) and upload it somewhere? It is hard to diagnose this kind of problems without seeing it.Mitchum
Sure. drive.google.com/file/d/0BzaMTyFoNpy3RHlCalRpM054bVE/… It's a bit different from what I have above.Favin
M
7

Your problem is that gcc follows strict library naming conventions. It attempts to find glfw3.dll.a, but finds none (because it is named glfw3dll.a - simple rename will fix your problem).

Next step it looks for libglfw3.a, and succeeds - but it is a static library, while reference declared as dynamic in header files (tricky windows DECLSPECs... this problem don't exist on e.g. linux). So, it cannot find _imp__glfwInit, because in static library it is called just glfwInit, so you getting an error.

Removing libglfw3.a is also one of options - in that case gcc will look further and eventually find glfw3.dll and use it.

Mitchum answered 25/3, 2014 at 6:27 Comment(3)
So many people in the Internet suggest to remove mingw 32 bit version and install Mingw-w64, but it doesn't resolve the issue. I renamed glfw3dll.a to glfw3.dll.a and program launched flawlessly! Second suggestion to remove libglfw3.a and glfw3.dll.a also worked out! You're the master. Can you explain why and how gcc looks for the necessary dll's further, once .a file is not found? So the truth is that actually one of the glfw creators named incorrectly .a files in pre-compiled binaries?Toneless
@Toneless I don't think there is any other step, with default settings it tries to link with dynamic library first (.dll.a on windows), and if it can't - then it tries static one (.a). Direct linking with .dll is specific addition gcc toolchain have; for all I know MSVC toolchain can't link with dll directly without use of import libraries (what gcc have in .dll.a), so I suppose it just considered as last resort as it could be problemmatic in some cases. I don't think glfw does anything wrong either, they just follow their MSVC naming scheme. You can link with -lglfw3dll.Mitchum
@Toneless declspec is big deal on windows. If your include file says functions are dllimport - they have to be in dll, and attempt to link with static library will produce an error. So if your program intends to use glfw in dll form, it have to define GLFW_DLL before including glfw3.h (note -DGLFW_DLL flag in original question), and link wtih dll; but as you have to know that at build time, it is probably better to have separate library name for dll version and just link with -lglfw3dll to ensure it wouldn't pick static version. You don't have either problem on linux/osx.Mitchum

© 2022 - 2024 — McMap. All rights reserved.