如何在Linux上编译跨平台的Go语言项目?

我正在尝试在Linux上设置我的Go编译器,它可以编译任何其他体系结构或平台的项目。 我使用官方Ubuntu 14.04版本库中的默认软件包,我使用的是64位系统。 这个configuration允许我编译只适用于Linux,只适用于64位系统。 至less我想编译32位Linux甚至32位Windows系统。 是否有可能做某事?

还有一件事是我想用两个Go绑定: https : //github.com/mattn/go-gtk和https://github.com/mattn/go-webkit

我正在使用go-webkit示例代码进行testing:

package main import ( "os" "github.com/mattn/go-gtk/gtk" "github.com/mattn/go-webkit/webkit" ) const HTML_STRING = ` <doctype html> <meta charset="utf-8"/> <style> div { font-size: 5em } </style> <script src="http://code.jquery.com/jquery-latest.js"></script> <script> $(function() { $('#hello1').slideDown('slow', function() { $('#hello2').fadeIn() }) }) </script> <div id="hello1" style="display: none">Hello</div> <div id="hello2" style="display: none">世界</div> </div> ` const MAP_EMBED = ` <style> *{ margin : 0; padding : 0; } </style> <iframe width="100%" height="100%" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.co.jp/maps?f=q&amp;source=s_q&amp;hl=en&amp;geocode=&amp;q=osaka&amp;aq=&amp;sll=34.885931,-115.180664&amp;sspn=29.912003,39.506836&amp;brcurrent=3,0x6000e86b2acc70d7:0xa399ff48811f596d,0&amp;ie=UTF8&amp;hq=&amp;hnear=%E5%A4%A7%E9%98%AA%E5%BA%9C%E5%A4%A7%E9%98%AA%E5%B8%82&amp;ll=34.693738,135.502165&amp;spn=0.471406,0.617294&amp;z=11&amp;output=embed"></iframe> ` func main() { gtk.Init(nil) window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL) window.SetTitle("webkit") window.Connect("destroy", gtk.MainQuit) vbox := gtk.NewVBox(false, 1) entry := gtk.NewEntry() entry.SetText("http://golang.org/") vbox.PackStart(entry, false, false, 0) swin := gtk.NewScrolledWindow(nil, nil) swin.SetPolicy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) swin.SetShadowType(gtk.SHADOW_IN) webview := webkit.NewWebView() webview.Connect("load-committed", func() { entry.SetText(webview.GetUri()) }) swin.Add(webview) vbox.Add(swin) entry.Connect("activate", func() { webview.LoadUri(entry.GetText()) }) button := gtk.NewButtonWithLabel("load String") button.Clicked(func() { webview.LoadString("hello Go GTK!", "text/plain", "utf-8", ".") }) vbox.PackStart(button, false, false, 0) button = gtk.NewButtonWithLabel("load HTML String") button.Clicked(func() { webview.LoadHtmlString(HTML_STRING, ".") }) vbox.PackStart(button, false, false, 0) button = gtk.NewButtonWithLabel("Google Maps") button.Clicked(func() { webview.LoadHtmlString(MAP_EMBED, ".") }) vbox.PackStart(button, false, false, 0) window.Add(vbox) window.SetSizeRequest(600, 600) window.ShowAll() proxy := os.Getenv("HTTP_PROXY") if len(proxy) > 0 { soup_uri := webkit.SoupUri(proxy) webkit.GetDefaultSession().Set("proxy-uri", soup_uri) soup_uri.Free() } entry.Emit("activate") gtk.Main() } 

如果我编译它工作正常

 go build 

如果我尝试使用其他设置进行编译:

 GOOS=windows GOARCH=386 go build GOARCH=386 go build 

我得到这个错误:

webview.go:5:2:在/home/yeeapple/Documents/Coding/Go/Source/src/github.com/mattn/go-gtk/gtk中没有可构build的Go源文件

webview.go:6:2:/home/yeeapple/Documents/Coding/Go/Source/src/github.com/mattn/go-webkit/webkit中没有可构build的Go源文件

我看到的另一件事是,在GOPATH目录和pkg文件夹是只有“linux_amd64”文件夹与* .a文件。

例如,如果没有其他导入,我可以为其他系统编译Go文件。 跨平台编译工作正常:

 package main import "fmt" func main() { fmt.Printf("hello, world\n") } 

版本:

 $ go version go version go1.2.1 linux/amd64 $ gccgo --version gccgo (Ubuntu 4.9-20140406-0ubuntu1) 4.9.0 20140405 (experimental) [trunk revision 209157] Copyright (C) 2014 Free Software Foundation, Inc. 

使用Go 1.2,交叉编译代码时cgo功能被禁用。 这意味着任何包含import "C"源文件都不会被编译,这会导致许多软件包无法使用。 所以,当您简单的“hello world”程序编译时,使用cgo的等效程序将会失败:

 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) } 

在amd64 Linux系统上,如果您尝试为x86编译,将会出现构建失败:

 $ GOARCH=386 go build hello.go can't load package: no buildable Go source files in /... 

为了编译这个程序,你还需要设置环境变量CGO_ENABLED=1手动启用cgo 。 这将导致它尝试编译该程序,但是如果您没有安装x86编译器,它仍然会失败。 既然你说你在使用Ubuntu,你可以通过安装gcc-multilib软件包来完成:

 $ sudo apt-get install gcc-multilib 

安装后,你应该可以编译程序:

 $ GOARCH=386 CGO_ENABLED=1 go build hello.go $ file hello hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=..., not stripped 

虽然Ubuntu提供了Windows交叉编译工具链(在mingw32包中),但编译Windows二进制文件时仍然有问题:

 $ GOOS=windows GOARCH=386 CGO_ENABLED=1 go build hello.go go build runtime/cgo: cannot use cgo when compiling for a different operating system 

这个检查在GO 1.3中不再存在,所以你可能会对这个版本有一些好运。

现在使用交叉编译器工具链只是战斗的一部分:您还需要为可用的目标体系结构编译您的依赖项的版本。 对于像WebKit那样大的东西,这并不是微不足道的,但是你可以使用CFLAGSLDFLAGSPKG_CONFIG_PATH环境变量指向Go一个合适的副本。