[インデックス 18013] ファイルの概要
このコミットは、Go言語のソースツリーに含まれるrace.bat
スクリプトにおける環境設定の問題を修正するものです。race.bat
は、Goのデータ競合検出器(Race Detector)を有効にした状態でGoの標準ライブラリをビルドし、テストを実行するためのWindowsバッチスクリプトです。このコミットの主な目的は、GOROOT
環境変数の設定が不適切であったために発生していたビルドエラーを解消することにあります。
コミット
このコミットは、Windows環境でGoのデータ競合検出器を使用する際に発生していたGOROOT
環境変数の設定に関する問題を解決します。具体的には、race.bat
スクリプト内でGOROOT
が正しく設定されていなかったために、go tool dist
コマンドが失敗するというエラーを修正します。修正は、race.bat
スクリプトの冒頭でGOROOT
を現在のディレクトリの親ディレクトリに明示的に設定することで行われます。
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/830f9ac030a99265379fcbff8f40d66f4fa3e669
元コミット内容
race.bat: fix env setup
Currently it fails as:
go tool dist: $GOROOT is not set correctly or not exported
GOROOT=c:\go
c:\go\include\u.h does not exist
Fail.
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/42550044
変更の背景
この変更は、Goのデータ競合検出器を有効にしてビルドおよびテストを行うためのrace.bat
スクリプトが、Windows環境で正しく動作しないという問題に対応するために行われました。元のコミットメッセージに記載されているエラーメッセージ「go tool dist: $GOROOT is not set correctly or not exported
」が示すように、go tool dist
コマンドがGOROOT
環境変数を正しく認識できないことが根本原因でした。
race.bat
スクリプトは、Goのソースツリーのsrc
ディレクトリ内で実行されることを想定しています。この場合、GOROOT
はGoのインストールルートディレクトリ(src
の親ディレクトリ)を指す必要があります。しかし、スクリプト内でGOROOT
が明示的に設定されていなかったため、システム環境変数やコマンドプロンプトの起動方法によっては、go tool dist
が期待するGOROOT
のパスを見つけられず、ビルドに必要なファイル(例: c:\go\include\u.h
)を見つけられないという問題が発生していました。
この問題は、特にGoの開発者がWindows環境でデータ競合検出器を利用してコードのテストやデバッグを行う際に、ビルドプロセスの妨げとなっていました。そのため、race.bat
スクリプトが自己完結的にGOROOT
を正しく設定できるように修正する必要がありました。
前提知識の解説
このコミットを理解するためには、以下のGo言語に関する前提知識が必要です。
-
GOROOT:
GOROOT
は、Go言語のインストールディレクトリのルートパスを示す環境変数です。Goのコンパイラ、標準ライブラリ、ツールなどがこのディレクトリに格納されています。Goのツールチェーンが正しく機能するためには、GOROOT
が適切に設定されている必要があります。例えば、Windows環境でGoをC:\go
にインストールした場合、GOROOT
はC:\go
に設定されます。 -
Go Race Detector (データ競合検出器): Goには、並行処理におけるデータ競合(複数のgoroutineが同時に共有メモリにアクセスし、少なくとも1つが書き込み操作を行う場合に発生する競合状態)を検出するための組み込みツールであるRace Detectorがあります。これは、
go build -race
、go run -race
、go test -race
などのコマンドで有効にできます。Race Detectorは、実行時にメモリアクセスを監視し、データ競合の可能性を報告することで、並行プログラムのデバッグを支援します。 -
go tool dist
:go tool dist
は、Goのビルドシステムの一部であり、Goのツールチェーン自体をビルドしたり、Goの環境に関する情報を取得したりするために使用される内部ツールです。GoのソースコードからGoのバイナリをビルドする際に、このツールが利用されます。go tool dist
は、GOROOT
環境変数に依存して、Goのソースツリーやビルドに必要なファイルを見つけます。 -
Windowsバッチスクリプト (
.bat
): Windowsのコマンドプロンプトで実行されるスクリプトファイルです。set
コマンドを使用して環境変数を設定したり、call
コマンドで他のバッチファイルを実行したり、%CD%
のような特殊変数で現在のディレクトリパスを取得したりできます。 -
make.bat
: Goのソースツリーのルートにあるビルドスクリプトで、Goのツールチェーンや標準ライブラリをビルドするために使用されます。race.bat
はこのmake.bat
を呼び出して、Race Detectorを有効にしたビルドを行います。
技術的詳細
このコミットの技術的な核心は、WindowsバッチスクリプトにおけるGOROOT
環境変数の動的な設定と、go tool dist
コマンドのGOROOT
への依存関係にあります。
元のrace.bat
スクリプトでは、GOROOT
が明示的に設定されていませんでした。Windows環境では、コマンドプロンプトの起動方法や、Goがシステム全体にインストールされているか、あるいはポータブルな形式で利用されているかによって、GOROOT
の値が異なる場合があります。race.bat
はGoのソースツリーのsrc
ディレクトリに存在するため、このスクリプトが実行される際には、GOROOT
はsrc
ディレクトリの親ディレクトリ(Goのルートディレクトリ)を指している必要があります。
エラーメッセージ「go tool dist: $GOROOT is not set correctly or not exported
」は、go tool dist
が期待するGOROOT
の値を見つけられなかったか、あるいはその値が指すパスにGoのビルドに必要なファイル(例: include/u.h
)が存在しなかったことを示しています。これは、go tool dist
がGOROOT
を基点としてGoのソースツリー内のファイルを探索するためです。
このコミットでは、race.bat
スクリプトの冒頭に以下の行を追加することでこの問題を解決しています。
set GOROOT=%CD%\..
%CD%
: これはWindowsバッチスクリプトの特殊変数で、現在のディレクトリのパスを表します。race.bat
がgo/src
ディレクトリで実行される場合、%CD%
はgo\src
となります。\..
: これは親ディレクトリを意味します。したがって、%CD%\..
はgo\src\..
となり、結果としてgo
ディレクトリ(Goのルートディレクトリ)のパスを生成します。
この変更により、race.bat
が実行されるたびに、スクリプト自身の位置に基づいてGOROOT
が動的に、かつ正確に設定されるようになります。これにより、go tool dist
コマンドが常に正しいGOROOT
パスを認識し、Goのビルドに必要なファイルを適切に見つけられるようになり、エラーが解消されます。
また、もう一つの変更点として、echo # go test -race -short -std
がecho # go test -race -short std
に変更されています。これは、echo
コマンドで表示されるメッセージの整形に関する微細な修正であり、機能的な変更ではありません。go test
コマンド自体はgo test -race -short std
のままであり、Race Detectorを有効にして標準ライブラリのテストを短時間で実行するという意図は変わりません。
コアとなるコードの変更箇所
変更はsrc/race.bat
ファイルに対して行われました。
--- a/src/race.bat
+++ b/src/race.bat
@@ -15,6 +15,7 @@ echo race.bat must be run from go\\src
goto end
:ok
+set GOROOT=%CD%\..
call make.bat --dist-tool >NUL
if errorlevel 1 goto fail
.\cmd\dist\dist env -wp >env.bat
@@ -35,7 +36,7 @@ go install -race cmd/cgo
echo # go install -race std
go install -race std
if errorlevel 1 goto fail
-echo # go test -race -short -std
+echo # go test -race -short std
go test -race -short std
if errorlevel 1 goto fail
echo # go test -race -run=nothingplease -bench=.* -benchtime=.1s -cpu=4 std
コアとなるコードの解説
このコミットのコアとなる変更は、src/race.bat
ファイルに以下の行が追加されたことです。
set GOROOT=%CD%\..
この行は、race.bat
スクリプトが実行される際に、GOROOT
環境変数を現在のディレクトリ(%CD%
)の親ディレクトリ(..
)に設定することを意味します。
なぜこの変更が必要だったのか?
race.bat
はGoのソースツリーのsrc
ディレクトリに配置されています。Goのビルドシステムやツール(特にgo tool dist
)は、GOROOT
環境変数にGoのインストールルートディレクトリのパスが設定されていることを期待します。src
ディレクトリの親ディレクトリこそが、Goのインストールルートディレクトリに相当します。
以前は、race.bat
スクリプト内でGOROOT
が明示的に設定されていなかったため、スクリプトが実行される環境によっては、GOROOT
が正しく設定されていなかったり、go tool dist
が期待するパスを見つけられなかったりする問題が発生していました。これにより、go tool dist
がGoのビルドに必要な内部ファイル(例: c:\go\include\u.h
)を見つけられず、ビルドプロセスが失敗していました。
この変更が問題をどのように解決したのか?
set GOROOT=%CD%\..
という行を追加することで、race.bat
が実行されるたびに、そのスクリプト自身の位置に基づいてGOROOT
が動的に、かつ正確に設定されるようになります。これにより、go tool dist
やその他のGoツールが常に正しいGOROOT
パスを認識し、Goのソースツリー内の必要なファイルを適切に見つけられるようになり、ビルドエラーが解消されます。
もう一つの変更点であるecho # go test -race -short -std
からecho # go test -race -short std
への変更は、echo
コマンドで出力される文字列から不要なハイフンを削除するもので、機能的な影響はありません。これは単に、ユーザーに表示されるメッセージの整形を改善するためのものです。実際のgo test
コマンドの動作には影響を与えません。
関連リンク
- Go Race Detector: https://go.dev/doc/articles/race_detector
- Go Command Documentation: https://go.dev/cmd/go/
- Go Change-Id (CL) 42550044: https://golang.org/cl/42550044
参考にした情報源リンク
- Go言語公式ドキュメント
- Goのソースコードリポジトリ (GitHub)
- Windowsバッチスクリプトに関する一般的な情報
- Stack Overflowなどの開発者コミュニティでの関連する議論 (具体的なURLは割愛)
- Goのビルドシステムに関する情報 (具体的なURLは割愛)