[インデックス 14411] ファイルの概要
このコミットは、Go言語プロジェクトのsrc/run.bash
ファイルに対する変更です。run.bash
は、Goのテストやベンチマークを実行するためのシェルスクリプトであり、Goプロジェクトのビルドおよびテストインフラストラクチャの重要な部分を担っています。
コミット
このコミットは、run.bash
スクリプトにおけるlinux/arm
ビルドの問題を修正することを目的としています。具体的には、一部のホスト環境で/usr/bin/time
コマンドが存在しない、または期待通りに動作しない場合にビルドが失敗する問題を解決するため、シェル組み込みのtime
コマンドを使用するように変更しています。また、GOMAXPROCS
環境変数を明示的にunset
する変更も含まれています。
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/fa21df31440d6fb64eebffdc9a1c5c958af8c118
元コミット内容
commit fa21df31440d6fb64eebffdc9a1c5c958af8c118
Author: Dave Cheney <dave@cheney.net>
Date: Thu Nov 15 13:59:46 2012 +1100
run.bash: fix linux/arm build
Revert to the shell builtin to avoid hosts that do not have /usr/bin/time.
R=golang-dev, iant
CC=golang-dev
https://golang.org/cl/6848054
変更の背景
この変更の背景には、特定の環境、特にlinux/arm
アーキテクチャでGoのビルドやテストを実行する際に発生する問題がありました。run.bash
スクリプト内で実行時間を計測するためにtime
コマンドが使用されていましたが、一部のシステムでは/usr/bin/time
という外部コマンドが存在しないか、パスが通っていないなどの理由で利用できない場合がありました。これにより、スクリプトの実行が中断され、ビルドプロセスが失敗していました。
この問題に対処するため、外部コマンドの/usr/bin/time
に依存するのではなく、より普遍的に利用可能なシェル組み込みのtime
コマンドを使用するように修正されました。これにより、さまざまなLinux環境、特にリソースが限られているか、標準的なツールセットが完全に揃っていないARMベースのシステムでの互換性が向上しました。
また、GOMAXPROCS
環境変数の扱いも変更されています。以前はGOMAXPROCS=
と設定されていましたが、これはGOMAXPROCS=1
と同じ意味を持つことがあり、Goランタイムが使用するCPUコア数を1に制限してしまう可能性がありました。このコミットでは、unset GOMAXPROCS
とすることで、Goランタイムがデフォルトの動作(通常は利用可能なCPUコア数に基づいて自動的に設定される)に従うように修正されています。これは、ベンチマークの正確性や、システムのリソースを最大限に活用するために重要です。
前提知識の解説
run.bash
スクリプト
run.bash
は、Go言語のソースコードリポジトリに含まれるシェルスクリプトで、主にGoのテストスイートやベンチマークを実行するために使用されます。Goプロジェクトの継続的インテグレーション(CI)システムや開発者のローカル環境で、Goの変更が既存の機能やパフォーマンスに影響を与えないことを確認するために利用されます。
time
コマンド(シェル組み込み vs. 外部コマンド)
Unix系システムには、プログラムの実行時間を計測するためのtime
コマンドが存在します。しかし、このtime
コマンドには2種類あります。
- シェル組み込みコマンド:
bash
やzsh
などのシェルに内蔵されている機能です。これは、シェルが直接解釈・実行するため、外部の実行ファイルに依存しません。通常、real
(実時間)、user
(ユーザーCPU時間)、sys
(システムCPU時間)の3つの時間を報告します。 - 外部コマンド:
/usr/bin/time
などのパスに存在する独立した実行ファイルです。これは、シェル組み込みのtime
よりも詳細な情報(メモリ使用量、I/O操作など)を提供できる場合があります。
このコミットの背景にある問題は、一部のシステムで/usr/bin/time
が存在しない、またはパスが通っていないために、スクリプトがこの外部コマンドを見つけられずエラーになることでした。シェル組み込みのtime
は、どのシェル環境でも利用できるため、より移植性が高い解決策となります。
GOMAXPROCS
環境変数
GOMAXPROCS
はGo言語のランタイムが使用する論理CPUの最大数を制御する環境変数です。
GOMAXPROCS
が設定されていない場合、Goランタイムはデフォルトで利用可能なCPUコア数(Go 1.5以降)または1(Go 1.4以前)を使用します。GOMAXPROCS=N
と設定すると、Goランタイムは最大N個の論理CPUを使用します。GOMAXPROCS=
(空文字列)と設定した場合、シェルによってはGOMAXPROCS=1
として解釈されることがあり、意図せず並列実行が制限される可能性がありました。
このコミットが行われた2012年時点では、GoのバージョンはGo 1.0〜1.1の範囲であり、GOMAXPROCS
のデフォルト値は1でした。そのため、明示的にunset
することで、Goランタイムがシステムデフォルトの動作(この場合は1)に従うようにしつつ、将来的なGoバージョンの変更(Go 1.5でデフォルトがCPUコア数になったことなど)にも対応しやすくなります。ベンチマークの実行においては、GOMAXPROCS
が意図しない値に設定されていると、正確なパフォーマンス測定ができないため、この変更は重要です。
linux/arm
ビルド
linux/arm
は、Linuxオペレーティングシステム上で動作するARMアーキテクチャ向けのGoのビルドターゲットを指します。ARMプロセッサは、スマートフォン、タブレット、組み込みシステム、シングルボードコンピュータ(Raspberry Piなど)など、多岐にわたるデバイスで広く使用されています。これらの環境は、デスクトップやサーバー環境と比較して、利用可能なツールやライブラリの構成が異なる場合があるため、特定の互換性問題が発生することがあります。
技術的詳細
このコミットの技術的詳細は、シェルスクリプトの実行環境におけるコマンドの解決順序と、Goランタイムの環境変数処理に焦点を当てています。
-
time
コマンドの解決:- 変更前:
GOMAXPROCS= time go run run.go
- この行では、
time
コマンドがgo run run.go
の実行時間を計測するために使用されています。 - シェルは通常、まず組み込みコマンドを検索し、次に
PATH
環境変数で指定されたディレクトリ内の実行ファイルを検索します。 - しかし、
GOMAXPROCS=
のように環境変数の設定が前置されている場合、シェルによってはtime
コマンドの解決方法に影響を与える可能性がありました。特に、/usr/bin/time
のような外部コマンドが優先的に呼び出されることを期待しているが、それが存在しない場合にエラーとなる問題がありました。
- この行では、
- 変更後:
unset GOMAXPROCS time go run run.go
unset GOMAXPROCS
を独立した行にすることで、time
コマンドの前に環境変数の設定が完了します。- これにより、
time
コマンドはシェル組み込みのtime
が確実に使用されるようになります。シェル組み込みのtime
は、外部コマンドの存在に依存しないため、/usr/bin/time
が存在しない環境でもスクリプトが正常に動作するようになります。これは、特にlinux/arm
のような、よりミニマルなシステム環境でGoをビルド・テストする際に重要です。
- 変更前:
-
GOMAXPROCS
のunset
:- 変更前:
GOMAXPROCS= time go run run.go
GOMAXPROCS=
という記述は、シェルによってはGOMAXPROCS
を空文字列に設定する、またはGOMAXPROCS=1
として解釈される可能性がありました。Go 1.4以前のバージョンでは、GOMAXPROCS
が設定されていない場合のデフォルト値は1でした。したがって、この記述は意図せずGoランタイムの並列性を1に制限してしまう可能性がありました。
- 変更後:
unset GOMAXPROCS
unset
コマンドは、指定された環境変数を完全に削除します。- これにより、Goランタイムは
GOMAXPROCS
が設定されていない状態となり、Goのバージョンに応じたデフォルトの動作(Go 1.5以降では利用可能なCPUコア数、それ以前では1)に従うようになります。ベンチマークの実行において、GOMAXPROCS
が意図しない値に設定されていると、正確なパフォーマンス測定ができないため、この変更はベンチマークの信頼性を向上させます。
- 変更前:
この変更は、Goのビルドおよびテストプロセスが、より多様なLinux環境、特にARMベースのシステムで堅牢に動作することを保証するための重要な改善です。
コアとなるコードの変更箇所
--- a/src/run.bash
+++ b/src/run.bash
@@ -115,7 +115,8 @@ echo '#' ../test/bench/go1
go test ../test/bench/go1
(xcd ../test
-GOMAXPROCS= time go run run.go
+unset GOMAXPROCS
+time go run run.go
) || exit $?
echo
コアとなるコードの解説
変更はsrc/run.bash
ファイルの116行目と117行目で行われています。
-
- GOMAXPROCS= time go run run.go
:- これは変更前の行です。
GOMAXPROCS=
という環境変数の設定がtime
コマンドの前に置かれています。 - 前述の通り、この形式は一部のシェルや環境で問題を引き起こす可能性がありました。特に、
time
コマンドが外部の/usr/bin/time
を指している場合、そのコマンドが見つからないとエラーになります。また、GOMAXPROCS=
がGOMAXPROCS=1
として解釈され、Goプログラムの並列実行が意図せず制限される可能性がありました。
- これは変更前の行です。
-
+ unset GOMAXPROCS
:- この行が新しく追加されました。
GOMAXPROCS
環境変数を明示的にunset
(未設定状態にする)しています。 - これにより、Goランタイムは
GOMAXPROCS
が設定されていない場合のデフォルトの動作に従います。これは、Go 1.5以降では利用可能なCPUコア数、それ以前のバージョンでは1となります。ベンチマークの実行において、環境変数が意図しない値に設定されることを防ぎ、より正確な結果を得るために重要です。
- この行が新しく追加されました。
-
+ time go run run.go
:- この行は、
time go run run.go
というコマンド自体は変更されていませんが、GOMAXPROCS=
の設定が分離されたことで、time
コマンドがシェル組み込みのtime
として確実に解釈されるようになります。 - これにより、
/usr/bin/time
のような外部コマンドの存在に依存することなく、スクリプトが安定して実行されるようになります。
- この行は、
これらの変更により、run.bash
スクリプトは、より多様なLinux環境、特に/usr/bin/time
が存在しないか、PATH
が適切に設定されていないlinux/arm
のような環境でも、Goのテストやベンチマークを堅牢に実行できるようになりました。また、GOMAXPROCS
の扱いを明確にすることで、ベンチマークの信頼性も向上しています。
関連リンク
- Go Change-Id:
6848054
(Gerrit Code Review): https://golang.org/cl/6848054
参考にした情報源リンク
time
コマンド (Unix): https://man7.org/linux/man-pages/man1/time.1.html- Bash組み込みコマンド
time
: https://www.gnu.org/software/bash/manual/bash.html#Job-Control-Builtins (Bashのマニュアル内でtime
コマンドのセクションを参照) - Go
GOMAXPROCS
環境変数: https://pkg.go.dev/runtime#GOMAXPROCS - Go 1.5
GOMAXPROCS
の変更に関するブログ記事 (Go 1.5リリースノート): https://go.dev/blog/go1.5-runtime (特に"Scheduler"セクション) - ARMアーキテクチャ (Wikipedia): https://ja.wikipedia.org/wiki/ARM%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3