[インデックス 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は割愛)