在Wine环境下编译Golang应用程序

4
我正在尝试创建一个针对Go编写的应用程序的无人值守(可能是确定性的)构建流程。
该想法是使用创建Dockerfile文件,安装所有先决条件,以便可以轻松地与他人共享构建过程,而不需要真正的Windows安装。
然而,我在尝试构建具有C绑定的库时卡住了。
我得到了这个非常不描述性的错误提示。
C:\godev\src\github.com\obscuren\secp256k1-go>go build --work
WORK=C:\users\root\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.

完整日志可以在此找到,使用-x参数。

我可以在OS X和“真实”的Windows安装上轻松构建此库。

任何帮助将不胜感激。

编辑:

使用OneofOne提供的大纲也会给我带来一些错误。

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

当我启用Go的交叉编译时,最初遇到了这个错误。我通过安装gcc-multilib来克服它。下一个问题是以下内容。

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

Googling这个错误只有两个搜索结果,与我的用例无关。希望有人曾经遇到过这个问题。
编辑2:目前还不确定解决方案,但是我已经...
apt-get install gcc-multilib
apt-get install gcc-mingw-w64

并使用

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

现在我又向前迈进了一步。:)


1
它显示“访问被拒绝”,可能是权限问题。 - OneOfOne
我考虑过这个问题,但是所有的东西都是以 root 用户身份运行的。 - Maran
1个回答

4

虽然这并不是对确切问题的答案,但正确的方法是在Linux上使用mingw64进行交叉编译Windows可执行文件,我在我的项目中多次使用它,效果很好。

首先,您需要在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)
}

然后在 Arch Linux 上安装 mingw 工具链:

将以下内容添加到 /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

然后运行pacman -Syu mingw-w64-toolchain mingw-w64

编辑: 如果您使用的是64位发行版,则需要多库gcc,在ArchLinux上通常是pacman-Sy multilib-devel

根据您的发行版,通常有本地repo或有人为mingw创建了自定义repo。

全部安装完成后,您可以通过运行以下命令编译Windows可执行文件:

┌─ 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

我已将它们作为我的shell别名https://github.com/OneOfOne/etc-fish/blob/master/env/01-go.fish
我使用的是Fish,但这些别名非常简单,可以轻松移植到Bash(或其他任何Shell)。
//编辑,一个额外的奖励
如果你想获得所需dll文件的列表(99%的情况下你不需要复制任何东西,但只有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

1
感谢您详细的说明。我会尽快测试并看看能否使其正常工作 :) - Maran
我尝试了很多方法,但我仍然无法启用跨编译:# 运行时/cgo pkg/runtime/cgo/cgo.go:26:46: 致命错误:sys/types.h:没有那个文件或目录。有任何想法吗? ^编译终止。 - Maran
已更新原帖。 - Maran
我添加了一条编辑说明,如果你使用的是amd64架构,则需要multilib工具链。 - OneOfOne
任何想要从Linux(通常包括Ubuntu)构建Windows可执行文件并具有使用CGo功能的人可能对我的尝试总结感兴趣。请查看此摘要 - Michael Tiller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接