[インデックス 16090] ファイルの概要
このコミットは、Go言語のディストリビューションツール(misc/dist)において、go installコマンドでビルドされる標準ライブラリ(std)および関連ツール(cmd/go, cmd/godocなど)が、raceフラグ(競合検出機能)が有効な状態で配布されないようにするための変更です。これにより、配布されるGoツールが不必要に低速になることを防ぎます。
コミット
- Author: Andrew Gerrand adg@golang.org
- Date: Thu Apr 4 12:07:53 2013 +1100
- Commit Message:
misc/dist: don't ship race-enabled commands R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/8350044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/1b9e36356be410adf3b0b80e99996f8f3476d8cf
元コミット内容
commit 1b9e36356be410adf3b0b80e99996f8f3476d8cf
Author: Andrew Gerrand <adg@golang.org>
Date: Thu Apr 4 12:07:53 2013 +1100
misc/dist: don't ship race-enabled commands
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/8350044
---
misc/dist/bindist.go | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/misc/dist/bindist.go b/misc/dist/bindist.go
index 1f5cfc817e..d06a4f6e28 100644
--- a/misc/dist/bindist.go
+++ b/misc/dist/bindist.go
@@ -197,6 +197,12 @@ func (b *Build) Do() error {
if err != nil {
return err
}
+ // Re-install std without -race, so that we're not left with
+ // a slower, race-enabled cmd/go, cmd/godoc, etc.
+ _, err = b.run(src, goCmd, "install", "-a", "std")
+ if err != nil {
+ return err
+ }
}
if err := b.tour(); err != nil {
変更の背景
Go言語には、データ競合(data race)を検出するための「競合検出器(Race Detector)」という強力なツールが組み込まれています。これは、go build -race や go test -race のように、ビルドコマンドに -race フラグを付与することで有効になります。競合検出器を有効にしてビルドされたバイナリは、実行時にデータ競合の可能性を監視し、問題があれば報告します。
しかし、競合検出器を有効にすると、実行時のパフォーマンスが低下するというトレードオフがあります。これは、競合検出のための追加のインストゥルメンテーション(計測コードの挿入)やランタイムチェックが行われるためです。
このコミットが行われた背景には、Goの公式ディストリビューション(バイナリ配布)において、開発者が誤って、あるいは意図せず -race フラグが有効な状態でビルドされたGoツール(cmd/go、cmd/godocなど)を配布してしまう可能性があったことが挙げられます。もし、これらのツールが競合検出器有効な状態で配布されてしまうと、ユーザーは不必要に低速なGoツールを使用することになり、開発体験が損なわれることになります。
このコミットは、Goのディストリビューションプロセスの一部である misc/dist パッケージが、最終的なバイナリ配布物を作成する際に、Goツール自体が競合検出器なしでビルドされることを保証するためのものです。これにより、配布されるGoツールは常に最適なパフォーマンスで動作するようになります。
前提知識の解説
- Go言語のビルドシステム: Go言語は、
go buildコマンドを使用してソースコードをコンパイルし、実行可能なバイナリを生成します。go installコマンドは、パッケージをコンパイルしてインストールディレクトリ(通常は$GOPATH/binまたは$GOBIN)に配置します。 go install std:stdはGoの標準ライブラリ全体を指します。go install stdは、標準ライブラリに含まれるすべてのパッケージと、それらに関連するコマンド(例:cmd/go、cmd/godocなど)をビルドしてインストールします。-raceフラグ:go buildやgo testなどのコマンドに-raceフラグを付与すると、Goの競合検出器が有効になります。これにより、ビルドされるバイナリにデータ競合を検出するための追加のコードが組み込まれます。これはデバッグやテストには非常に有用ですが、本番環境での使用やパフォーマンスが重要な場合には通常は使用されません。misc/distパッケージ: Goのソースツリー内のmisc/distディレクトリには、Goの公式バイナリディストリビューションを作成するためのツールが含まれています。これは、Goのリリースプロセスにおいて、様々なプラットフォーム向けのGoバイナリパッケージを生成するために使用されます。goCmd: Goのビルドスクリプト内で、Goコマンド自体を実行するための変数または関数を指します。install -a:go install -aは、すべての依存関係を強制的に再ビルドするオプションです。これは、クリーンな状態からビルドをやり直す際に役立ちます。
技術的詳細
このコミットの技術的な核心は、Goのディストリビューションビルドプロセスにおいて、標準ライブラリ(std)が競合検出器なしで再インストールされることを保証する点にあります。
misc/dist/bindist.go ファイルは、Goのバイナリディストリビューションを作成する際の主要なロジックを含んでいます。このファイル内の Build 構造体の Do() メソッドは、ビルドプロセス全体をオーケストレーションします。
変更が加えられた箇所は、既存のビルドステップの直後に追加されています。元のコードでは、Goツール自体がビルドされる際に、もし以前のビルドで -race フラグが有効になっていた場合、その設定が引き継がれてしまう可能性がありました。
新しいコードでは、以下の行が追加されています。
// Re-install std without -race, so that we're not left with
// a slower, race-enabled cmd/go, cmd/godoc, etc.
_, err = b.run(src, goCmd, "install", "-a", "std")
if err != nil {
return err
}
このコードブロックは、以下のことを行います。
- コメント: 「
// Re-install std without -race, so that we're not left with // a slower, race-enabled cmd/go, cmd/godoc, etc.」というコメントが追加されており、この変更の目的が明確に説明されています。つまり、-raceフラグなしでstdを再インストールすることで、低速な競合検出器有効なcmd/goやcmd/godocなどが残らないようにする、という意図です。 b.run(src, goCmd, "install", "-a", "std"):b.runは、misc/distツールがシェルコマンドを実行するためのヘルパー関数です。srcは、Goのソースディレクトリへのパスを指します。goCmdは、Goコマンドの実行パスです。"install", "-a", "std"は、実行されるGoコマンドの引数です。これはgo install -a stdに相当します。install: 指定されたパッケージをビルドしてインストールします。-a: すべての依存関係を強制的に再ビルドします。これにより、以前のビルド設定(例えば-raceフラグ)がキャッシュに残っていても、確実にクリーンな状態でビルドがやり直されます。std: Goの標準ライブラリ全体を対象とします。これにより、cmd/goやcmd/godocといったGoツール自体も再ビルドされ、インストールされます。
このステップを明示的に追加することで、Goのディストリビューションビルドの最終段階で、Goツールが競合検出器なしの状態で確実にビルドされ、配布されるバイナリに含まれることが保証されます。これにより、ユーザーは常に最適化されたパフォーマンスのGoツールを利用できるようになります。
コアとなるコードの変更箇所
--- a/misc/dist/bindist.go
+++ b/misc/dist/bindist.go
@@ -197,6 +197,12 @@ func (b *Build) Do() error {
if err != nil {
return err
}
+ // Re-install std without -race, so that we're not left with
+ // a slower, race-enabled cmd/go, cmd/godoc, etc.
+ _, err = b.run(src, goCmd, "install", "-a", "std")
+ if err != nil {
+ return err
+ }
}
if err := b.tour(); err != nil {
コアとなるコードの解説
追加された6行のコードは、Goのディストリビューションビルドプロセスにおいて、Goツール自体が競合検出器なしでビルドされることを保証するためのものです。
-
// Re-install std without -race, so that we're not left with -
// a slower, race-enabled cmd/go, cmd/godoc, etc.- これらの行はコメントであり、このコードブロックの目的を説明しています。Goツール(
cmd/go,cmd/godocなど)が、競合検出器が有効な状態(-raceフラグ付き)でビルドされるとパフォーマンスが低下するため、それを避けるために標準ライブラリ(std)を-raceなしで再インストールするという意図が示されています。
- これらの行はコメントであり、このコードブロックの目的を説明しています。Goツール(
-
_, err = b.run(src, goCmd, "install", "-a", "std")- この行が実際の処理を実行します。
b.runは、misc/distパッケージ内で外部コマンドを実行するためのヘルパー関数です。srcはGoのソースディレクトリのパスです。goCmdはGoコマンドの実行パスです。"install", "-a", "std"は、goCmdに渡される引数です。これは実質的にgo install -a stdコマンドを実行することを意味します。install: Goのパッケージをビルドしてインストールします。-a: すべての依存関係を強制的に再ビルドします。これにより、以前のビルドキャッシュがクリアされ、確実にクリーンな状態でビルドが行われます。これは、以前のビルドで-raceフラグが使われていたとしても、その影響を排除するために重要です。std: Goの標準ライブラリ全体を対象とします。これには、cmd/goやcmd/godocといったGoツール自体も含まれます。このステップにより、これらのツールが競合検出器なしの状態で再ビルドされ、インストールされます。
_は、コマンドの標準出力(stdout)を破棄することを示します。errは、コマンド実行中に発生したエラーを捕捉します。
-
if err != nil { -
return err -
}- これらの行は標準的なエラーハンドリングです。もし
go installコマンドの実行中にエラーが発生した場合、そのエラーを呼び出し元に返して処理を中断します。
- これらの行は標準的なエラーハンドリングです。もし
この変更により、Goの公式バイナリディストリビューションに含まれるGoツールは、常に最適なパフォーマンスで動作することが保証され、ユーザーが意図せず低速なツールを使用する状況が回避されます。
関連リンク
- Go CL 8350044: https://golang.org/cl/8350044
参考にした情報源リンク
- Go言語の公式ドキュメント (Go Race Detector): https://go.dev/doc/articles/race_detector
- Goコマンドのドキュメント: https://go.dev/cmd/go/
- Goソースコード (misc/dist): https://github.com/golang/go/tree/master/misc/dist