DLL-linking via Windows cgo->gcc->ld gives "undefined-reference-to-(function)" errors [closed]
Asked Answered
W

3

24

(Very detailed problem report -- tl;dr at the bottom!)

I really prefer GLFW to Glut and want to get its Golang binding working under Windows 64-bit with Go 1.0.1 64-bit. Under Linux, the binding it works flawlessly. This is in principle doable under Windows -- GitHub user chsc has managed to do so, but he's on Win32 and his tips didn't resolve my issues yet. However I do have a complete and clean Mingw64 set up based on tdm64-gcc-4.6.1.

Now here's the strange thing -- getting the freeglut binding to work under 64-bit Windows, 64-bit Go 1.0.1 works -- the glfw binding fails for me. I want to figure out why, as they essentially both use the same cgo features and techniques.

Note I currently have a self-made half-baked but essentially working replacement package in place that uses LoadLibrary/GetProcAddress calls to expose glfw.dll in Go. This works but I think a hard-linked compiled-in CGO binding would be more desirable than countless Syscall(), Syscall6(), Syscall9(), Syscall12() etc Go func invocations. If Win32 and Linux gophers can have this, why not us Win64 folks?

So here's my setup so far:

  1. I have a Golang build with three patches to make lib linking work with cgo applied
  2. I have successfully compiled the newest freeglut and GLFW libraries as 64-bit DLLs using MinGW64.
  3. Header files glut.h, freeglut*.h and glfw.h are placed in \MinGW64\x86_64-w64-mingw32\include\GL (next to gl.h, glaux.h, glu.h)
  4. Lib files libfreeglut.a and libglfwdll.a are placed in \MinGW64\x86_64-w64-mingw32\lib (next to libglu32.a, libopengl32.a)
  5. 64-bit DLLs glfw.dll and freeglut64.dll are placed in \windows and \windows\system32 (next to opengl32.dll, glu32.dll)
  6. freeglut64.dll and glfw.dll both work, I believe -- at least most of their example programs do after installing the DLLs.

