Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体

343
votes
answers
楼主
27 views
+10

交叉編譯Go OSX?

我試圖在OSX上交叉編譯一個go app來為windows和linux構建二進製文件。我已經閱讀了網上可以找到的所有內容。我發現的最近的例子已經發表(除了許多未完成的關於瘋狂郵件列表的討論): http://solovyov.net/en/2012/03/09/cross-compiling-go/ 但它不適用於我的安裝。我去了1.0.2。由於1.0.2是最新版本,因此我認為以上所有示例都不適用於此版本。 嘗試將./make.bash --no-cleanENV變量設置為386 / windows,它確實構建了go,但它構建用於我的安裝,這darwin/amd64完全忽略了ENV中設置的構建不同編譯器的內容。 有人建議如何做(如果可以完成)?

與此同時,我在golang-nuts郵件列表上提出了相同的問題,並且在最終食譜得到熟食的幫助和耐心方面...這是討論主題:groups.google.com/forum/?fromgroups=# !topic / golang-nuts / ...有幾個步驟和結論,我在路上遇到了錯誤,但現在配方似乎很簡單 - 3個步驟和一些迭代。 - ljgww 2012年8月29日2:53

現在我正在回顧一下,我徘徊為什麼ENV vars沒有觸發正確的編譯 - 也許是因為我做了sudo(可能我會在sudo-ing時獲得不同的unix ENV所以如果它們不是GOOS&GOARCH將不可用完成內聯) - ljgww 2012年8月29日3:10

re:jdi - 我只是想在mac上編譯我的“mockup”go app來贏取/ lin二進製文件,但是,要做到這一點,我必須為平台/處理器的每個組合構建自己。(目前還不能回答我自己的問題 - 這裡聲譽不夠) - ljgww 2012年8月29日3:14

你輸入了它在示例中所說的內容嗎?CGO_ENABLED = 0 GOOS = windows GOARCH = amd64 ./make.bash - 如果你試圖將它分割成多行,那麼環境變量將不會被輸出以符合症狀--Nick Craig-Wood 2012年8月29日18 :14

確保您不會混淆主機和目標架構。你應該看到這個輸出:“#Build compilers and Go bootstrap tool for host,darwin / amd64。” “#為主機構建軟件包和命令,darwin / amd64。” “#為windows / 386構建軟件包和命令。” - Sam於2012年8月30日0:43

up vote 119 down vote accepted favorite
沙发
+1190
+50

使用Go 1.5,它們似乎改進了交叉編譯過程,這意味著它現在已經內置。不需要./make.bashbrew不需要。這裡描述這個過程但對於TLDR-ers(像我一樣):你只需設置GOOSGOARCH環境變量並運行go build。

對於那些更加懶散的複制貼紙(像我一樣),如果你在* nix系統上做這樣的事情:

env GOOS=linux GOARCH=arm go build -v github.com/path/to/your/app

你甚至學會了這個env技巧,它讓你只為該命令設置環境變量,完全免費。

env命令僅在自定義環境中運行該調用,並在完成後“重置”它。例如,運行導出GOOS = windows,然後是帶或不帶env和echo $ GOOS的命令。隨著env GOOS沒有改變。 - meonlol 2016年6月13日9:17

在沒有環境的情況下也是如此(至少在Bash中)。我運行導出GOOS = windows然後GOOS = linux bash -c'echo“GOOS:$ GOOS”'然後回顯“GOOS:$ GOOS”。env是否提供與其他shell方言或其他平台的更好兼容性?如果不是這裡似乎是多餘的。 - davidchambers 2016年6月13日14:43

@davidchambers在BASH中它們是等價的。而在其他一些Shell中,例如FISH shell,它不支持FOO = bar cmd,因此你必須使用env FOO = bar cmd。因此我認為使用env FOO = bar cmd的最大優點是兼容性。 - PickBoy 2016年12月1日12:12

難以置信的答案就在這裡。你解決了我的問題,教了我一個新的伎倆,讓我自言自語。 - T Blank 2017年1月16日6:07

很好的答案,謝謝!為了編譯在heroku(intel x86)上使用,我稍微修改了一行到env GOOS = linux GOARCH = 386 go build -v github.com/path/to/your/app它就像一個冠軍--Ira Herman Aug 18 '17在19:19

+1340

感謝golang-nuts的親切和耐心的幫助,配方如下:

