我正在尝试为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的完整日志可以be found here。
我可以在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’
Google搜索此错误会导致两次点击,这对我的用户案例无用。我希望以前有人经历过这个。
编辑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
现在我更进了一步。 :)
答案 0 :(得分:5)
虽然不是确切问题的答案,但这样做的正确方法是在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位发行版,则需要在ArchLinux上使用multilib gcc,通常为pacman -Sy multilib-devel
。
取决于你的发行版,通常有一个本地回购或有人为mingw定制回购。
完成所有安装后,您可以通过运行以下命令编译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(或其他任何东西)。
//编辑,奖金
如果你想获得所需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