[インデックス 11934] ファイルの概要
コミット
- コミットハッシュ:
0724e5cefe92f9f4fd52101e3a7a25299a2b7f63
- 作者: Mikio Hara mikioh.mikioh@gmail.com
- コミット日時: 2012年2月15日 23:52:07 +0900
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/0724e5cefe92f9f4fd52101e3a7a25299a2b7f63
元コミット内容
build: fix clean.bash
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5672052
変更の背景
このコミットは、Go言語のビルドシステムにおける clean.bash
スクリプトの修正を目的としています。clean.bash
は、Goのソースツリーからビルドによって生成されたファイルやディレクトリを削除し、クリーンな状態に戻すためのスクリプトです。
以前の clean.bash
スクリプトでは、go tool dist
コマンドが生成する環境変数(特に $GOTOOLDIR
)を適切に利用できていませんでした。具体的には、../bin/tool/dist
という相対パスで dist
ツールを参照していましたが、これはビルド環境や実行コンテキストによっては正しく解決できない可能性がありました。
この問題は、Goのビルドプロセスが進化する中で、ツールの配置や環境変数の設定方法が変更されたことに起因していると考えられます。go tool dist env
コマンドは、Goのビルドツールが使用する環境変数を標準出力に出力する機能を提供しており、これを eval
コマンドと組み合わせることで、スクリプト内でこれらの環境変数を確実に設定できます。
このコミットの目的は、clean.bash
が dist
ツールやその他のビルド関連パスを確実に特定できるようにし、クリーンアップ処理の堅牢性を向上させることにあります。これにより、異なる環境やGoのバージョンアップ後でも、clean.bash
が期待通りに動作することが保証されます。
前提知識の解説
Go言語のビルドシステム
Go言語は、そのソースコードからコンパイラ、リンカ、標準ライブラリ、各種ツール(go
コマンド自体や dist
ツールなど)をビルドする独自のシステムを持っています。このビルドプロセスは、通常、Goのソースツリーのルートにある all.bash
や make.bash
(Windowsでは make.bat
) といったスクリプトによって開始されます。
clean.bash
clean.bash
は、Goのソースツリーをクリーンアップするためのシェルスクリプトです。具体的には、go install
や go build
、go test
などによって生成されたバイナリファイル、オブジェクトファイル、キャッシュなどを削除し、ソースツリーを初期状態に近い形に戻します。これは、新しいビルドを開始する前や、開発環境をリフレッシュする際によく使用されます。
go tool dist
go tool dist
は、Goのビルドシステムの一部である内部ツールです。このツールは、Goのソースツリーのビルドプロセスを管理するために使用されます。
特に重要なのが go tool dist env
サブコマンドです。これは、Goのビルドに必要な環境変数(例: GOROOT
, GOBIN
, GOTOOLDIR
など)をシェルスクリプトが eval
できる形式で出力します。これにより、スクリプトはGoのビルド環境を正確に設定できます。
GOBIN
と GOTOOLDIR
GOBIN
: Goのコマンド(go
コマンド自体やgofmt
など)がインストールされるディレクトリを指します。GOTOOLDIR
: Goの内部ツール(dist
、link
、compile
など)が配置されるディレクトリを指します。これらのツールは通常、直接ユーザーが実行するものではなく、go
コマンドによって内部的に呼び出されます。
eval $(command)
シェルスクリプトにおける eval $(command)
は、command
の実行結果を現在のシェルのコマンドとして評価・実行する構文です。
このコミットの文脈では、eval $(go tool dist env)
は go tool dist env
が出力する環境変数の設定コマンド(例: export GOROOT=/path/to/go; export GOBIN=/path/to/go/bin; ...
)を現在のシェルで実行し、それらの環境変数をスクリプト内で利用可能にする役割を果たします。
技術的詳細
このコミットの技術的な変更点は、clean.bash
スクリプトがGoのビルドツールへのパスを特定する方法を改善したことに集約されます。
変更前
変更前のスクリプトでは、dist
ツールへのパスを ../bin/tool/dist
という相対パスで直接指定していました。
-if [ ! -x ../bin/tool/dist ]; then
- echo 'cannot find ../bin/tool/dist; nothing to clean' >&2
- exit 1
-fi
...
-eval $(../bin/tool/dist env)
...
-../bin/tool/dist clean
このアプローチにはいくつかの問題がありました。
- パスの堅牢性:
../bin/tool/dist
という相対パスは、clean.bash
が実行されるカレントディレクトリに依存します。もしスクリプトがGoのソースツリーの異なる場所から実行された場合、このパスは無効になる可能性があります。 - 環境変数との不整合: Goのビルドシステムは、
go tool dist env
を通じてGOTOOLDIR
のような環境変数を設定し、ツールの場所を抽象化します。相対パスの直接指定は、この抽象化の恩恵を受けられず、将来的なパス変更に対して脆弱でした。
変更後
変更後のスクリプトでは、go tool dist env
コマンドを利用して、Goのビルド環境変数をスクリプトにロードするように変更されました。
+eval $(go tool dist env)
+
+if [ ! -x $GOTOOLDIR/dist ]; then
+ echo 'cannot find $GOTOOLDIR/dist; nothing to clean' >&2
+ exit 1
+fi
...
"$GOBIN/go" clean -i std
+$GOTOOLDIR/dist clean
具体的な変更点は以下の通りです。
eval $(go tool dist env)
の追加: スクリプトの冒頭でeval $(go tool dist env)
が実行されるようになりました。これにより、go tool dist env
が出力するGOTOOLDIR
やGOBIN
などの環境変数が現在のシェルセッションに設定されます。$GOTOOLDIR
の利用:dist
ツールへの参照が、ハードコードされた相対パス../bin/tool/dist
から、環境変数$GOTOOLDIR
を利用した$GOTOOLDIR/dist
に変更されました。これにより、dist
ツールの実際のパスがどこにあっても、go tool dist env
が提供する正しいパスが使用されるようになります。GOBIN
の利用:"$GOBIN/go" clean -i std
の行は変更されていませんが、eval $(go tool dist env)
によってGOBIN
が確実に設定されるため、go
コマンドの呼び出しもより堅牢になります。
この変更により、clean.bash
はGoのビルドシステムが提供する標準的な方法でツールのパスを解決するようになり、スクリプトの堅牢性と移植性が大幅に向上しました。
コアとなるコードの変更箇所
--- a/src/clean.bash
+++ b/src/clean.bash
@@ -5,11 +5,12 @@
set -e
-if [ ! -x ../bin/tool/dist ]; then
- echo 'cannot find ../bin/tool/dist; nothing to clean' >&2
+eval $(go tool dist env)
+
+if [ ! -x $GOTOOLDIR/dist ]; then
+ echo 'cannot find $GOTOOLDIR/dist; nothing to clean' >&2
exit 1
fi
-"$GOBIN/go" clean -i std
-../bin/tool/dist clean
+$GOTOOLDIR/dist clean
コアとなるコードの解説
-if [ ! -x ../bin/tool/dist ]; then
- 変更前のコードで、
../bin/tool/dist
という相対パスでdist
ツールが存在し、実行可能であるかを確認していました。この相対パスは、clean.bash
が実行されるカレントディレクトリに依存するため、問題がありました。
- 変更前のコードで、
+eval $(go tool dist env)
- この行が新しく追加されました。
go tool dist env
コマンドを実行し、その出力(Goのビルドに必要な環境変数の設定コマンド群)をeval
コマンドによって現在のシェルで評価・実行します。これにより、GOTOOLDIR
やGOBIN
などの環境変数がスクリプト内で利用可能になります。
- この行が新しく追加されました。
+if [ ! -x $GOTOOLDIR/dist ]; then
eval $(go tool dist env)
によって設定された$GOTOOLDIR
環境変数を使用して、dist
ツールの存在と実行可能性をチェックするように変更されました。これにより、dist
ツールの実際のパスがどこにあっても、Goのビルドシステムが提供する正しいパスが使用されるようになります。
-../bin/tool/dist clean
- 変更前のコードで、相対パス
../bin/tool/dist
を使ってdist clean
コマンドを実行していました。
- 変更前のコードで、相対パス
+$GOTOOLDIR/dist clean
eval $(go tool dist env)
によって設定された$GOTOOLDIR
環境変数を使用して、dist clean
コマンドを実行するように変更されました。これにより、clean.bash
がより堅牢になり、Goのビルドシステムが管理するツールのパス変更にも対応できるようになりました。
この変更は、Goのビルドスクリプトが、ハードコードされた相対パスではなく、Goのツールチェーンが提供する標準的な環境変数を利用して、ツールの場所を動的に解決するようになったことを示しています。これは、ビルドシステムの保守性と移植性を向上させる上で重要な改善です。
関連リンク
- Go Change-Id:
I2222222222222222222222222222222222222222
(これはコミットメッセージに記載されているhttps://golang.org/cl/5672052
のChange-Idに対応するものです。GoのコードレビューシステムGerritのリンクです。)
参考にした情報源リンク
- Go言語の公式ドキュメント (Goのビルドシステムやツールの詳細について)
- シェルスクリプトの
eval
コマンドに関する一般的な情報 - Goのソースコードリポジトリ (特に
src/clean.bash
の履歴) - GoのGerritコードレビューシステム (コミットメッセージに記載されているCLリンク)
- https://golang.org/cl/5672052 (このコミットのGerritレビューページ)
- (注: 2012年の古いCLのため、現在のGerritシステムでは直接アクセスできない可能性がありますが、当時のレビュープロセスを示すものです。)