1)需要為不同的目標平台和體系結構編譯Go編譯器。這是在go安裝中從src文件夾完成的。在我的案例中,Go安裝就位於/usr/local/go編譯需要發布make實用程序的編譯器在此之前,您需要了解一些注意事項。

交叉編譯時存在關於CGO庫的問題,因此需要禁用CGO庫。

編譯是通過將位置更改為源目錄來完成的,因為編譯必須在該文件夾中完成

cd /usr/local/go/src

然後編譯Go編譯器:

sudo GOOS=windows GOARCH=386 CGO_ENABLED=0 ./make.bash --no-clean

您需要通過更改GOOS和GOARCH參數,為希望交叉編譯的每個操作系統和體系結構重複此步驟。

如果您像我一樣在用戶模式下工作,則需要sudo,因為Go編譯器位於系統目錄中。否則,您需要以超級用戶身份登錄。在Mac上,您可能需要啟用/配置SU訪問(默認情況下不可用),但如果您已設法安裝Go,則可能已具有root訪問權限。

2)一旦構建了所有交叉編譯器,您就可以通過使用以下設置來愉快地交叉編譯應用程序,例如:

GOOS=windows GOARCH=386 go build -o appname.exe appname.go

GOOS=linux GOARCH=386 CGO_ENABLED=0 go build -o appname.linux appname.go

將GOOS和GOARCH更改為您要構建的目標。

如果您遇到CGO問題,請在命令行中包含CGO_ENABLED = 0。另請注意,linux和mac的二進製文件沒有擴展名,因此您可以添加擴展名以便擁有不同的文件。-o開關指示Go使輸出文件類似於c / c ++的舊編譯器,因此上面使用的appname.linux可以是任何其他擴展。

最初讓我感到困惑的是,在編譯的第一部分中說:#為主機構建編譯器和Go bootstrap工具,darwin / amd64但後來它實際上最終為:---在/ usr / local中安裝Go for windows / 386 / go / usr / local / go / bin中的已安裝命令,因此必須觀察結束而不是開始編譯編譯器。 - ljgww 2012年8月30日18:23

一切都是通過嘗試來做的:$ GOARCH = 386 GOOS = linux go build app.go並收到錯誤#timetime /usr/local/go/src/pkg/runtime/extern.go:137:undefined:theGoos / usr / local /go/src/pkg/runtime/extern.go:137:在const初始化程序中不能使用Goos作為類型字符串 - ljgww 2012年8月30日18:38

Homebrew中的Go包有一個選項“--cross-compile-all”,它將自動構建所有交叉編譯器。 - nimrodm 2014年4月28日19:30

很棒的提示@nimrodm!重新編譯你的安裝,你需要運行brew重新安裝go --cross-compile-all - linqu 2015年1月14日在17:06

@ljgww'sudo'沒有配置ENV。我最終在/ usr / local / go / pkg / linux_amd64 /上使用chown / - Nuno Silva 2015年10月9日12:51

+630

如果你在OS X上使用Homebrew,那麼你有一個更簡單的解決方案:

$ brew install go --with-cc-common # Linux, Darwin, and Windows

要么..

$ brew install go --with-cc-all # All the cross-compilers

reinstall如果您已經go安裝,請使用

注意到更新的開關是:--cross-compile-all為所有支持的平台構建交叉編譯器和運行時支持--cross-compile-common為darwin,linux和windows構建交叉編譯器和運行時支持 - Chip Tol Feb 17 '15在16:48

--cross-compile-all現在是--with-cc-all - gianebao 2015年5月13日8:32

@ sheeks06 - 修復。謝謝! - docwhat 2015年5月14日15:09

