0

Compiling code that uses GLFW in MinGW-w64, everything goes fine until the linking phase. At this point, ld starts to complain about undefined references to GLFW functions, even though I specified the additional library directories and used libraries. Here's my g++ invocation (I, of course, use a lot of enviroment variables in my batch file to shorten the command, here it is unwrapped):

x86_64-w64-mingw32-g++.exe -I./deps/glfw-3.2.1/include -I./deps/gl3w/include -I./include -L./deps/glfw-3.2.1/lib-mingw-w64/x86_64 -lglfw3 -lopengl32 -lgdi32 -lkernel32 -luser32 -lcomdlg32 -std=c++14 -fpermissive -mwindows -o build\out\windows\Release\x86_64\GemVerse.exe ./deps/gl3w/src/gl3w.c ./src/main.cpp

Here is the same command, broken down:

x86_64-w64-mingw32-g++.exe %INCLUDEDIRS% %LIBDIRS64% %CFLAGS% %LIBS% -o build\out\windows\Release\x86_64\GemVerse.exe %SOURCES%

Where %INCLUDEDIRS%=-I./deps/glfw-3.2.1/include -I./deps/gl3w/include -I./deps/glm-0.9.9.3/include -I./include, %LIBDIRS64%=-L./deps/glfw-3.2.1/lib-mingw-w64/x86_64, %LIBS%=-lglfw3 -lopengl32 -lgdi32 -lkernel32 -luser32 -lcomdlg32, %CFLAGS%=-std=c++14 -fpermissive -mwindows and %SOURCES%=./deps/gl3w/src/gl3w.c ./src/main.cpp

As you can see, the library gets found and linked, but the symbols are still unresolved. How is this possible and how to link GLFW properly?


EDIT 1:

I've changed the library order, now it's -lopengl32 -lgdi32 -lkernel32 -luser32 -lcomdlg32 -glfw3, so that GLFW is at the end. That didn't fix the problem, ld still doesn't find the definitions. Here is the g++ log, since I don't seem to have attached one, my fault:
./deps/gl3w/src/gl3w.c: In function 'int open_libgl()':
./deps/gl3w/src/gl3w.c:47:52: warning: invalid conversion from 'FARPROC' {aka 'long long int (*)()'} to 'void*' [-fpermissive]
  *(void **)(&wgl_get_proc_address) = GetProcAddress(libgl, "wglGetProcAddress");
                                      ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Users\vtonc\AppData\Local\Temp\cc6GSYa1.o:main.cpp:(.text$_ZN8gemverse6GVGame4initEv[_ZN8gemverse6GVGame4initEv]+0x65): undefined reference to `glfwInit'
C:\Users\vtonc\AppData\Local\Temp\cc6GSYa1.o:main.cpp:(.text$_ZN8gemverse6GVGame4initEv[_ZN8gemverse6GVGame4initEv]+0x74): undefined reference to `glfwWindowHint'
C:\Users\vtonc\AppData\Local\Temp\cc6GSYa1.o:main.cpp:(.text$_ZN8gemverse6GVGame4initEv[_ZN8gemverse6GVGame4initEv]+0x83): undefined reference to `glfwWindowHint'
C:\Users\vtonc\AppData\Local\Temp\cc6GSYa1.o:main.cpp:(.text$_ZN8gemverse6GVGame4initEv[_ZN8gemverse6GVGame4initEv]+0x92): undefined reference to `glfwWindowHint'
C:\Users\vtonc\AppData\Local\Temp\cc6GSYa1.o:main.cpp:(.text$_ZN8gemverse6GVGame4initEv[_ZN8gemverse6GVGame4initEv]+0x9e): undefined reference to `glfwWindowHint'
C:\Users\vtonc\AppData\Local\Temp\cc6GSYa1.o:main.cpp:(.text$_ZN8gemverse6GVGame4initEv[_ZN8gemverse6GVGame4initEv]+0xc0): undefined reference to `glfwCreateWindow'
C:\Users\vtonc\AppData\Local\Temp\cc6GSYa1.o:main.cpp:(.text$_ZN8gemverse6GVGame4initEv[_ZN8gemverse6GVGame4initEv]+0xd4): undefined reference to `glfwMakeContextCurrent'
C:\Users\vtonc\AppData\Local\Temp\cc6GSYa1.o:main.cpp:(.text.startup+0x1b): undefined reference to `glfwTerminate'
C:\Users\vtonc\AppData\Local\Temp\cc6GSYa1.o:main.cpp:(.text.startup+0x3b): undefined reference to `glfwGetKey'
C:\Users\vtonc\AppData\Local\Temp\cc6GSYa1.o:main.cpp:(.text.startup+0x5c): undefined reference to `glfwSwapBuffers'
C:\Users\vtonc\AppData\Local\Temp\cc6GSYa1.o:main.cpp:(.text.startup+0x61): undefined reference to `glfwPollEvents'
C:\Users\vtonc\AppData\Local\Temp\cc6GSYa1.o:main.cpp:(.text.startup+0x66): undefined reference to `glfwTerminate'
C:\Users\vtonc\AppData\Local\Temp\cc6GSYa1.o:main.cpp:(.text.startup+0x7d): undefined reference to `glfwSetWindowShouldClose'
collect2.exe: error: ld returned 1 exit status
The terminal process terminated with exit code: 1

Some names are mangled, since the initialization code in my project is incapsulated into a class.

Kotauskas
  • 1,239
  • 11
  • 31
  • [Wrong order](http://lampwww.epfl.ch/~fsalvi/docs/gcc/www.network-theory.co.uk/docs/gccintro/gccintro_14.html) in command line? (also, long description with discussion in comments on SO - https://stackoverflow.com/a/409470/4074081) – dewaffled Mar 06 '19 at 13:45
  • @dewaffled So I should put the GLFW library at the end of the ordering? And why does `ld` report undefined references to GLFW if GLFW's references to its dependencies are undefined instead? – Kotauskas Mar 06 '19 at 13:57
  • @dewaffled I've edited the question, providing research and a log – Kotauskas Mar 06 '19 at 17:47

1 Answers1

0

I fixed the problem by putting %SOURCES% before %LIBS% in the g++ invocation, thanks to this answer. That seems to make difference as well: not only the library order is important, but the order of inputs (sources before libraries) too.

Kotauskas
  • 1,239
  • 11
  • 31