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

[インデックス 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種類あります。

  1. シェル組み込みコマンド: bashzshなどのシェルに内蔵されている機能です。これは、シェルが直接解釈・実行するため、外部の実行ファイルに依存しません。通常、real(実時間)、user(ユーザーCPU時間)、sys(システムCPU時間)の3つの時間を報告します。
  2. 外部コマンド: /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ランタイムの環境変数処理に焦点を当てています。

  1. 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をビルド・テストする際に重要です。
  2. GOMAXPROCSunset:

    • 変更前: 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の扱いを明確にすることで、ベンチマークの信頼性も向上しています。

関連リンク

参考にした情報源リンク