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

[インデックス 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 -racego test -race のように、ビルドコマンドに -race フラグを付与することで有効になります。競合検出器を有効にしてビルドされたバイナリは、実行時にデータ競合の可能性を監視し、問題があれば報告します。

しかし、競合検出器を有効にすると、実行時のパフォーマンスが低下するというトレードオフがあります。これは、競合検出のための追加のインストゥルメンテーション(計測コードの挿入)やランタイムチェックが行われるためです。

このコミットが行われた背景には、Goの公式ディストリビューション(バイナリ配布)において、開発者が誤って、あるいは意図せず -race フラグが有効な状態でビルドされたGoツール(cmd/gocmd/godocなど)を配布してしまう可能性があったことが挙げられます。もし、これらのツールが競合検出器有効な状態で配布されてしまうと、ユーザーは不必要に低速なGoツールを使用することになり、開発体験が損なわれることになります。

このコミットは、Goのディストリビューションプロセスの一部である misc/dist パッケージが、最終的なバイナリ配布物を作成する際に、Goツール自体が競合検出器なしでビルドされることを保証するためのものです。これにより、配布されるGoツールは常に最適なパフォーマンスで動作するようになります。

前提知識の解説

  1. Go言語のビルドシステム: Go言語は、go build コマンドを使用してソースコードをコンパイルし、実行可能なバイナリを生成します。go install コマンドは、パッケージをコンパイルしてインストールディレクトリ(通常は $GOPATH/bin または $GOBIN)に配置します。
  2. go install std: std はGoの標準ライブラリ全体を指します。go install std は、標準ライブラリに含まれるすべてのパッケージと、それらに関連するコマンド(例: cmd/gocmd/godoc など)をビルドしてインストールします。
  3. -race フラグ: go buildgo test などのコマンドに -race フラグを付与すると、Goの競合検出器が有効になります。これにより、ビルドされるバイナリにデータ競合を検出するための追加のコードが組み込まれます。これはデバッグやテストには非常に有用ですが、本番環境での使用やパフォーマンスが重要な場合には通常は使用されません。
  4. misc/dist パッケージ: Goのソースツリー内の misc/dist ディレクトリには、Goの公式バイナリディストリビューションを作成するためのツールが含まれています。これは、Goのリリースプロセスにおいて、様々なプラットフォーム向けのGoバイナリパッケージを生成するために使用されます。
  5. goCmd: Goのビルドスクリプト内で、Goコマンド自体を実行するための変数または関数を指します。
  6. 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
		}

このコードブロックは、以下のことを行います。

  1. コメント: 「// Re-install std without -race, so that we're not left with // a slower, race-enabled cmd/go, cmd/godoc, etc.」というコメントが追加されており、この変更の目的が明確に説明されています。つまり、-race フラグなしで std を再インストールすることで、低速な競合検出器有効な cmd/gocmd/godoc などが残らないようにする、という意図です。
  2. 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/gocmd/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ツール自体が競合検出器なしでビルドされることを保証するためのものです。

  1. // Re-install std without -race, so that we're not left with

  2. // a slower, race-enabled cmd/go, cmd/godoc, etc.

    • これらの行はコメントであり、このコードブロックの目的を説明しています。Goツール(cmd/go, cmd/godocなど)が、競合検出器が有効な状態(-raceフラグ付き)でビルドされるとパフォーマンスが低下するため、それを避けるために標準ライブラリ(std)を-raceなしで再インストールするという意図が示されています。
  3. _, 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/gocmd/godoc といったGoツール自体も含まれます。このステップにより、これらのツールが競合検出器なしの状態で再ビルドされ、インストールされます。
    • _ は、コマンドの標準出力(stdout)を破棄することを示します。
    • err は、コマンド実行中に発生したエラーを捕捉します。
  4. if err != nil {

  5. return err

  6. }

    • これらの行は標準的なエラーハンドリングです。もし go install コマンドの実行中にエラーが発生した場合、そのエラーを呼び出し元に返して処理を中断します。

この変更により、Goの公式バイナリディストリビューションに含まれるGoツールは、常に最適なパフォーマンスで動作することが保証され、ユーザーが意図せず低速なツールを使用する状況が回避されます。

関連リンク

参考にした情報源リンク