doutangshuan6473 2014-07-28 15:07
浏览 109

在Wine下编译Golang应用程序

I'm trying to create an unattended (and perhaps deterministic) build process for an application written in Go.

The idea is to use create a Dockerfile which installs all the prerequisites so it's easy to share the build process with others and doesn't require a real windows installation.

However I'm stuck trying to build a library that has C bindings.

I get this very non-descriptive error

C:\godev\src\github.com\obscuren\secp256k1-go>go build --work
WORK=C:\usersoot\Temp\go-build287695705
# _/C_/godev/src/github.com/obscuren/secp256k1-go
copying $WORK\_\C_\godev\src\github.com\obscuren\secp256k1-go\_obj\_cgo_defun.8 to $WORK\_\C_\godev\src\github.com\obscuren\secp256k1-go.a: write $WORK\_\C_\godev\src\github.com\obscuren\secp256k1-go.a: Access denied.

A full log with -x can be found here.

I can build this library on OS X and a 'real' Windows installation just fine.

Any help would be appreciated.

Edit:

Using the outline by OneofOne also gives me some errors.

# runtime/cgo
pkg/runtime/cgo/cgo.go:26:46: fatal error: sys/types.h: No such file or directory.
compilation terminated.

Initially I got this error when enabling cross-compiling for Go. I overcame that by installing gcc-multilib. The next problem is the following.

# runtime/cgo
gcc: error: unrecognized command line option ‘-mthreads’

Googling for this error results in two hits which are not useful to my user-case. I'm hoping anybody experienced this before.

Edit 2:

Not sure yet what solved it but I did

apt-get install gcc-multilib
apt-get install gcc-mingw-w64

And used

GOOS=windows GOARCH=386 CGO_ENABLED=1 CXX_FOR_TARGET=i686-w64-mingw32-g++ CC_FOR_TARGET=i686-w64-mingw32-gcc ./make.bash

Now I'm a step further. :)

  • 写回答

1条回答 默认 最新

  • drnpwmq4536 2014-07-28 17:41
    关注

    While not an answer to the exact question, the proper way of doing this is using mingw64 on Linux to cross-compile windows executables, I've used it several times in my projects and it worked fine.

    First, you have to enable crosscompiling in Go:

    ┌─ oneofone@Oa [~]                                                                                                               
    └──➜ cd $GOROOT/src
    ┌─ oneofone@Oa [/u/s/g/src]                                                                                                      
    └──➜ env GOOS=windows GOARCH=386 CGO_ENABLED=1 ./make.bash #use GOARCH=amd64 for 64bit windows binaries
    ....compile progress...
    ┌─ oneofone@Oa [/u/s/g/src]                                                                                                      
    └──➜ cd /tmp
    
    ┌─ oneofone@Oa [/tmp]                                                                                                            
    └──➜ cat win-cgo-test.go 
    package main
    
    /*
    #include <stdlib.h>
    #include <stdio.h>
    */
    import "C"
    import "unsafe"
    
    func main() {
            hello := C.CString("Hello world")
            defer C.free(unsafe.Pointer(hello))
            C.puts(hello)
    }
    

    Then install the mingw toolchain, on Arch Linux:

    Add this to /etc/pacman.conf:

    [mingw-w64]
    SigLevel = Never
    Server = http://downloads.sourceforge.net/project/mingw-w64-archlinux/$arch
    Server = http://arch.linuxx.org/archlinux/$repo/os/$arch
    

    then run pacman -Syu mingw-w64-toolchain mingw-w64

    Edit: also if you are on a 64bit distro you need multilib gcc, on ArchLinux that's usually pacman -Sy multilib-devel.

    Depends on your distro, there's usually either a native repo or someone made a custom repo for mingw.

    After it all installs, you can compile your windows executables by running:

    ┌─ oneofone@Oa [/tmp]                                                                                                            
    └──➜ env GOOS=windows GOARCH=386 CGO_ENABLED=1 CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ CGO_LDFLAGS="-lssp" go build win-cgo-test.go 
    ┌─ oneofone@Oa [/tmp]                                                                                                            
    └──➜ file win-cgo-test.exe 
    win-cgo-test.exe: PE32 executable (console) Intel 80386 (stripped to external PDB), for MS Windows
    

    I have them as aliases in my shell, https://github.com/OneOfOne/etc-fish/blob/master/env/01-go.fish.

    I use Fish, however they are simple enough to port to Bash (or anything else really).

    //edit, a bonus

    If you want to get a list of the required dlls (99% of the time you don't need to copy anything, but just for the 1%):

    └──➜ i686-w64-mingw32-objdump -p win-cgo-test.exe | grep "DLL Name:"
            DLL Name: ws2_32.dll
            DLL Name: advapi32.dll
            DLL Name: ntdll.dll
            DLL Name: kernel32.dll
            DLL Name: winmm.dll
            DLL Name: msvcrt.dll
    
    评论

报告相同问题?

悬赏问题

  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 unity第一人称射击小游戏,有demo,在原脚本的基础上进行修改以达到要求
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line