🍣

golang コンパイラのブートストラップ

2024/05/02に公開

golang コンパイラのブートストラップ

この記事では ubuntu 22.04 を利用する。

概要

golang (go言語)コンパイラ自身のコンパイルを行う。
手順だけ知りたい場合 まとめ の手順を実施すればよい。

  1. golangのコンパイラ自身は最新版のソースコードが go言語で記載されている。
  2. 最新版バージョンは少し古いバージョンの golang のコンパイラでビルドできる。
  3. そのコンパイラはさらに少し古いバージョンの golang のコンパイラでビルドできる。
  4. 最終的に go1.4またはそれ以前のコンパイラは c言語のコンパイラでビルドできる。

コンパイラが対象言語で記述されている場合にコンパイラ自身のコンパイルをするときの流れをブートストラップと呼ぶ。(ここでは golang のコンパイラが golang で記述されているときにどうやって自分自身をコンパイルするかという課題を解決するか)

処理の流れ

  1. c コンパイラおよび git をインストールする。
  2. 必要なバージョンのすべての go のコンパイラのソースコードを入手する。
  3. go 1.4 を C コンパイラでビルドする。
  4. go 1.17 を go 1.4 コンパイラでビルドする。
  5. go 1.20 を go 1.17 コンパイラでビルドする。
  6. go 1.22 を go 1.20 コンパイラでビルドする。
  7. go master (2024/8/27 現在) を go 1.22 コンパイラでビルドする。

参考情報

Installing Go from sourceInstall Go compiler binaries for bootstrap

Go <= 1.4: a C toolchain.
1.5 <= Go <= 1.19: a Go 1.4 compiler.
1.20 <= Go <= 1.21: a Go 1.17 compiler.
1.22 <= Go <= 1.23: a Go 1.20 compiler.
Going forward, Go version 1.N will require a Go 1.M compiler, where M is N-2 rounded down to an even number. Example: Go 1.24 and 1.25 require Go 1.22.

準備

c コンパイラおよび git をインストール

sudo apt install -y build-essential  git

golang のコンパイラのソースコードを入手

1 か 2 のいずれかからソースを入手する。

1. github から入手する場合

git clone -b release-branch.go1.4  https://github.com/golang/go go1.4
git clone -b release-branch.go1.17 https://github.com/golang/go go1.17
git clone -b release-branch.go1.20 https://github.com/golang/go go1.20
git clone -b release-branch.go1.22 https://github.com/golang/go go1.22
git clone                          https://github.com/golang/go go-master

2. googlesource.com から入手する場合

git clone -b release-branch.go1.4  https://go.googlesource.com/go go1.4
git clone -b release-branch.go1.17 https://go.googlesource.com/go go1.17
git clone -b release-branch.go1.20 https://go.googlesource.com/go go1.20
git clone -b release-branch.go1.22 https://go.googlesource.com/go go1.22
git clone                          https://go.googlesource.com/go go-master

ビルド

go 1.4 を C コンパイラでビルド

(                                         cd go1.4/src     && ./make.bash )
  • コマンド全体を 括弧で囲んでいるのは cd してカレントディレクトリを変更した後に元のディレクトリに cd しなおす手間を省くため。
  • 括弧で囲んでいることにより、括弧内の処理を抜けるとカレントディレクトリは自動的に元のディレクトリに戻る。

go 1.17 を go 1.4 コンパイラでビルド

(export GOROOT_BOOTSTRAP=$(pwd)/go1.4  && cd go1.17/src    && ./make.bash )

go 1.20 を go 1.17 コンパイラでビルド

(export GOROOT_BOOTSTRAP=$(pwd)/go1.17 && cd go1.20/src    && ./make.bash )

go 1.22 を go 1.20 コンパイラでビルド

(export GOROOT_BOOTSTRAP=$(pwd)/go1.20 && cd go1.22/src    && ./make.bash )

master (2024/8/27 現在) を go 1.22 コンパイラでビルド

(export GOROOT_BOOTSTRAP=$(pwd)/go1.22 && cd go-master/src && ./make.bash )

※ 将来のバージョンでは Install Go compiler binaries for bootstrap にある通り、さらに間に別のバージョンの go コンパイラを挟む必要がある可能性がある。

まとめ

事前準備

sudo apt install -y build-essential  git
git clone -b release-branch.go1.4  https://github.com/golang/go go1.4
git clone -b release-branch.go1.17 https://github.com/golang/go go1.17
git clone -b release-branch.go1.20 https://github.com/golang/go go1.20
git clone -b release-branch.go1.22 https://github.com/golang/go go1.22
git clone                          https://github.com/golang/go go-master

ビルドスクリプト

#!/bin/sh -e

(                                         cd go1.4/src     && ./make.bash )
(export GOROOT_BOOTSTRAP=$(pwd)/go1.4  && cd go1.17/src    && ./make.bash )
(export GOROOT_BOOTSTRAP=$(pwd)/go1.17 && cd go1.20/src    && ./make.bash )
(export GOROOT_BOOTSTRAP=$(pwd)/go1.20 && cd go1.22/src    && ./make.bash )
(export GOROOT_BOOTSTRAP=$(pwd)/go1.22 && cd go-master/src && ./make.bash )

GitHub

https://github.com/m-tmatma/golang-compiler-bootstrap

Discussion