Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Go: SWIG doesn't work on Windows #100

Closed
steeve opened this issue Oct 25, 2013 · 5 comments
Closed

Go: SWIG doesn't work on Windows #100

steeve opened this issue Oct 25, 2013 · 5 comments
Labels

Comments

@steeve
Copy link

steeve commented Oct 25, 2013

Hey guys, sorry for the mistake when submitting.

I'm trying to build Go bindings for C++ lib, and while it does work on Linux, Mac, here are the steps I have to do to modify the cxx file to make it work on Windows, based in part on https://groups.google.com/forum/#!topic/golang-nuts/9L0U4Q7AtyE

First of all, change all struct swigargs to be __attribute__((__packed__)), according to https://code.google.com/p/go/source/browse/src/cmd/cgo/out.go#530 :

$ sed -i '' 's/} \*swig_a/} __attribute__((__packed__)) \*swig_a/g' file_wrap.cxx

For instance

  struct swigargs {
    long : 0;
    intgo result;
  } __attribute__((__packed__)) *swig_a = (struct swigargs *) swig_v;

However, on Win32, long long int is broken, suggested fix is, according to https://code.google.com/p/go/issues/detail?id=6541 :

$ sed -i '' 's/__attribute__((__packed__))/__attribute__((__packed__, __gcc_struct__))/g' file_wrap.cxx
  struct swigargs {
    long : 0;
    intgo result;
  } __attribute__((__packed__, __gcc_struct__)) *swig_a = (struct swigargs *) swig_v;

Also, Windows doesn't resolve symbols at compile time, so we need to properly set these symbols in a DllMain, and then have the file use them, see the dllmain file here: https://gist.github.com/steeve/7152742/raw/dllmain.cxx

Finally, we need to fix the imports, I do it like so:

# Comment out externs
    sed -i '' 's/\(extern void\)/\/\/\1/' $@
# Insert dllmain
    cat dllmain.i $@ > $@.tmp
    mv $@.tmp $@
# Fix imports by specifying then to the external dll, and commenting the x_wrap_* symbols
    sed -i '' 's/\(#pragma dynimport _ _\)/\/\/\1/' libtorrent_gc.c
    sed -i '' 's/\(#pragma dynimport.*\)\(""\)/\1"$(LIBRARY_NAME)"/g' libtorrent_gc.c
    sed -i '' 's/\(static void (\*x_wrap_\)/\/\/\1/g' libtorrent_gc.c
    sed -i '' 's/cgocall(x\(_wrap_.*\)/cgocall(\1/g' libtorrent_gc.c

And here is a snippet of my Makefile to do that:

$(SRCS) $(GOFILES): $(SWIG_FILES)
    $(SWIG) $(SWIG_FLAGS) -o $@ -outdir . $<
# It should always be like this, according to https://code.google.com/p/go/source/browse/src/cmd/cgo/out.go
    sed -i '' 's/} \*swig_a/} __attribute__((__packed__)) \*swig_a/g' $@
# Temp fix for https://code.google.com/p/go/issues/detail?id=6541
# See also https://code.google.com/p/go/issues/detail?id=5603
ifeq ($(CC), gcc)
    ifneq (,$(filter $(ARCH),x86 x64))
        sed -i '' 's/__attribute__((__packed__))/__attribute__((__packed__, __gcc_struct__))/g' $@
    endif
endif
ifeq ($(OS), Windows_NT)
# Patch SWIG generated files for succesful compilation on Windows.
# Based on https://groups.google.com/forum/#!topic/golang-nuts/9L0U4Q7AtyE
# Comment out externs
    sed -i '' 's/\(extern void\)/\/\/\1/' $@
# Insert dllmain
    cat dllmain.i $@ > $@.tmp
    mv $@.tmp $@