Everything should be in place, right? Now first for the successful binding (that I don't need), freeglut -- when I go get -x github.com/zombiezen/Go-GLUT/glut, all is built just fine and I can successfully create a glut window and show a triangle in a Windows test.exe compiled from a .go source file. Thanks to -x, go get shows what it does to build:

WORK=C:\Users\roxor\AppData\Local\Temp\go-build292908674
mkdir -p $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\
cd C:\Go\src\pkg\github.com\zombiezen\Go-GLUT\glut
C:\Go\pkg\tool\windows_amd64\cgo.exe -objdir $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\ -- -I $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\ glut.go
C:\Go\pkg\tool\windows_amd64\6c.exe -FVw -I $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\ -I C:\Go\pkg\windows_amd64 -o $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_cgo_defun.6 -DGOOS_windows -DGOARCH_amd64 $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_cgo_defun.c
gcc -I . -g -O2 -m64 -mthreads -I $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\ -o $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_cgo_main.o -c $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_cgo_main.c
gcc -I . -g -O2 -m64 -mthreads -I $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\ -o $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_cgo_export.o -c $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_cgo_export.c
gcc -I . -g -O2 -m64 -mthreads -I $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\ -o $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\glut.cgo2.o -c $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\glut.cgo2.c
gcc -I . -g -O2 -m64 -mthreads -I $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\ -o $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\support.o -c .\support.c
gcc -I . -g -O2 -m64 -mthreads -o $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_cgo_.o $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_cgo_main.o $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_cgo_export.o $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\glut.cgo2.o $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\support.o -lfreeglut
C:\Go\pkg\tool\windows_amd64\cgo.exe -objdir $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\ -dynimport $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_cgo_.o -dynout $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_cgo_import.c
C:\Go\pkg\tool\windows_amd64\6c.exe -FVw -I $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\ -I C:\Go\pkg\windows_amd64 -o $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_cgo_import.6 -DGOOS_windows -DGOARCH_amd64 $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_cgo_import.c
gcc -I . -g -O2 -m64 -mthreads -o $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_all.o $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_cgo_export.o $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\glut.cgo2.o $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\support.o -Wl,-r -nostdlib -lgcc -lmingwex -lmingw32
C:\Go\pkg\tool\windows_amd64\6g.exe -o $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_go_.6 -p github.com/zombiezen/Go-GLUT/glut -D _/C_/Go/src/pkg/github.com/zombiezen/Go-GLUT/glut -I $WORK $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_cgo_gotypes.go $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\glut.cgo1.go
C:\Go\pkg\tool\windows_amd64\pack.exe grc $WORK\github.com\zombiezen\Go-GLUT\glut.a $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_go_.6 $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_cgo_import.6 $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_cgo_defun.6 $WORK\github.com\zombiezen\Go-GLUT\glut\_obj\_all.o
mkdir -p C:\Go\pkg\windows_amd64\github.com\zombiezen\Go-GLUT\
cp $WORK\github.com\zombiezen\Go-GLUT\glut.a C:\Go\pkg\windows_amd64\github.com\zombiezen\Go-GLUT\glut.a

To get to this point, I had to slightly modify glut.go as follows:

// # include <GL/glut.h>
// #cgo windows LDFLAGS: -lfreeglut
// #include <stdlib.h>
// #include "support.h"
import "C"

So, to summarize, this builds fine, can be imported and linked from Go and used in code.

Now for GLFW. The GO file reads extremely similar to glut.go:

//#cgo windows LDFLAGS: -lglfwdll -lglu32 -lopengl32
//#include <stdlib.h>
//#define GLFW_DLL
//#include <GL/glfw.h>
import "C"

The #define GLFW_DLL is so that no static linking happens. Here's the output of go get -x github.com/jteeuwen/glfw however:

WORK=C:\Users\roxor\AppData\Local\Temp\go-build499107422
mkdir -p $WORK\github.com\jteeuwen\glfw\_obj\
cd C:\Go\src\pkg\github.com\jteeuwen\glfw
C:\Go\pkg\tool\windows_amd64\cgo.exe -objdir $WORK\github.com\jteeuwen\glfw\_obj\ -- -I $WORK\github.com\jteeuwen\glfw\_obj\ callback.go glfw.go image.go vidmode.go
C:\Go\pkg\tool\windows_amd64\6c.exe -FVw -I $WORK\github.com\jteeuwen\glfw\_obj\ -I C:\Go\pkg\windows_amd64 -o $WORK\github.com\jteeuwen\glfw\_obj\_cgo_defun.6 -DGOOS_windows -DGOARCH_amd64 $WORK\github.com\jteeuwen\glfw\_obj\_cgo_defun.c
gcc -I . -g -O2 -m64 -mthreads -I $WORK\github.com\jteeuwen\glfw\_obj\ -o $WORK\github.com\jteeuwen\glfw\_obj\_cgo_main.o -c $WORK\github.com\jteeuwen\glfw\_obj\_cgo_main.c
gcc -I . -g -O2 -m64 -mthreads -I $WORK\github.com\jteeuwen\glfw\_obj\ -o $WORK\github.com\jteeuwen\glfw\_obj\_cgo_export.o -c $WORK\github.com\jteeuwen\glfw\_obj\_cgo_export.c
gcc -I . -g -O2 -m64 -mthreads -I $WORK\github.com\jteeuwen\glfw\_obj\ -o $WORK\github.com\jteeuwen\glfw\_obj\callback.cgo2.o -c $WORK\github.com\jteeuwen\glfw\_obj\callback.cgo2.c
gcc -I . -g -O2 -m64 -mthreads -I $WORK\github.com\jteeuwen\glfw\_obj\ -o $WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o -c $WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.c
gcc -I . -g -O2 -m64 -mthreads -I $WORK\github.com\jteeuwen\glfw\_obj\ -o $WORK\github.com\jteeuwen\glfw\_obj\image.cgo2.o -c $WORK\github.com\jteeuwen\glfw\_obj\image.cgo2.c
gcc -I . -g -O2 -m64 -mthreads -I $WORK\github.com\jteeuwen\glfw\_obj\ -o $WORK\github.com\jteeuwen\glfw\_obj\vidmode.cgo2.o -c $WORK\github.com\jteeuwen\glfw\_obj\vidmode.cgo2.c
gcc -I . -g -O2 -m64 -mthreads -I $WORK\github.com\jteeuwen\glfw\_obj\ -o $WORK\github.com\jteeuwen\glfw\_obj\callback.o -c .\callback.c
gcc -I . -g -O2 -m64 -mthreads -o $WORK\github.com\jteeuwen\glfw\_obj\_cgo_.o $WORK\github.com\jteeuwen\glfw\_obj\_cgo_main.o $WORK\github.com\jteeuwen\glfw\_obj\_cgo_export.o $WORK\github.com\jteeuwen\glfw\_obj\callback.cgo2.o $WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o $WORK\github.com\jteeuwen\glfw\_obj\image.cgo2.o $WORK\github.com\jteeuwen\glfw\_obj\vidmode.cgo2.o $WORK\github.com\jteeuwen\glfw\_obj\callback.o -lglfwdll -lglu32 -lopengl32
# github.com/jteeuwen/glfw
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwGetNumberOfProcessors':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:39: undefined reference to `__imp_glfwGetNumberOfProcessors'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwGetKey':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:51: undefined reference to `__imp_glfwGetKey'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwSetTime':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:60: undefined reference to `__imp_glfwSetTime'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwExtensionSupported':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:71: undefined reference to `__imp_glfwExtensionSupported'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwPollEvents':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:80: undefined reference to `__imp_glfwPollEvents'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwGetMousePos':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:90: undefined reference to `__imp_glfwGetMousePos'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwGetJoystickParam':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:102: undefined reference to `__imp_glfwGetJoystickParam'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwGetProcAddress':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:112: undefined reference to `__imp_glfwGetProcAddress'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwGetGLVersion':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:123: undefined reference to `__imp_glfwGetGLVersion'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwSetMouseWheel':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:133: undefined reference to `__imp_glfwSetMouseWheel'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwGetJoystickPos':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:148: undefined reference to `__imp_glfwGetJoystickPos'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwOpenWindow':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:168: undefined reference to `__imp_glfwOpenWindow'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwSetMousePos':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:178: undefined reference to `__imp_glfwSetMousePos'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwSwapInterval':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:188: undefined reference to `__imp_glfwSwapInterval'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwGetMouseButton':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:209: undefined reference to `__imp_glfwGetMouseButton'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwSetWindowTitle':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:218: undefined reference to `__imp_glfwSetWindowTitle'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwGetVideoModes':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:231: undefined reference to `__imp_glfwGetVideoModes'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwGetJoystickButtons':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:246: undefined reference to `__imp_glfwGetJoystickButtons'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwRestoreWindow':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:255: undefined reference to `__imp_glfwRestoreWindow'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwInit':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:265: undefined reference to `__imp_glfwInit'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwSwapBuffers':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:274: undefined reference to `__imp_glfwSwapBuffers'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwGetMouseWheel':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:284: undefined reference to `__imp_glfwGetMouseWheel'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwIconifyWindow':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:293: undefined reference to `__imp_glfwIconifyWindow'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwWaitEvents':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:302: undefined reference to `__imp_glfwWaitEvents'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwSetWindowPos':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:312: undefined reference to `__imp_glfwSetWindowPos'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwGetWindowSize':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:322: undefined reference to `__imp_glfwGetWindowSize'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwDisable':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:332: undefined reference to `__imp_glfwDisable'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwGetWindowParam':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:344: undefined reference to `__imp_glfwGetWindowParam'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwCloseWindow':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:353: undefined reference to `__imp_glfwCloseWindow'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwOpenWindowHint':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:363: undefined reference to `__imp_glfwOpenWindowHint'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwSleep':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:372: undefined reference to `__imp_glfwSleep'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwEnable':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:382: undefined reference to `__imp_glfwEnable'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwSetWindowSize':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:392: undefined reference to `__imp_glfwSetWindowSize'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwTerminate':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:411: undefined reference to `__imp_glfwTerminate'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwGetDesktopMode':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:420: undefined reference to `__imp_glfwGetDesktopMode'
$WORK\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwGetTime':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:429: undefined reference to `__imp_glfwGetTime'
$WORK\github.com\jteeuwen\glfw\_obj\image.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwFreeImage':
C:\Go\src\pkg\github.com\jteeuwen\glfw/image.go:38: undefined reference to `__imp_glfwFreeImage'
$WORK\github.com\jteeuwen\glfw\_obj\image.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwReadImage':
C:\Go\src\pkg\github.com\jteeuwen\glfw/image.go:52: undefined reference to `__imp_glfwReadImage'
$WORK\github.com\jteeuwen\glfw\_obj\image.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwLoadTextureImage2D':
C:\Go\src\pkg\github.com\jteeuwen\glfw/image.go:65: undefined reference to `__imp_glfwLoadTextureImage2D'
$WORK\github.com\jteeuwen\glfw\_obj\image.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwLoadMemoryTexture2D':
C:\Go\src\pkg\github.com\jteeuwen\glfw/image.go:78: undefined reference to `__imp_glfwLoadMemoryTexture2D'
$WORK\github.com\jteeuwen\glfw\_obj\image.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwLoadTexture2D':
C:\Go\src\pkg\github.com\jteeuwen\glfw/image.go:91: undefined reference to `__imp_glfwLoadTexture2D'
$WORK\github.com\jteeuwen\glfw\_obj\image.cgo2.o: In function `_cgo_680190d759a2_Cfunc_glfwReadMemoryImage':
C:\Go\src\pkg\github.com\jteeuwen\glfw/image.go:107: undefined reference to `__imp_glfwReadMemoryImage'
$WORK\github.com\jteeuwen\glfw\_obj\callback.o: In function `setWindowSizeCB':
C:/Go/src/pkg/github.com/jteeuwen/glfw/callback.c:9: undefined reference to `__imp_glfwSetWindowSizeCallback'
$WORK\github.com\jteeuwen\glfw\_obj\callback.o: In function `setWindowCloseCB':
C:/Go/src/pkg/github.com/jteeuwen/glfw/callback.c:14: undefined reference to `__imp_glfwSetWindowCloseCallback'
$WORK\github.com\jteeuwen\glfw\_obj\callback.o: In function `setWindowRefreshCB':
C:/Go/src/pkg/github.com/jteeuwen/glfw/callback.c:19: undefined reference to `__imp_glfwSetWindowRefreshCallback'
$WORK\github.com\jteeuwen\glfw\_obj\callback.o: In function `setMouseButtonCB':
C:/Go/src/pkg/github.com/jteeuwen/glfw/callback.c:24: undefined reference to `__imp_glfwSetMouseButtonCallback'
$WORK\github.com\jteeuwen\glfw\_obj\callback.o: In function `setMousePosCB':
C:/Go/src/pkg/github.com/jteeuwen/glfw/callback.c:29: undefined reference to `__imp_glfwSetMousePosCallback'
$WORK\github.com\jteeuwen\glfw\_obj\callback.o: In function `setMouseWheelCB':
C:/Go/src/pkg/github.com/jteeuwen/glfw/callback.c:34: undefined reference to `__imp_glfwSetMouseWheelCallback'
$WORK\github.com\jteeuwen\glfw\_obj\callback.o: In function `setKeyCB':
C:/Go/src/pkg/github.com/jteeuwen/glfw/callback.c:39: undefined reference to `__imp_glfwSetKeyCallback'
$WORK\github.com\jteeuwen\glfw\_obj\callback.o: In function `setCharCB':
C:/Go/src/pkg/github.com/jteeuwen/glfw/callback.c:44: undefined reference to `__imp_glfwSetCharCallback'
collect2: ld returned 1 exit status

Yes, it's a mouthful -- but essentially just always the same error, and fairly late in the build procedure. Notice if #define GLFW_DLL isn't defined, I get essentially the same output except without the __imp_ prefixes -- and static linking is neither encourage for Go nor is it desirable for this particular use-case.

Now, when gcc complains about "undefined reference to", from what I google there could be various reasons...

  • it cannot be failure to find the DLL's -- they're in the appropriate places and for freeglut64.dll it works
  • it cannot be failure to find the .a libs -- they're in the appropriate places, and libfreeglut.a works, and if I change -lglfwdll to -lblafoobar then gcc fails much earlier and rightly complains "blafoobar not found" -- so it does find libglfwdll.a.
  • order of lib dependencies? I tried -lglfwdll as the first lib (before -lglu32 -lopengl32) and as the last (after those two), no difference.
  • is the Golang glfw binding faulty? Don't think so, works for others, including under Windows for chsc (32-bit though)

TL;DR -- under Windows 64-bit, Go 1.0.1 64-bit fully patched, CGO successfully generates stuff to feed into GCC for both freeglut and glfw. GCC then happily eats that stuff to build the freeglut binding, but rejects it for building the glfw binding, with "undefined reference to" for all C.funcs(). Both libfreeglut and libglfwdll are correctly built and installed as 64-bit DLLs and .h/.a libs correctly located. What could be the cause?

Waldo answered 29/4, 2012 at 3:42 Comment(5)
64 and 32-bit use a different symbol underscoring "policy". Are you sure you're compensating for that?Chirk
What does this mean exactly? Is there any reason this could apply to a fully built 64-bit freeglut.dll but not a fully build valid and working (in other non-Go programs) 64-bit glfw.dll?Waldo
the only way this could happen if the faulty library explicitely adds the underscore to it's function names (I've seen this happen before, I think it was WebKit). You can check the exports of the library using nm or objdump, and see if the names match exactly.Chirk
OK thanks for those pointers, will forward it to the GLFW devs =)Waldo
I had a similar issue while using Java and JNI. GCC "decorated" the function calls of a library with something like "@8" or "@16" on a 64 Bit machine. If you access the library using your calls, the application or the linker n your case would not find them. This issue was resolved in my case by adding : -Wl,-add-stdcall-alias to the linking phase of the build chain. It creates aliases redirecting to the @8 decorated functions so JNI found them.Halberd
W
2

No longer an issue with the newest releases of Go, GLFW and Mingw-w64.

Waldo answered 11/10, 2012 at 19:36 Comment(0)
B
5

I've had the exact same problem for a while now and I've been looking into it every time I worked off the frustration of the last attempt. Compiling 32-bit glfw for go was no problem but the 64 bit version eluded me.

Today, after reading kneo's comment I tried his solution but couldn't get it to work. But it lead me to looking at libglfwdll.a which had the @nn stdcall suffixes while libglfw.a didn't have them. Trying various LDFLAGS (-Wl,--kill-at, -Wl,--enable-stdcall-fixup) didn't yield successful results, I studied http://www.willus.com/mingw/yongweiwu_stdcall.html but couldn't get it to work.

I was about to give up when I when I decided to see if there was a new version of glfw (2.7.6) with the following bugfix:

[Win32] Bugfix: A .def file using __stdcall naming conventions was used for the 64-bit DLL on MinGW-w64

so long story short, compiling the new glfw version and installing it fixed the issue and go get github.com/jteeuwen/glfw now works without any problem.

Brazilin answered 6/7, 2012 at 13:34 Comment(0)
W
2

No longer an issue with the newest releases of Go, GLFW and Mingw-w64.

Waldo answered 11/10, 2012 at 19:36 Comment(0)
M
0

I can think of two possibilities:

  1. the symbols are actually not present in the library. You can check this with nm. Make sure the symbol type is an upper-case letter; if there are only lower case codes then the libraries are not built right.

  2. you have a circular dependency. I.e. Library A depends on library B which in turn depends on A again. You can get around this adding the library to the command a second time or using linker groups (see ld --help).

Note that the order of the libraries on the command line is very important: the linker reads each library in turn, in the order they appear, searches for the symbols it needs at the time, and then moves on. If a symbol is first referenced by a late library, the linker will not revisit earlier libraries to find the definition. This is why circular dependencies are a problem.

Marceline answered 30/6, 2012 at 21:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.