[インデックス 10931] ファイルの概要
このコミットは、Go言語のビルドスクリプト src/run.bash
において、time
コマンドの使用方法を bash
の組み込みコマンド time
を利用するように変更したものです。これにより、特に windows/amd64
環境でのビルドの安定性向上を目指しています。
コミット
commit efa2246e423a2fdbd833e0103def8c6a4cbd5042
Author: Russ Cox <rsc@golang.org>
Date: Wed Dec 21 01:24:57 2011 -0500
build: rewrite to use bash time builtin
Should help windows/amd64
R=adg
CC=golang-dev
https://golang.org/cl/5500058
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/efa2246e423a2fdbd833e0103def8c6a4cbd5042
元コミット内容
build: rewrite to use bash time builtin
Should help windows/amd64
変更の背景
このコミットの主な背景は、Go言語のビルドシステムが特定の環境、特に windows/amd64
(64ビット版Windows) において、time
コマンドの挙動に起因する問題に直面していたことです。
従来のスクリプトでは、time
コマンドが GOPATH=""
の前に置かれていました。これは、シェルによっては外部コマンドとしての time
(/usr/bin/time
など) を呼び出す可能性があり、その外部コマンドが GOPATH
環境変数の設定に影響を与えたり、Windows環境ではそもそも利用できなかったり、あるいは異なる挙動を示すことが考えられます。
windows/amd64
環境でのビルドの信頼性と互換性を向上させるため、time
コマンドを bash
シェルの組み込み機能として確実に利用するように変更する必要がありました。組み込みコマンドは、外部プログラムのパスに依存せず、シェル自体が提供するため、より移植性が高く、予測可能な挙動をします。
前提知識の解説
time
コマンド (シェル組み込み vs. 外部コマンド)
time
コマンドは、指定されたコマンドの実行にかかった時間(実時間、ユーザーCPU時間、システムCPU時間)を測定するために使用されます。
- シェル組み込み (
bash time builtin
):bash
などのシェルには、time
という名前の組み込みコマンドが用意されています。これはシェルの一部として機能し、外部プログラムを呼び出す必要がありません。通常、より高速で、環境変数の継承などに関してシェル自身のルールに従います。 - 外部コマンド (
/usr/bin/time
など): 一方で、time
という名前の実行ファイルがシステムパス (/usr/bin/time
など) に存在することもあります。これは独立したプログラムであり、シェル組み込みのtime
とは異なる機能やオプションを持つことがあります。環境変数の扱いもシェル組み込みとは異なる場合があります。
このコミットでは、bash
の組み込み time
を確実に使用することで、クロスプラットフォーム、特にWindows環境での互換性と安定性を確保しようとしています。
GOPATH
環境変数
GOPATH
はGo言語のワークスペースのルートディレクトリを指定する環境変数です。Goのソースコード、コンパイルされたパッケージ、実行可能ファイルがこのワークスペース内に配置されます。GOPATH=""
と設定することは、一時的に GOPATH
を空にし、Goツールがデフォルトの場所(Goモジュールが導入される前のGoのバージョンでは、通常は $HOME/go
など)を使用するように指示するか、あるいは特定のビルドやテストの際に GOPATH
の影響を受けないようにするために行われます。
go install
コマンド
go install
はGoのパッケージをコンパイルし、その結果生成される実行可能ファイルやパッケージアーカイブを GOPATH
(またはGoモジュールモードでのキャッシュディレクトリ) の bin
または pkg
ディレクトリにインストールするコマンドです。
go test
コマンド
go test
はGoのパッケージのテストを実行するコマンドです。-short
オプションは、テストの実行時間を短縮するために、時間のかかるテストをスキップするように指示します。
windows/amd64
これは、Go言語のビルドターゲットを示すプラットフォームとアーキテクチャの組み合わせです。windows
はオペレーティングシステムがMicrosoft Windowsであることを示し、amd64
はCPUアーキテクチャが64ビットのAMD64 (Intel 64を含む) であることを示します。Goはクロスコンパイルをサポートしており、異なるOSやアーキテクチャ向けのバイナリを生成できます。
技術的詳細
このコミットの技術的な核心は、time
コマンドの実行順序と、それがシェル組み込みコマンドと外部コマンドのどちらとして解釈されるかにあります。
従来のコード:
GOPATH="" time go install -a all
この記述では、GOPATH=""
という環境変数の設定が time
コマンドの前に来ています。シェルによっては、この time
を外部コマンドとして解釈し、その外部コマンドが GOPATH
の設定を正しく継承しない、あるいは time
コマンド自体がWindows環境に存在しない、といった問題が発生する可能性がありました。
新しいコード:
time GOPATH="" go install -a all
この変更では、time
コマンドが GOPATH=""
の前に移動しています。bash
シェルにおいて、time
がコマンドラインの先頭に置かれると、シェルはまず自身の組み込み time
コマンドとして解釈しようとします。これにより、外部の time
コマンドの有無や挙動に依存することなく、bash
組み込みの time
が確実に使用されるようになります。
bash
組み込みの time
は、その後に続くコマンド全体(この場合は GOPATH="" go install -a all
)の実行時間を測定します。GOPATH=""
の設定は、time
コマンドによって測定される対象のコマンド (go install
や go test
) に対して正しく適用されます。
この変更により、特にWindows環境で time
コマンドのパス解決や互換性の問題に悩まされることなく、ビルドスクリプトが安定して動作するようになります。これは、Goのビルドシステムが様々なプラットフォームで堅牢に機能するための重要な改善です。
コアとなるコードの変更箇所
--- a/src/run.bash
+++ b/src/run.bash
@@ -34,7 +34,7 @@ if $rebuild; then
if $USE_GO_TOOL; then
echo
echo '# Package builds'
- GOPATH="" time go install -a all
+ time GOPATH="" go install -a all
else
(xcd pkg
gomake clean
@@ -46,7 +46,7 @@ fi
if $USE_GO_TOOL; then
echo
echo '# Package tests'
- GOPATH="" time go test all -short
+ time GOPATH="" go test all -short
else
(xcd pkg
gomake testshort
コアとなるコードの解説
変更は src/run.bash
ファイルの2箇所にあります。
-
パッケージビルド部分 (
go install
): 変更前:GOPATH="" time go install -a all
変更後:time GOPATH="" go install -a all
-
パッケージテスト部分 (
go test
): 変更前:GOPATH="" time go test all -short
変更後:time GOPATH="" go test all -short
この変更の核心は、time
コマンドの位置を GOPATH=""
の前に移動させたことです。
- 変更前:
GOPATH=""
が先に評価され、その後にtime
コマンドが実行されます。この場合、シェルはtime
を外部コマンドとして解釈しようとする可能性があり、その外部コマンドがGOPATH
の設定を正しく継承しない、あるいはWindows環境では利用できないといった問題が生じることがありました。 - 変更後:
time
がコマンドラインの先頭に置かれることで、bash
シェルはこれを自身の組み込みコマンドとして解釈します。組み込みtime
は、その後に続くGOPATH="" go install -a all
(またはgo test all -short
) というコマンド全体を測定対象とします。これにより、GOPATH=""
の設定はgo install
やgo test
コマンドに確実に適用され、かつtime
コマンドの実行が外部プログラムの有無や挙動に依存しなくなるため、特にWindows環境での互換性と安定性が向上します。
この修正は、シェルスクリプトにおけるコマンドの評価順序と、組み込みコマンドの優先順位を考慮した、堅牢なクロスプラットフォーム対応のための典型的な例と言えます。
関連リンク
- Go CL (Code Review) 5500058: https://golang.org/cl/5500058
参考にした情報源リンク
- (特になし。コミット内容と一般的なシェルスクリプトの知識に基づいています。)