Built glfw3 but it still doesn't find the functions


#1

I’m building my application using the 64 bit MinGW, “x86_64-posix-seh-rev1, Built by MinGW-W64 project” to be precise.

At first I downloaded the 64 bit MinGW prebuilt from the website, but it didn’t link, undefined reference to basic stuff like glfwInit and half a dozen others.
Then I downloaded the source, configured it up for my MinGW and built it. It built without problems, even the example programs compiled and linked up, I can run them, they work fine.
I checked into the generated .a file (which is different from the prebuilt one from the website, larger by around 12k), and surely enough, the compiler left its mark in it: GCC: (x86_64-posix-seh-rev1, Built by MinGW-W64 project)
But when I try to link against this version, I get the same undefined references. The -l argument works, because it doesn’t complain about not finding the library, I removed the other .a files from the lib directory because I’ve read that it might confuse the glfw3.dll and the libglfw3.a or something.

My linker line is:

g++ -Ld:\Programs\Chipmunk-7.0.2\Build\src\ -Ld:\Programs\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\lib\ -lchipmunk -lglfw3 -lopengl32 -lgdi32 build/graphics/GlWindow.o build/app/main.o -o build/gurgula.exe

There must be something wrong with my side, because as I said, the example programs build fine. But I can’t get the proper parameterization out of the jungle of make files in that cmake-generated mess.


#2

There’s a short section on MinGW in Building applications using GLFW, but although it looks like you’re linking to the right programs it’s hard to tell without the error output text.

Since you’ve got the example programs working with cmake why not use cmake to generate your own makefiles? For a starting point take a look at my CmakeLists.txt for enkiTSExamples. You should be able to cut out the references to enkiTS, Remotery etc., and put your own source in the set() command and go from there.


#3

As for the error messages, they are nothing special, just the usual undefined references:
build/graphics/GlWindow.o:GlWindow.cpp:(.text+0x53): undefined reference to glfwInit' build/graphics/GlWindow.o:GlWindow.cpp:(.text+0xf8): undefined reference toglfwTerminate’
build/graphics/GlWindow.o:GlWindow.cpp:(.text+0x23a): undefined reference to glfwWindowHint' build/graphics/GlWindow.o:GlWindow.cpp:(.text+0x249): undefined reference toglfwWindowHint’
build/graphics/GlWindow.o:GlWindow.cpp:(.text+0x24e): undefined reference to glfwGetPrimaryMonitor' build/graphics/GlWindow.o:GlWindow.cpp:(.text+0x28b): undefined reference toglfwCreateWindow’
build/graphics/GlWindow.o:GlWindow.cpp:(.text+0x2d8): undefined reference to glfwMakeContextCurrent' build/graphics/GlWindow.o:GlWindow.cpp:(.text+0x2e2): undefined reference toglfwSwapInterval’
collect2.exe: error: ld returned 1 exit status
make: *** [build/gurgula.exe] Error 1

I would have liked to avoid getting down to cmake magic, I would like to actually understand what happens, and it shouldn’t be that complicated to link against a library.
But I might have to, if I can’t find out what I’m doing wrong…


#4

OK - so it’s definitely glfw exported functions you’re having a problem with.

Do you have GLFW_DLL set in your source as this would need glfw3dll to be linked (I’m presuming not but want to check all the angles)?

A common error on MinGW is to use 32 bit with 64 bit and visa versa, but since you’ve also built the libraries yourself on the same OS this shouldn’t be an the issue.

Although you may not want to use cmake, it would be a good approach to check first since it shouldn’t involve that much effort. It could be that once you’ve done that you can narrow the issue down and create your own make files.


#5

As you guessed, I don’t have GLFW_DLL set, that would cause it to link to imp* versions of the same functions.

But writing a cmake config for the whole thing (and it took this long (with lunch) because I knew nothing about cmake other than to call cmake -G with the appropriate build system and then make), now it compiles and links.

The sad thing is, I still have no clue why. I tried make -n, but the targets and executed commands are really obfuscated with CMake machinery.
This is the command that I think does the linking:
D:\Programs\CMake\bin\cmake.exe -E cmake_link_script CMakeFiles\gurgula.dir\link.txt --verbose=

There is no file called *link_script, but there is a link txt, containing:
D:\Programs\CMake\bin\cmake.exe -E remove -f CMakeFiles\gurgula.dir/objects.a
D:\Programs\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin\ar.exe cr CMakeFiles\gurgula.dir/objects.a @CMakeFiles\gurgula.dir\objects1.rsp
D:\Programs\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin\g++.exe -Wl,–whole-archive CMakeFiles\gurgula.dir/objects.a -Wl,–no-whole-archive -o bin\gurgula.exe -Wl,–out-implib,bin\libgurgula.dll.a -Wl,–major-image-version,0,–minor-image-version,0 @CMakeFiles\gurgula.dir\linklibs.rsp

And linklibs.rsp is just
-lglfw3 -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32

If I try to use these linker options in my normal makefile in a backup copy of the project, it doesn’t work, same results as before.

So the problem is kinda “solved”, but I have no clue how. If anyone has any insight what the cmake does that I didn’t notice, that would be nice.


#6

I see you’ve tried -n, I’m not sure if this is better but you may want to try:

make VERBOSE=1

See this stckoverflow for more information.