Go Wiki: Gccgoクロスコンパイル

はじめに

標準のGoコンパイラ *gc* でサポートされていないプラットフォームでGoプログラムを実行したい場合、GCCがより多くのプラットフォームをサポートしているため、目的のターゲットプラットフォームをターゲットとするGCCコンパイラのバージョンをビルドできます。これは、GCCにgccgoというGoフロントエンドがあるため可能です。

詳細

定義

より多くの定義と複雑なクロス状況については、Wikipediaの記事をご覧ください。

Goツールとgccgo

後でGoツールのソースコードが必要になるので、混乱を避けるためにパッケージマネージャーからインストールしたバージョンをアンインストールしても構いません(完全にオプションです)。また、ホストをターゲットとするgccgoをビルド&インストールします(そうです、ターゲットだけでなくホスト用のgccoも必要です)。

クロスコンパイラのビルド

ビルド

まず、クロスコンパイルバージョンのGCCをビルドする必要があります。GCCとlibc実装の間に相互依存関係があるため、ブートストラップによる複数の段階が必要となる複雑なプロセスです。eglic(glibcでも動作します)を使用してGCCクロツールチェーンをビルドする方法に関する非常に優れたチュートリアルは、Jim Blandyによって書かれ、eglibcのメーリングリストに投稿されました patches Cross-building instructions。完全なGCCがビルドされる最終段階では、単に*–enable-languages=c,c++,go*でスクリプトを設定します(Go公式ドキュメントを参照)。

ewxb_gcc_cross-compiler_builder スクリプトを開始点として使用できます。このスクリプトがそのまま動作することを期待するのではなく、x-toolchainをビルドする際の手順のヒントとして使用してください。

最新版である必要がなく(最新のGo機能が必要な場合があります)、幸運にもGCCのバージョンが必要な場合は、クロスコンパイラビルダーを使用して設定を容易にすることができます。たとえば、crosstool-NGを使用すると、シンプルなTUIメニューでGCCを設定できます。

crosstool-NGの新しいバージョンでは、`CT_EXPERIMENTAL`と`CT_CC_SUPPORT_GOLANG`を有効にすることで、Go言語をビルドできます。これにより、`--enable-languages`に自動的に`go`が追加されます。

これで、「`<target`>-gcc」、「`<target`>-gnu-gccgo」などの名前のファイルを含むbinディレクトリが作成されます。Goビルドツールでは、使用するコンパイラのファイル名を指定できないため(文字列「gc」と「gccgo」のみを静的にサポート)、$PATH環境変数で「gccgo」と「gcc」という名前の最初のファイルを検索します。したがって、クロスコンパイラを使用する場合、システム上の通常のgccバイナリではなく、このディレクトリをオーバーレイとして追加し、$PATHの最初に設定する必要があります。Goツールは*gccgo*という名前のバイナリを検索するため、ツールが見つけるためのシンボリックリンクを作成する必要があります。

    $ cd path/to/cross-comp-gcc/bin
    $ ln -s <arch>-<os>-gnu-gcc gcc 
    $ ln -s <arch>-<os>-gnu-gccgo gccgo
    $ ln -s <arch>-<os>-gnu-ar ar
    $ export PATH="path/to/crosscomp-gcc/bin:$PATH" # Do this whenever you want to use the cross-compilers targeting your target instead of the system default targeting host.

など

$TARGETをターゲットアーキテクチャに、$PREFIXをビルドされたファイルの出力先に設定すると、シンボリックリンクを作成できます

##!/usr/bin/env bash        

cd $PREFIX/bin
for file in $(find . -type f); do       
    tool_name=$(echo $file | sed -e "s/${TARGET}-\(.*\)$/\1/")      
    ln -sf "$file" "$tool_name"         
done

テスト

クロスコンパイラのビルドが完了したら、簡単なCプログラムと簡単なGoプログラムの両方で動作することをテストする必要があります。

    $ gccgo -Wall -o helloworld helloworld.go
    $ file helloworld # verify that the architecture of the binary is the desired target and not a binary that can run on your host machine.
    $ <upload-command-to-target> helloworld
    $ <ssh/telnet etc. to target and test run>

注意点

ターゲット用にGoライブラリ*libgo*の共有オブジェクトをコンパイルしていない場合は、*gc*と同様に、Goプログラムを静的にコンパイルして、プログラムの実行に必要なすべてを含めることができます。これを行うには、gccgoに*-static*スイッチを追加します。生成されたELFファイルのリンク方法がわからない場合は、*readelf -d `<elf>`*または*objdump -T `<elf>`*で検査します。

クロスgccgo対応バージョンのGoツールのビルド

前提条件

ビルド

*go build -compiler gccgo `<go-package,files>`*を使用して、Goツールでビルドするときに使用するコンパイラを指定できます。ただし、これだけでは十分ではありません。*$GOARCH*と*$GOOS*を*gc*ではサポートされていないが*gccgo*ではサポートされている値に設定した場合、これらの追加アーキテクチャを理解する特別なバージョンのGoツールをビルドする必要があります。Goツールで別のバージョンのGoツールをコンパイルしますが、ホストをターゲットとするgccgoを使用するように指定すると、結果のGoツールはgccgoでサポートされているすべてのアーキテクチャでプログラムをコンパイルできます。

    $ cd ~/tmp
    $ hg clone ~/src/go # [0]
    $ cd go/src/cmd/go
    $ go build -o xgo -compiler gccgo . # [1] [2] [3]
    $ cp xgo ~/bin/ # Or any directory that is in your $PATH

Goプログラムのクロスコンパイル。

*$PATH*を_xgo_とクロスコンパイルバージョンの_gccgoを見つけ、*$GOARCH*を適切に設定すると、Goツール(xgoという名前)を使用してクロスコンパイルできるようになりました。

    $ export PATH="path/to/xgo/:path/to/crosscomp-gccgo/:$PATH"
    $ export GOARCH="<you-target's-arch>"
    $ export GOOS="<you-target's-OS>"
    $ xgo build -compiler gccgo <go-package/files>

TODO

「C」をインポートするGoプログラムは、xgoを使用して動作しないようです。現在、Go issue#7398によってブロックされています

このWikiページは、https://groups.google.com/forum/#!topic/golang-nuts/PgyS2yoO2jMの "[golang-nuts] MIPSクロスコンパイルの簡素化?"から得られた教訓に触発されています。


このコンテンツはGo Wikiの一部です。