Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 19717] ファイルの概要

このコミットは、Go言語のテストスクリプトである src/nacltest.bash に小さな変更を加えるものです。具体的には、Go Native Client (NaCl) 環境でのテスト実行時に、cmd/go コマンドが正しいGoのインストールパス(GOROOT)を参照するように修正しています。

コミット

nacltest.bash スクリプトにおいて、cmd/go を呼び出す前に GOROOT 環境変数を明示的に設定するように変更されました。これは、Goのビルドシステムが GOROOT_FINAL=/usr/local/go のような設定を使用している場合に、テスト環境内で cmd/go が誤ったGoのインストールを参照するのを防ぐための対応です。

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/54d0b5ab6a45dd9c0d8cf27ada3200c2f5ec6b28

元コミット内容

nacltest.bash: set GOROOT before invoking cmd/go
The builder builds with GOROOT_FINAL=/usr/local/go set.

TBR=rsc
R=golang-codereviews
CC=golang-codereviews
https://golang.org/cl/112100043

変更の背景

この変更の背景には、Go言語のビルドシステムと、Go Native Client (NaCl) 環境でのテスト実行における GOROOT 環境変数の扱いの問題があります。

Goの公式ビルドシステム、特に継続的インテグレーション (CI) 環境では、Goのツールチェインを特定のパスにインストールするように設定されることがあります。この際、GOROOT_FINAL という環境変数が使用されることがあります。GOROOT_FINAL は、Goのビルド時に、最終的にGoがインストールされるパスを埋め込むために使われることが意図されていました。例えば、/usr/local/go にインストールされることを想定してビルドが行われる場合、GOROOT_FINAL=/usr/local/go が設定されます。

しかし、nacltest.bash のようなテストスクリプトが cmd/go コマンドを呼び出す際、この GOROOT_FINAL の設定が原因で問題が発生する可能性がありました。テストスクリプトが実行されている現在のGoのソースツリーとは異なる、システムにインストールされている別のGoバージョン(GOROOT_FINAL で指定されたパス)を参照してしまう恐れがあったのです。

nacltest.bash は、Goのソースツリー内でビルドされたGoツールチェインを使用して、Go Native Client向けのテストを実行することを目的としています。もし cmd/go が誤った GOROOT を参照してしまうと、テスト対象のGoバージョンとは異なるツールチェインやライブラリが使用され、テストが失敗したり、意図しない結果になったりする可能性がありました。

このコミットは、このような問題を回避するために、nacltest.bash 内で明示的に GOROOT を現在のGoソースツリーのルートに設定し直すことで、cmd/go が常に正しいGoのインストールを参照するように保証しています。

前提知識の解説

Go言語 (Golang)

GoはGoogleによって開発されたオープンソースのプログラミング言語です。静的型付け、コンパイル型、並行処理のサポート、ガベージコレクションなどの特徴を持ち、シンプルさと効率性を重視しています。システムプログラミング、Webサービス、CLIツールなど幅広い分野で利用されています。

Go Native Client (NaCl)

Google Native Client (NaCl) は、ウェブブラウザ内でC/C++コードを安全かつ高性能に実行するための技術でした。Go言語もかつてはNaClへの実験的なサポートを提供しており、GoプログラムをNaClモジュールとしてコンパイルし、ウェブアプリケーション内で実行することが可能でした。これにより、Goの並行処理能力やパフォーマンスをウェブ環境で活用する試みが行われました。しかし、NaClはWebAssembly (Wasm) の登場により、その役割を終え、現在ではほとんど使用されていません。このコミットは、GoがNaClをサポートしていた時期の遺産と言えます。

GOROOT 環境変数

GOROOT はGo言語において非常に重要な環境変数です。これはGoのSDK(Software Development Kit)がインストールされているディレクトリのパスを指します。Goのコンパイラ (go build)、リンカ、標準ライブラリ、その他のツール (cmd/go など) は、この GOROOT の値に基づいて必要なファイルやパッケージを見つけます。

例えば、Goが /usr/local/go にインストールされている場合、GOROOT/usr/local/go に設定されます。Goのツールチェインが正しく機能するためには、この変数が適切に設定されている必要があります。

GOROOT_FINAL 環境変数

GOROOT_FINAL は、GoのソースコードからGoツールチェインをビルドする際に使用される、やや特殊な環境変数です。これは、ビルドされたGoツールチェインが最終的に配置されるパスをビルド時に埋め込むことを意図していました。例えば、開発環境でGoをビルドし、それを別の本番環境の /usr/local/go にデプロイする場合、ビルド時に GOROOT_FINAL=/usr/local/go を設定することで、ビルドされたバイナリがその最終パスを認識するように試みられました。

しかし、実際のところ GOROOT_FINAL は期待通りに機能しないケースが多く、ビルド時の GOROOT がバイナリに埋め込まれてしまう問題が頻繁に発生していました。このため、Goのビルドシステムでは、テストや実行時に明示的に GOROOT を設定し直すことが必要になる場合がありました。

cmd/go コマンド