我所知道的這些旗幟不再存在。我看到的唯一相關選項是--without-cgo :( - rdegges 2015年9月24日5:23

從Go 1.5開始,沒有單獨的交叉編譯器,你現在只使用標誌tip.golang.org/doc/go1.5#compiler_and_tools - chuckus 2016年7月4日14:27

+190

您可以使用Docker輕鬆完成此操作,因此無需額外的庫。只需運行此命令:

docker run --rm -it -v "$GOPATH":/go -w /go/src/github.com/iron-io/ironcli golang:1.4.2-cross sh -c '
for GOOS in darwin linux windows; do
  for GOARCH in 386 amd64; do
    echo "Building $GOOS-$GOARCH"
    export GOOS=$GOOS
    export GOARCH=$GOARCH
    go build -o bin/ironcli-$GOOS-$GOARCH
  done
done
'

您可以在以下文章中找到更多詳細信息:https//medium.com/iron-io-blog/how-to-cross-compile-go-programs-using-docker-beaa102a316d

為什麼有人想安裝Docker來執行此操作時,他們可以在env上執行shell循環GOOS = x GOARCH = y go install something / ...並以$ GOPATH / bin / $ GOOS_ $ GOARCH下的相應二進製文件結束?? 而BTW,Go支持的不僅僅是你列出的三個操作系統,為什麼不喜歡BSD? - Dave C 2015年7月9日13:03

你不會只是為了這樣安裝Docker,但是如果你擁有它,這比替代方案更容易和更清潔。 - Travis Reeder 2015年7月9日23:38

+50

對於需要啟用CGO並從OSX目標窗口進行交叉編譯的人員

因為我導入了https://github.com/mattn/go-sqlite3並且需要它,所以我需要在從我的mac編譯窗口時啟用CGO根據其他答案編譯給了我和錯誤:

/usr/local/go/src/runtime/cgo/gcc_windows_amd64.c:8:10: fatal error: 'windows.h' file not found

如果你像我一樣,你必須用CGO編譯。這就是我做的:

1.我們將使用CGO依賴庫交叉編譯Windows。首先我們需要安裝一個交叉編譯器mingw-w64

brew install mingw-w64

這可能會在這里安裝它/usr/local/opt/mingw-w64/bin/

2.就像其他答案一樣,我們首先需要將windows arch添加到我們的go編譯器工具鏈中。編譯編譯器需要編譯器(奇怪的句子)編譯go編譯器需要一個單獨的預構建編譯器。我們可以在一個文件夾中下載一個預構建的二進製文件或從源代碼構建,例如:~/Documents/go 現在我們可以改進我們的Go編譯器,根據最佳答案,但這次使用CGO_ENABLED=1和我們單獨的預構建編譯器GOROOT_BOOTSTRAP(Pooya是我的用戶名):

cd /usr/local/go/src
sudo GOOS=windows GOARCH=amd64 CGO_ENABLED=1 GOROOT_BOOTSTRAP=/Users/Pooya/Documents/go ./make.bash --no-clean
sudo GOOS=windows GOARCH=386 CGO_ENABLED=1 GOROOT_BOOTSTRAP=/Users/Pooya/Documents/go ./make.bash --no-clean

3.編譯我們的Go代碼時,用於mingw編譯啟用了CGO的go文件定位窗口:

GOOS="windows" GOARCH="386" CGO_ENABLED="1" CC="/usr/local/opt/mingw-w64/bin/i686-w64-mingw32-gcc" go build hello.go
GOOS="windows" GOARCH="amd64" CGO_ENABLED="1" CC="/usr/local/opt/mingw-w64/bin/x86_64-w64-mingw32-gcc" go build hello.go
+30

為許多平台創建可執行文件的過程可能有點乏味,所以我建議使用腳本:

#!/usr/bin/env bash

package=$1
if [[ -z "$package" ]]; then
  echo "usage: $0 <package-name>"
  exit 1
fi
package_name=$package

#the full list of the platforms: https://golang.org/doc/install/source#environment
platforms=(
"darwin/386"
"dragonfly/amd64"
"freebsd/386"
"freebsd/amd64"
"freebsd/arm"
"linux/386"
"linux/amd64"
"linux/arm"
"linux/arm64"
"netbsd/386"
"netbsd/amd64"
"netbsd/arm"
"openbsd/386"
"openbsd/amd64"
"openbsd/arm"
"plan9/386"
"plan9/amd64"
"solaris/amd64"
"windows/amd64"
"windows/386" )

for platform in "${platforms[@]}"
do
    platform_split=(${platform//// })
    GOOS=${platform_split[0]}
    GOARCH=${platform_split[1]}
    output_name=$package_name'-'$GOOS'-'$GOARCH
    if [ $GOOS = "windows" ]; then
        output_name+='.exe'
    fi

    env GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $package
    if [ $? -ne 0 ]; then
        echo 'An error has occurred! Aborting the script execution...'
        exit 1
    fi
done

我只在OSX上檢查了這個腳本

gist - go-executable-build.sh

discard