OSXでGoをクロスコンパイルしますか?


142

OS Xでgoアプリをクロスコンパイルして、WindowsとLinuxのバイナリをビルドしようとしています。ネットで見つけたものをすべて読みました。私が見つけた最も近い例が公開されています(go-nutsメーリングリストでの多くの未完成の議論は別として):

http://solovyov.net/en/2012/03/09/cross-compiling-go/

それでも私のインストールでは動作しません。1.0.2に移行しました。1.0.2はごく最近のバージョンなので、上記の例はすべてこのバージョンには適用されないようです。

./make.bash --no-cleanENV varsを386 / windowsに設定して試してみましたが、ビルドはビルドdarwin/amd64されますが、別のコンパイラーをビルドすることを想定しているENVでの設定を完全に無視して、私のインストール用にビルドをビルドします。

どのようにしてそれを行うことができますか?


これと並行して、私はgolang-nutsメーリングリストで同じ質問をしました。そして、親切な助けと忍耐強い人々のおかげで、最終的なレシピが作成されました...これはディスカッションスレッドです: groups.google.com/forum/?fromgroups=# !topic / golang-nuts /… いくつかのステップと結論がありましたが、途中で間違えましたが、レシピはかなりシンプルに見えます-3ステップといくつかの反復。
ljgww 2012

要約すると、ENV varsが正しいコンパイルをトリガーしなかった理由をたどっています-おそらく私はそうしたためですsudo(おそらく、sudoを実行すると別のunix ENVを取得するため、GOOSとGOARCHが実行されない場合は利用できません)インライン)
ljgww 2012

re:jdi-Macでwin / linバイナリに "モックアップ" goアプリをコンパイルしようとしていましたが、それを行うには、プラットフォーム/プロセッサの組み合わせごとにgo自体をビルドする必要がありました。(まだ自分の質問に答えることはできません-ここでは十分な評判がありません)
ljgww '29

1
例で言ったことを正確に入力しましたか?CGO_ENABLED=0 GOOS=windows GOARCH=amd64 ./make.bash-複数行に分割しようとした場合、症状に合った環境変数はエクスポートされません
Nick Craig-Wood

ホストとターゲットのアーキテクチャを混同していないことを確認してください。次の出力が表示されます。「#ホストdarwin / amd64用のビルドコンパイラとGoブートストラップツール。」「#ホストdarwin / amd64のパッケージとコマンドをビルドしています。」「#windows / 386用のパッケージとコマンドのビルド。」
サム

回答:


157

Go 1.5では、クロスコンパイルプロセスが改善されたようです。つまり、現在組み込まれています。./make.bash-ingまたはbrew-ingは必要ありません。プロセスが説明され、ここが、そこに(私のような)TLDR-ERSのために:あなただけの設定GOOSGOARCH環境変数をして行くのビルドを実行します。

* nixシステムを使用している場合は、(私のような)平凡なコピーペーストで、次のようにします。

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

envそのコマンドのみの環境変数を完全に無料で設定できるトリックまで学びました。


4
envコマンドが実行されるだけで、カスタム環境での呼び出しとそれが行われ、それの後に「リセット」。例えば、実行のためにexport GOOS=windows、の有無にかかわらず、コマンドenvecho $GOOSその後。envGOOSは変更されませんでした。
leondepeon

3
(少なくともBashでは)同じことが当てはまりますenvexport GOOS=windowsその後GOOS=linux bash -c 'echo "GOOS: $GOOS"'、私は走ったecho "GOOS: $GOOS"env他のシェルの方言で、または他のプラットフォームとの大きな互換性を提供?そうでない場合は、ここでは不要のようです。
davidchambers 2016年

2
@davidchambers BASHでは、これらは同等です。他のシェル(FISHシェルなど)ではサポートされていないためFOO=bar cmd、を使用する必要がありますenv FOO=bar cmd。したがって、使用する最大の利点env FOO=bar cmdは互換性です。
PickBoy

1
ここで信じられないほどの答え。あなたは私の問題を解決し、私に新しいトリックを教え、そして私を独り言にさせました。
Tブランク

1
すばらしい回答、ありがとうございます!heroku(intel x86)で使用するためにコンパイルするために、行をわずかに変更しenv GOOS=linux GOARCH=386 go build -v github.com/path/to/your/app、それはチャンピオンのように機能します
Ira Herman

