Go Wiki:GccgoCrossCompilation

簡介

如果您想在標準 Go 編譯器 gc 不支援的平台上執行 Go 程式,您可以建置一個針對您想要的目標平台的 GCC 編譯器版本,因為 GCC 支援更多平台。這是可行的,因為有一個名為 gccgo 的 GCC 的 Go 前端。

詳細資訊

定義

更多定義和複雜的交叉狀況可以在 維基百科文章 中找到。

Go 工具和 gccgo

稍後您將需要 Go 工具的原始碼,因此您最好解除安裝從套件管理員安裝的版本,以避免混淆(儘管完全是可選的)。此外,建置並安裝目標為主機的 gccgo(沒錯,您需要一個 gcco,不僅針對目標,還針對主機進行編譯)。

建置交叉編譯器

建置

首先,您必須建置 GCC 的交叉編譯版本。這是一個複雜的過程,因為它需要幾個階段的引導,因為 GCC 和 libc 實作之間存在相互依賴關係。Jim Blandy 編寫了一個非常好的教學,說明如何使用 eglic 建置 GCC 交叉工具鏈(也適用於 glibc),並張貼在 eglibc 的郵件清單中 修補程式交叉建置說明。在建置完整 GCC 的最後階段,只需使用 –enable-languages=c,c++,go 設定指令碼(請參閱 官方 Go 文件)。

您可以使用 ewxb_gcc_cross-compiler_builder 腳本作為起點。不要期望該腳本可以立即執行,而是作為一個提示,說明在建置 x 工具鏈時您可能會採取哪些步驟。

如果您很幸運,並且想要一個不是最新版本的 GCC(您可能想要擁有最新的 Go 功能),您可以使用交叉編譯器建構器來簡化設定,例如 crosstool-NG,它讓您可以透過一個簡單的 TUI 選單來設定 GCC。

較新的 crosstool-NG 版本可以透過啟用 CT_EXPERIMENTALCT_CC_SUPPORT_GOLANG 來建構 Go 語言。這會自動將 go 加入 --enable-languages

您現在應該有一個 bin 目錄,其中包含名稱類似於「<target>-gcc」、「<target>-gnu-gccgo」等檔案。由於 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 程式,以包含執行程式所需的所有內容。透過將 -static 開關新增至 gccgo 來執行此動作。如果您不確定如何連結您產生的 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>

待辦事項

使用 xgo 匯入「C」的 Go 程式似乎無法運作。目前受 Go issue#7398 阻擋

此 Wiki 頁面受到「[golang-nuts] MIPS 交叉編譯的簡化?」的啟發 @ https://groups.google.com/forum/#!topic/golang-nuts/PgyS2yoO2jM


此內容是 Go Wiki 的一部分。