Windows DLL-linking with cgo

2,648 views
Skip to first unread message

Phil S.

unread,
Apr 27, 2012, 3:56:13 AM4/27/12
to golang-nuts
My ultimate goal is to successfully link to a number of DLLs
(opengl32.dll glfw.dll and glu32.dll) from a Go package -- but trying
to link to the go-glfw package gave me "not defined" errors (details
at https://github.com/jteeuwen/glfw/issues/9 )

So I decided to first get a most basic cgo-dynamic/shared-library-
linking to work, from the very simple unmodified example in %GOROOT%
\misc\cgo\life. But just invoking the command:

go build -o life main.go

fails with essentially the same linker error, namely:

go-build374967034/_/C_/Go/misc/cgo/life.a(c-life.o)(.text): _assert:
not defined

... "someImportedFunc: not defined" -- just exactly the same error I
had when trying to link glfw as per above.

This is a fresh untampered-with install of Go 1.0.1 freshly downloaded
this morning, on a vanilla, fairly recent Win7 64-bit installation.
What could possibly go wrong? I know... Windows. Would love to hear
any ideas... seems like DLL linking with CGO is a no-brainer and
simple to do from what I read around the net. Yet even the simplest of
examples in the newest-version Go distribution immediately fails for
me.

minux

unread,
Apr 27, 2012, 9:40:59 AM4/27/12
to Phil S., golang-nuts
This is a known bug. Could you please apply these three CLs (in that order)
and try again?
CL 5823055, CL 5823059, and CL 5822049

Phil S.

unread,
Apr 27, 2012, 8:50:44 PM4/27/12
to golang-nuts
Hi minux,

thanks! Sounds like I'd have to give up running off a binary
distribution then? Might just give it a try but not really the
resolution I was hoping for. Out of curiosity, is there a known binary
release (a weekly pre-Go1) that does not exhibit this bug and is known
to work? From the discussion here https://github.com/chsc/gogl/issues/5
someone successfully linked to glfwdll.a without running into this
issue as recent as 2 weeks ago.


On Apr 27, 9:40 pm, minux <minux...@gmail.com> wrote:
> CL 5823055 <http://codereview.appspot.com/5823055/>, CL
> 5823059<http://codereview.appspot.com/5823059/>,
> and CL 5822049 <http://codereview.appspot.com/5822049/>

Phil S.

unread,
Apr 27, 2012, 9:51:05 PM4/27/12
to golang-nuts
OMG how do I apply those? Manually? I'm sure there is a neat tool
hidden in some unknown Wiki page. Spent an hour carefully manually
applying all diffs to the newest stable 1.0.1 codebase fetched with
Mercurial... after clean.bat, running all.bat gave me:

# Building compilers and Go bootstrap tool.
lib9
libbio
libmach
misc/pprof
cmd/addr2line
cmd/cov
cmd/nm
cmd/objdump
cmd/pack
cmd/prof
cmd/cc
cmd/gc
cmd/6l
C:\g\go\src\cmd\6l\..\ld\symtab.c: In function 'putelfsyment':
C:\g\go\src\cmd\6l\..\ld\symtab.c:67:3: error: 'other' undeclared
(first use in this function)
C:\g\go\src\cmd\6l\..\ld\symtab.c:67:3: note: each undeclared
identifier is reported only once for each function it appears in
C:\g\go\src\cmd\6l\..\ld\symtab.c: In function 'putelfsym':
C:\g\go\src\cmd\6l\..\ld\symtab.c:112:2: error: too many arguments to
function 'putelfsyment'
C:\g\go\src\cmd\6l\..\ld\symtab.c:61:1: note: declared here
C:\g\go\src\cmd\6l\..\ld\symtab.c: In function 'asmelfsym':
C:\g\go\src\cmd\6l\..\ld\symtab.c:119:2: error: too many arguments to
function 'putelfsyment'
C:\g\go\src\cmd\6l\..\ld\symtab.c:61:1: note: declared here

I'm sure my naive copy-pasting introduced human error somewhere.
Should I try again manually or is there a better way? Guess I'm a real
noob regarding gcc, mingw and mercurial code patches. Don't even know
what the heck 'CL' means!... Now *this* is some abbreviation where
Google is *not* your friend...


On Apr 28, 8:50 am, "Phil S." <philipp.schum...@gmail.com> wrote:
> Hi minux,
>
> thanks! Sounds like I'd have to give up running off a binary
> distribution then? Might just give it a try but not really the
> resolution I was hoping for. Out of curiosity, is there a known binary
> release (a weekly pre-Go1) that does not exhibit this bug and is known
> to work? From the discussion herehttps://github.com/chsc/gogl/issues/5

Phil S.

unread,
Apr 27, 2012, 10:32:56 PM4/27/12
to golang-nuts
OK ignore previous questions, figured out the git apply command by now
and applying only the very last patch-set of each of those 3 CLs in
order, then running all.bat seems to be fine. Tests passed, no errors
etc. Now back to my glfw use-case...

Phil S.

unread,
Apr 28, 2012, 12:13:49 AM4/28/12
to golang-nuts
Well those CL's don't break my Go distribution -- that's good -- but
they don't resolve my specific dynamic-DLL-linking use-case at all.
However I did previously attempt to link to the 32bit version of
glfw.dll which from what I gather is not possible, ie. a 64bit binary
can only link to other 64bit binaries I think. Anyway, that didn't
work, CL or not. Now, with successfully built 64bit versions of
glfw.dll and glfwdll.a in place at the appropriate locations, cgo
still does not successfully compile the glfw binding that was working
so well under Linux and that some other cgo Windows user *did*
successfully build only a few weeks ago. The errors I'm now getting
are some 30-50 variations of:


...\go-build086748098\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In
function `_cgo_b09453b6208a_Cfunc_glfwSomeFuncName':
C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:184: undefined
reference to `__imp_glfwSomeFuncName'


For details, check out https://github.com/jteeuwen/glfw/issues/9#issuecomment-5394247

Phil S.

unread,
Apr 28, 2012, 8:48:27 PM4/28/12
to golang-nuts
minux,

though I'm still fighting with my own obscure glfw use-case, I just
wanted to confirm and reinforce that those 3 CL's DID successfully fix
the cgo/gcc/ld "xyz: not defined" link-time bug not only on my Windows
machine but also on someone else's OSX: https://github.com/jteeuwen/glfw/issues/8#issuecomment-5398097

So I just wanted to say -- these patches do fix a real bug in the
current distribution across OSes -- I think they should make it into
the master branch or whatever it's called before the next minor
release :)