cmd/go は、Go言語のビルド、テスト、パッケージ管理、フォーマットなど、Go開発における主要な操作を行うためのコマンドラインツールです。このコマンドは、内部的に GOROOT を参照して、Goの標準ライブラリやツールチェインの他の部分を見つけます。

シェルスクリプト (.bash)

nacltest.bash はBashシェルスクリプトであり、Goのテストスイートの一部として機能します。シェルスクリプトは、一連のコマンドを自動的に実行するために使用され、環境変数の設定、プログラムの実行、ファイルの操作などを行います。

技術的詳細

このコミットの技術的な核心は、Goのビルドプロセスにおける GOROOT の解決順序と、テスト環境におけるそのオーバーライドの必要性にあります。

通常、cmd/go は以下の順序で GOROOT を決定しようとします。

  1. GOROOT 環境変数が設定されていれば、その値を使用します。
  2. 設定されていなければ、cmd/go バイナリ自身のパスから相対的にGoのインストールパスを推測します。
  3. それでも見つからなければ、一般的なインストールパス(例: /usr/local/go)を試します。

問題は、Goのビルドシステムが GOROOT_FINAL を設定してビルドを行う場合、ビルドされた cmd/go バイナリが、その GOROOT_FINAL の値を内部的に「記憶」してしまう可能性があったことです。これにより、nacltest.bash が実行されているGoのソースツリーとは異なる、システム上の別のGoインストールを参照してしまうことが起こり得ました。

nacltest.bash は、Goのソースツリーをクローンし、その中でGoツールチェインをビルドし、そのビルドされたツールチェインを使ってNaCl向けのテストを実行します。このプロセスでは、テスト対象のGoソースツリーが GOROOT として機能する必要があります。

コミット前の状態では、./make.bash を実行した後、cmd/go を呼び出す際に、もしシステム環境に GOROOT_FINAL に基づく別のGoインストールが存在した場合、cmd/go がそちらを参照してしまう可能性がありました。これは、テストが意図したGoのバージョンや設定で行われないことを意味します。

このコミットでは、export GOROOT=$(pwd)/.. という行を追加することで、この問題を解決しています。

  • $(pwd) は現在の作業ディレクトリ、つまり src/ ディレクトリの絶対パスを返します。
  • .. は親ディレクトリを意味します。したがって、$(pwd)/..src/ ディレクトリの親ディレクトリ、つまりGoのソースツリーのルートディレクトリの絶対パスを指します。
  • export GOROOT=... は、この計算されたパスを GOROOT 環境変数に設定し、以降のコマンド(特に cmd/go)がこの新しい GOROOT の値を使用するようにします。

これにより、nacltest.bash が実行されるGoのソースツリーのルートが常に GOROOT として明示的に設定されるため、cmd/go はテスト対象のGoバージョンを確実に参照し、外部の GOROOT_FINAL の影響を受けなくなります。これは、テストの再現性と信頼性を保証するために重要な変更です。

コアとなるコードの変更箇所

--- a/src/nacltest.bash
+++ b/src/nacltest.bash
@@ -67,6 +67,9 @@ if [ ! -f make.bash ]; then
 fi
 GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH ./make.bash
 
+# the builder might have set GOROOT_FINAL.
+export GOROOT=$(pwd)/..
+
 # Build zip file embedded in package syscall.
 gobin=${GOBIN:-$(pwd)/../bin}
 rm -f pkg/syscall/fstest_nacl.go

コアとなるコードの解説

変更の中心は、src/nacltest.bash スクリプトに以下の3行が追加されたことです。

# the builder might have set GOROOT_FINAL.
export GOROOT=$(pwd)/..
  1. # the builder might have set GOROOT_FINAL.

    • これはコメント行で、この変更がなぜ行われたのかを説明しています。Goのビルドシステム(特にCI環境)が GOROOT_FINAL 環境変数を設定している可能性があるため、それに対応するための措置であることを示唆しています。
  2. export GOROOT=$(pwd)/..

    • $(pwd): これはシェルコマンドの置換機能で、現在の作業ディレクトリの絶対パスを返します。nacltest.bash が実行される際、通常はGoのソースツリーの src/ ディレクトリがカレントディレクトリになります。
    • /..: これはパスの親ディレクトリを意味します。したがって、$(pwd)/..src/ ディレクトリの親ディレクトリ、つまりGoのソースツリーのルートディレクトリの絶対パスを指します。
    • export GOROOT=...: このコマンドは、計算されたGoソースツリーのルートパスを GOROOT 環境変数に設定します。export キーワードは、この環境変数が現在のシェルプロセスだけでなく、そこから起動される子プロセス(この場合は cmd/go など)にも引き継がれることを保証します。

この変更により、nacltest.bash 内で cmd/go やその他のGoツールが呼び出される前に、GOROOT が明示的に現在のGoソースツリーのルートに設定されます。これにより、システムに存在する可能性のある他のGoインストール(GOROOT_FINAL の影響を受けたものなど)ではなく、テスト対象のGoソースツリーからビルドされたツールチェインとライブラリが確実に使用されるようになります。これは、テストの独立性と正確性を保つ上で非常に重要です。

関連リンク

参考にした情報源リンク