136

golang-nutsの親切で忍耐強いサポートのおかげで、レシピは次のようになります。

1)異なるターゲットプラットフォームおよびアーキテクチャ用に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パラメータを変更して、クロスコンパイルするOSおよびアーキテクチャごとにこの手順を繰り返す必要があります。

私と同じようにユーザーモードで作業している場合は、Goコンパイラがシステムディレクトリにあるため、sudoが必要です。それ以外の場合は、スーパーユーザーとしてログインする必要があります。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スイッチは、c / c ++の古いコンパイラと同様に出力ファイルを作成するようにGoに指示します。したがって、上記で使用されたappname.linuxは、他の任意の拡張子にすることができます。


最初に私を混乱させたのは、コンパイルの最初の部分でmakeが言うことです# Building compilers and Go bootstrap tool for host, darwin/amd64が、後で実際には次の--- Installed Go for windows/386 in /usr/local/go Installed commands in /usr/local/go/binようになります。
ljgww 2012

すべてはやろうとすることから始まりました:$ GOARCH=386 GOOS=linux go build app.goそしてエラーが発生しました # runtime /usr/local/go/src/pkg/runtime/extern.go:137: undefined: theGoos /usr/local/go/src/pkg/runtime/extern.go:137: cannot use theGoos as type string in const initializer
ljgww

30
GoのHomebrewのパッケージには、すべてのクロスコンパイラを自動的にビルドするオプション「--cross-compile-all」があります。
nimrodm 2014

8
素晴らしいヒント@nimrodm!goインストールを再コンパイルするには、実行する必要がありますbrew reinstall go --cross-compile-all
linqu

1
@ljgww 'sudo'にはENVが設定されていません。最終的に/ usr / local / go / pkg / linux_amd64 /でchownを使用しました
Nuno Silva

63

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インストールしている場合に使用します。


3
留意更新スイッチは、次のとおりです。すべてのサポートされるプラットフォーム--cross-コンパイル共通ビルド用--cross-コンパイルすべてのビルドクロスコンパイラとランタイムサポートをクロスコンパイラやダーウィン、LinuxとWindowsのためのランタイム・サポート
チップコウサ

3
--cross-compile-allが現在--with-cc-all
gianebao

@ sheeks06-修正されました。ありがとう!
docwhat

1
これらのフラグは、私の知る限りでは存在しません。私が見る唯一の関連オプションは--without-cgo :(
rdegges

5
Go 1.5以降、個別のクロスコンパイラーはなく、フラグのみを使用します。tip.golang.org
doc / go1.5#

24

これは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


1
シェルループをenv GOOS=x GOARCH=y go install something/...実行して適切なバイナリが作成されるのに、なぜDockerをインストールしてこれを実行するのでしょう$GOPATH/bin/$GOOS_$GOARCHか?ところで、Goはあなたがリストした3つ以上のOSをサポートしています。なぜBSDを愛さないのですか?
Dave C

8
これを行うためだけにDockerをインストールすることはありませんが、それがある場合は、他の方法より簡単でクリーンです。
Travis Reeder 2015

7

多くのプラットフォームで実行可能ファイルを作成するプロセスは少々面倒なので、スクリプトを使用することをお勧めします。

#!/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


私が探していたまさに...私はそれをdockerizedている:) gist.github.com/marcellodesales/...
マルチェロドゥ販売

6

CGOを有効にし、OSXターゲットウィンドウからクロスコンパイルする必要がある人向け

私は必要なCGOは、私が輸入していたので、私のMacからWindows用のコンパイル中に有効https://github.com/mattn/go-sqlite3、それはそれを必要としていました。他の回答に従ってコンパイルすると、エラーが発生しました:

/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アーチをgoコンパイラーツールチェーンに追加する必要があります。コンパイラーをコンパイルするには、コンパイラー(奇妙な文)が必要です。goコンパイラーをコンパイルするには、別のビルド済みコンパイラーが必要です。ビルド済みのバイナリをダウンロードするか、フォルダー内のソースからビルドする~/Documents/go ことができます。例:Goコンパイラーを改善できるようにCGO_ENABLED=1なりましたGOROOT_BOOTSTRAP

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.