[インデックス 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 ]; theneval $(go tool dist env)によって設定された$GOTOOLDIR環境変数を使用して、distツールの存在と実行可能性をチェックするように変更されました。これにより、distツールの実際のパスがどこにあっても、Goのビルドシステムが提供する正しいパスが使用されるようになります。
-../bin/tool/dist clean- 変更前のコードで、相対パス
../bin/tool/distを使ってdist cleanコマンドを実行していました。
- 変更前のコードで、相対パス
+$GOTOOLDIR/dist cleaneval $(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システムでは直接アクセスできない可能性がありますが、当時のレビュープロセスを示すものです。)