# Fix imports by specifying then to the external dll, and commenting the x_wrap_* symbols
    sed -i '' 's/\(#pragma dynimport _ _\)/\/\/\1/' libtorrent_gc.c
    sed -i '' 's/\(#pragma dynimport.*\)\(""\)/\1"$(LIBRARY_NAME)"/g' libtorrent_gc.c
    sed -i '' 's/\(static void (\*x_wrap_\)/\/\/\1/g' libtorrent_gc.c
    sed -i '' 's/cgocall(x\(_wrap_.*\)/cgocall(\1/g' libtorrent_gc.c
endif
@steeve
Copy link
Author

steeve commented Oct 25, 2013

I'll try and see if I can do it in a platform independant way through #ifdef/#define, in which case I'll submit a PR.

@fire
Copy link

fire commented Feb 6, 2014

Is there any progress on this?

@steeve
Copy link
Author

steeve commented Feb 6, 2014

Not that I know of. You might want to check this https://github.com/steeve/libtorrent-go/blob/master/Makefile#L124

steeve added a commit to steeve/swig that referenced this issue Nov 5, 2014
Based on the work of Wei Guangjing[1].
On Windows, dynamic binding of methods is not possible. So we use DllMain to do
that.
[1] https://groups.google.com/forum/#!topic/golang-nuts/9L0U4Q7AtyE
[2] swig#100

Closes swig#100

Signed-off-by: Steeve Morin <steeve.morin@gmail.com>
steeve added a commit to steeve/swig that referenced this issue Nov 5, 2014
Based on the work of Wei Guangjing[1].
On Windows, dynamic binding of methods is not possible. So we use DllMain to do
that.
[1] https://groups.google.com/forum/#!topic/golang-nuts/9L0U4Q7AtyE
[2] swig#100

Closes swig#100

Signed-off-by: Steeve Morin <steeve.morin@gmail.com>
steeve added a commit to steeve/swig that referenced this issue Nov 6, 2014
Based on the work of Wei Guangjing[1].
On Windows, dynamic binding of methods is not possible. So we use DllMain to do
that.
[1] https://groups.google.com/forum/#!topic/golang-nuts/9L0U4Q7AtyE
[2] swig#100

Closes swig#100

Signed-off-by: Steeve Morin <steeve.morin@gmail.com>
steeve added a commit to steeve/swig that referenced this issue Nov 6, 2014
Based on the work of Wei Guangjing[1].
On Windows, dynamic binding of methods is not possible. So we use DllMain to do
that.
[1] https://groups.google.com/forum/#!topic/golang-nuts/9L0U4Q7AtyE
[2] swig#100

Closes swig#100

Signed-off-by: Steeve Morin <steeve.morin@gmail.com>
steeve added a commit to steeve/swig that referenced this issue Nov 12, 2014
Based on the work of Wei Guangjing[1].
On Windows, dynamic binding of methods is not possible. So we use DllMain to do
that.
[1] https://groups.google.com/forum/#!topic/golang-nuts/9L0U4Q7AtyE
[2] swig#100

Closes swig#100

Signed-off-by: Steeve Morin <steeve.morin@gmail.com>
@ojwb ojwb added the Go label Sep 9, 2016
@ojwb
Copy link
Member

ojwb commented Jan 24, 2022

Looks like #262 addressed the missing __attribute__((__packed__)), but also swigargs went away in 4461c44 when support for -no-cgo was removed (because it only worked with Go versions before 1.5).

Looking at the current version of https://github.com/steeve/libtorrent-go/blob/master/Makefile I don't see any of the fixups to the SWIG generated code mentioned above.

@steeve Does that mean this issue is no longer relevant (perhaps due to the switch to always using cgo and/or changes in more recent Go versions)? Or do the linked commits above in your fork need merging?

@ojwb
Copy link
Member

ojwb commented Feb 14, 2022

golang/go#7281 indicates that this should have worked for more than 5 years (but after all the comments above apart from mine from a few weeks ago), so I'm going to close this now.

If it doesn't seem fixed please give details and I'll be happy to reopen.

@ojwb ojwb closed this as completed Feb 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants