在Wine下编译Golang应用程序

huangapple go评论125阅读模式
英文:

Compiling Golang applications under Wine

问题

我正在尝试为一个使用Go语言编写的应用程序创建一个无人值守(可能是确定性的)构建过程。

我的想法是使用一个Dockerfile来安装所有的先决条件,这样就可以轻松地与他人共享构建过程,而不需要一个真实的Windows安装。

然而,我在尝试构建一个具有C绑定的库时遇到了问题。

我得到了这个非常不明确的错误:

  1. C:\godev\src\github.com\obscuren\secp256k1-go>go build --work
  2. WORK=C:\users\root\Temp\go-build287695705
  3. # _/C_/godev/src/github.com/obscuren/secp256k1-go
  4. 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.

完整的日志可以在这里找到:1

我可以在OS X和一个“真实”的Windows安装上成功构建这个库。

任何帮助将不胜感激。

编辑:

按照OneofOne的大纲也给我带来了一些错误。

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

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

  1. # runtime/cgo
  2. gcc: error: unrecognized command line option ‘-mthreads

在谷歌上搜索这个错误只有两个结果,对我的用户案例没有用。我希望有人之前遇到过这个问题。

编辑2:

还不确定是什么解决了这个问题,但我做了以下操作:

  1. apt-get install gcc-multilib
  2. apt-get install gcc-mingw-w64

并使用以下命令:

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

现在我又前进了一步。 在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

  1. C:\godev\src\github.com\obscuren\secp256k1-go>go build --work
  2. WORK=C:\users\root\Temp\go-build287695705
  3. # _/C_/godev/src/github.com/obscuren/secp256k1-go
  4. 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.

  1. # runtime/cgo
  2. pkg/runtime/cgo/cgo.go:26:46: fatal error: sys/types.h: No such file or directory.
  3. 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.

  1. # runtime/cgo
  2. 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

  1. apt-get install gcc-multilib
  2. apt-get install gcc-mingw-w64

And used

  1. 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. 在Wine下编译Golang应用程序

答案1

得分: 4

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

首先,你需要在Go中启用交叉编译:

  1. ┌─ oneofone@Oa [~]
  2. └──➜ cd $GOROOT/src
  3. ┌─ oneofone@Oa [/u/s/g/src]
  4. └──➜ env GOOS=windows GOARCH=386 CGO_ENABLED=1 ./make.bash #对于64位Windows二进制文件,请使用GOARCH=amd64
  5. ....编译进度....
  6. ┌─ oneofone@Oa [/u/s/g/src]
  7. └──➜ cd /tmp
  8. ┌─ oneofone@Oa [/tmp]
  9. └──➜ cat win-cgo-test.go
  10. package main
  11. /*
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. */
  15. import "C"
  16. import "unsafe"
  17. func main() {
  18. hello := C.CString("Hello world")
  19. defer C.free(unsafe.Pointer(hello))
  20. C.puts(hello)
  21. }

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

将以下内容添加到/etc/pacman.conf:

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

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

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

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

安装完成后,可以通过运行以下命令来编译你的Windows可执行文件:

  1. ┌─ oneofone@Oa [/tmp]
  2. └──➜ 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
  3. ┌─ oneofone@Oa [/tmp]
  4. └──➜ file win-cgo-test.exe
  5. 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%的情况):

  1. └──➜ i686-w64-mingw32-objdump -p win-cgo-test.exe | grep "DLL Name:"
  2. DLL Name: ws2_32.dll
  3. DLL Name: advapi32.dll
  4. DLL Name: ntdll.dll
  5. DLL Name: kernel32.dll
  6. DLL Name: winmm.dll
  7. DLL Name: msvcrt.dll
英文:

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:

  1. ┌─ oneofone@Oa [~]
  2. └──➜ cd $GOROOT/src
  3. ┌─ oneofone@Oa [/u/s/g/src]
  4. └──➜ env GOOS=windows GOARCH=386 CGO_ENABLED=1 ./make.bash #use GOARCH=amd64 for 64bit windows binaries
  5. ....compile progress...
  6. ┌─ oneofone@Oa [/u/s/g/src]
  7. └──➜ cd /tmp
  8. ┌─ oneofone@Oa [/tmp]
  9. └──➜ cat win-cgo-test.go
  10. package main
  11. /*
  12. #include &lt;stdlib.h&gt;
  13. #include &lt;stdio.h&gt;
  14. */
  15. import &quot;C&quot;
  16. import &quot;unsafe&quot;
  17. func main() {
  18. hello := C.CString(&quot;Hello world&quot;)
  19. defer C.free(unsafe.Pointer(hello))
  20. C.puts(hello)
  21. }

Then install the mingw toolchain, on Arch Linux:

Add this to /etc/pacman.conf:

  1. [mingw-w64]
  2. SigLevel = Never
  3. Server = http://downloads.sourceforge.net/project/mingw-w64-archlinux/$arch
  4. 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:

  1. ┌─ oneofone@Oa [/tmp]
  2. └──➜ env GOOS=windows GOARCH=386 CGO_ENABLED=1 CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ CGO_LDFLAGS=&quot;-lssp&quot; go build win-cgo-test.go
  3. ┌─ oneofone@Oa [/tmp]
  4. └──➜ file win-cgo-test.exe
  5. 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%):

  1. └──➜ i686-w64-mingw32-objdump -p win-cgo-test.exe | grep &quot;DLL Name:&quot;
  2. DLL Name: ws2_32.dll
  3. DLL Name: advapi32.dll
  4. DLL Name: ntdll.dll
  5. DLL Name: kernel32.dll
  6. DLL Name: winmm.dll
  7. DLL Name: msvcrt.dll

huangapple
  • 本文由 发表于 2014年7月28日 23:07:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/24998260.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定