[golang]移植 go 到新的作業系統與架構

研究如何將 go 移植到新的平台,這個似乎比移植 python 還難一點。

# 移植 go 到新的作業系統與架構
Go 1.5 之後,編譯 go 的方法
https://github.com/embeddedgo/go/tree/embedded/src/cmd/dist
https://docs.google.com/document/d/1OaatvGhEAq7VseQ9kkavxKNAfepWy2yhPUBs96FGV28/edit

根據這個文件,安裝新的 go,需要已經編譯好的 go。在還沒有 go 的地方,只能從 go1.4 開始編譯。因為 go1.4 是最後一個用 c 產生的 go 的編譯器。更高的版本都必須要用 go 來編譯。

官方文件 https://golang.org/doc/install/source 的方法,從 source 開始編譯 bootstrap toolchain,可以下載 https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz 。這個包裡面有做調整使它更適應新的作業系統。裡面可以支援的作業系統與指令集有限。

在 cmd/dist/build.c 裡有列出可用的作業系統與指令集
static char *okgoos[] = {
    "darwin",
    "dragonfly",
    "linux",
    "android",
    "solaris",
    "freebsd",
    "nacl",
    "netbsd",
    "openbsd",
    "plan9",
    "windows",
};

static char *gochars = "5668";

static char *okgoarch[] = {
    // same order as gochars
    "arm",
    "amd64",
    "amd64p32",
    "386",
};

在裡面會用到的 assambler, compiler, go compiler, linker 的程式碼,就放在 cmd/dist/[5-8][a,c,g,l]
例如,arm 架構就用 5[a,c,g,l],386 架構就用 8[a,c,g,l]

當 make.bash 能夠完整跑完,bootstrap toolchain 才算是完整。

裡面的流程是
1. 用 c 編譯 cmd/dist/dist 執行檔
2. 用 cmd/dist/dist bootstrap -a 編譯出 go_bootstrap 執行檔(原始檔來源 cmd/go)。cmd/dist/dist 會利用 [5-8][c,l] 與 gcc 編譯 .c 檔,用 [5-8][a] 編譯 .s 檔,用 [5-8][g,l] 編譯 .go 檔。
3. 用 go_bootstrap install 編譯 go 的其他 package,都是 .go 檔。
4. 最後刪除 go_bootstrap 執行檔
5. 用 cmd/dist/dist banner 顯示編譯資訊

以下有詳細指令關於從 source 編譯與安裝 go

http://www.boomerangsworld.de/cms/dev_guides/install_go.html

從以上資訊,可以了解到,在新的作業系統與架構上安裝 go,可能有兩種途徑:

1. 從 go1.4 開始,修正 cmd/dist/dist 的原始碼,認到正確的 GOOS GOARCH。然後在 cmd/dist/dist bootstrap 階段,提供正確的 a, c, g, l 的 .c, .s 檔案。

2. 使用 cross compile 的方式,在已經可以正常執行的環境下,編譯新架構的 go。在 go 大於 1.5 之後的版本,go compiler 與 go linker 的程式架構已經改變,所以要修改的程式與原來的 cmd/dist/[5-8][a,c,g,l] 不一樣。在 goroot/src/cmd/internal/obj, cmd/asm/internal, src/cmd/link, src/cmd/compile/internal/ssa/gen 這些地方都要修正。https://embeddedgo.github.io/2019/11/19/porting_go_to_microcontrollers_part1.html https://embeddedgo.github.io/2019/11/24/porting_go_to_microcontrollers_part2.html

假始只想要安裝 go1.4 的話,那麼就去修正 cmd/dist/[5-8][a,c,g,l] 應該就可以了。

如果,想要移殖新版的 go,應該採用第二個方法。產生一個新的 go。
如果採用第一個方法,在修正完 cmd/dist/[5-8][a,c,g,l] 之後,還要再修正 go compiler 與 go linker 的程式。等於做兩次工。
 

 

 

 

分享