On Apr 28, 12:13 pm, "Phil S." <philipp.schum...@gmail.com> wrote:
> Well those CL's don't break my Go distribution -- that's good -- but
> they don't resolve my specific dynamic-DLL-linking use-case at all.
> However I did previously attempt to link to the 32bit version of
> glfw.dll which from what I gather is not possible, ie. a 64bit binary
> can only link to other 64bit binaries I think. Anyway, that didn't
> work, CL or not. Now, with successfully built 64bit versions of
> glfw.dll and glfwdll.a in place at the appropriate locations, cgo
> still does not successfully compile the glfw binding that was working
> so well under Linux and that some other cgo Windows user *did*
> successfully build only a few weeks ago. The errors I'm now getting
> are some 30-50 variations of:
>
> ...\go-build086748098\github.com\jteeuwen\glfw\_obj\glfw.cgo2.o: In
> function `_cgo_b09453b6208a_Cfunc_glfwSomeFuncName':
> C:\Go\src\pkg\github.com\jteeuwen\glfw/glfw.go:184: undefined
> reference to `__imp_glfwSomeFuncName'
>
> For details, check outhttps://github.com/jteeuwen/glfw/issues/9#issuecomment-5394247

Phil S.

unread,
Apr 30, 2012, 11:53:23 PM4/30/12
to golang-nuts
Hi minux,

one of those 3 CL's introduce a new CGO bug in Win64. As you probably
know, for // #cgo windows LDFLAGS the typical library lookup is
something like -lopengl32 -- should lookup \MinGW64\x86_64-w64-
mingw32\lib\libopengl32.a (in my %path% case) and \windows
\system32\opengl32.dll. However there is another gcc/ld syntax that
goes like this: -Wl,/dll64/opengl32.dll -- note the hard-coded
absolute file path including extension. (Why would I do this? Because
in Windows if a DLL is requested by a 32-bit process the 32-bit
version of the DLL is loaded from \windows\syswow64, if it is
requested by a 64-bit process, the 64-bit version of the DLL is loaded
from \windows\system32 -- I know, ironic that 64-bit ones are in
system32 and 32-bit ones are in syswow64, but this is not a typo. gcc
and ld are always 32-bit processes even in mingw64.)

So this is valid gcc/ld LDFLAGS syntax and also it works when doing a
"go build" on a package using this. For example, in my use-case a
modified version of package https://github.com/chsc/gogl/blob/master/gl21/gl21.go
(the original works great under Linux and Win 32-bit).

So "go build" doesn't complain about this. But when I link such a
built package with a (pure GO) consumer package, a simple main.exe
console app, linking fails with the following warning:

malformed pe file: unexpected flags for PE section .idata$2

and then lots of "somefunc: not defined" linker errors.

(Now of course the 64-bit DLL according to file.exe is a "PE32+
executable for MS Windows (DLL) (console) Mono/.Net assembly" -- not
the classical "PE32 executable for MS Windows (DLL) (console) Intel
80386 32-bit" that 32-bit DLLs are described as -- .)

This does not happen in Go 1.0.1 without those 3 CLs applied. Though I
don't know which of those 3 CLs does this -- according to Google the
error message is produced in src/cmd/ld/ldpe.c.

minux

unread,
May 1, 2012, 6:38:09 AM5/1/12
to Phil S., golang-nuts
Hi Phil,
     Could you please provide a zip file available containing all the required files (mainly .a, .h
and .dll files) so that I can reproduce this problem on my machine?
Reply all
Reply to author
Forward
0 new messages