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

[インデックス 12565] ファイルの概要

このコミットは、Go言語のコマンドラインツール cmd/go におけるビルドスクリプトの出力から、環境変数 $GOROOT および $GOBIN の参照を削除する変更です。これにより、スクリプトの出力がよりクリーンになり、特定の環境変数に依存しない形になります。

コミット

commit 376fc748f6dfbe7ad12fc97d0bf8b2385c9314d7
Author: Russ Cox <rsc@golang.org>
Date:   Mon Mar 12 12:39:31 2012 -0400

    cmd/go: stop using $GOROOT and $GOBIN in script output
    
    They were necessary to produce a canonical script
    when we checked in build scripts, but now they're just
    getting in the way.
    
    Fixes #3279.
    
    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/5796068

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/376fc748f6dfbe7ad12fc97d0bf8b2385c9314d7

元コミット内容

    cmd/go: stop using $GOROOT and $GOBIN in script output
    
    They were necessary to produce a canonical script
    when we checked in build scripts, but now they're just
    getting in the way.
    
    Fixes #3279.

変更の背景

この変更の背景には、Go言語のビルドシステムにおける進化があります。かつて、Goのビルドスクリプトをバージョン管理システムにコミットする際、スクリプトの出力を「正規化された(canonical)」形式にするために、$GOROOT$GOBIN といった環境変数を明示的に出力に含める必要がありました。これは、異なる環境でビルドが行われた場合でも、スクリプトの出力が常に一貫した形式を保つようにするためと考えられます。

しかし、コミットメッセージにあるように、この必要性は時間とともに薄れました。Goのツールチェインやビルドプロセスの改善により、これらの環境変数をスクリプト出力に含めることが、むしろ「邪魔になっている(getting in the way)」状況になったと推測されます。具体的には、これらの変数が含まれることで、スクリプトの可読性が低下したり、特定の環境に依存するような印象を与えたり、あるいは単に冗長になったりする問題が生じていた可能性があります。

この変更は、Goのビルドシステムが成熟し、より柔軟で環境に依存しない設計へと移行していることを示唆しています。#3279 というIssue番号が関連付けられていますが、これはGoプロジェクト内部のトラッキングシステムにおける課題番号である可能性が高く、この変更が特定のバグ修正や改善要求に対応するものであることを示しています。

前提知識の解説

このコミットを理解するためには、以下のGo言語に関する基本的な概念を理解しておく必要があります。

  • cmd/go: Go言語の公式ツールチェインに含まれるコマンドラインツールです。Goプログラムのビルド、テスト、インストール、フォーマットなど、多岐にわたる操作を行います。開発者が日常的に最も頻繁に利用するツールの一つです。
  • $GOROOT: Go言語のインストールディレクトリを示す環境変数です。Goの標準ライブラリやツールチェインの実行ファイルなどがこのディレクトリに格納されています。Goのバージョンやインストール方法によってパスは異なりますが、Goのビルドシステムはこの変数を利用して必要なリソースを見つけます。
  • $GOBIN: Goの実行可能バイナリがインストールされるディレクトリを示す環境変数です。go install コマンドなどでビルドされたプログラムは、デフォルトでこのディレクトリに配置されます。通常、このディレクトリはシステムのPATHに追加され、どこからでもGoの実行可能ファイルを実行できるように設定されます。
  • ビルドスクリプトの出力: cmd/go ツールがビルドプロセス中に生成する情報や、特定のコマンド(例: go build -x で詳細なビルドコマンドを表示する場合など)の出力のことです。この出力には、コンパイラやリンカの呼び出しコマンド、使用されるパスなどが含まれることがあります。
  • 正規化されたスクリプト(canonical script): 特定の環境や設定に依存せず、常に同じ形式で出力されるスクリプトのことです。バージョン管理システムで管理されるコードやスクリプトは、異なる開発者の環境でビルドされても、その出力が予測可能で一貫していることが望ましいとされます。

技術的詳細

このコミットは、src/cmd/go/build.go ファイル内の fmtcmd 関数から、$GOBIN$GOROOT の文字列置換処理を削除しています。

fmtcmd 関数は、ビルドコマンドの文字列を整形するために使用される内部関数です。この関数は、実際のファイルパス(gobingoroot 変数に格納されている値)を、対応する環境変数名($GOBIN$GOROOT)に置き換える処理を行っていました。

具体的には、以下の2行が削除されました。

--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -929,8 +929,6 @@ func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string
 	if b.work != "" {
 		cmd = strings.Replace(cmd, b.work, "$WORK", -1)
 	}
-	cmd = strings.Replace(cmd, gobin, "$GOBIN", -1)
-	cmd = strings.Replace(cmd, goroot, "$GOROOT", -1)
 	return cmd
 }

この変更により、fmtcmd 関数が生成するコマンド文字列には、実際の $GOBIN$GOROOT の値がそのまま含まれるようになります。つまり、以前は /usr/local/go/bin/go のようなパスが $GOBIN/go のように抽象化されて出力されていたのが、変更後は具体的なパスがそのまま出力されるようになります。

この変更は、Goのビルドシステムが、もはやスクリプト出力の正規化のためにこれらの環境変数による置換を必要としなくなったことを意味します。これは、Goのツールチェインが、環境変数の具体的な値に依存することなく、ビルドパスを適切に解決できるようになったか、あるいは、ビルドスクリプトの出力が、以前ほど厳密な正規化を必要としなくなったことを示唆しています。

コアとなるコードの変更箇所

src/cmd/go/build.go ファイルの fmtcmd 関数内。

// 変更前
func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string {
	cmd := fmt.Sprintf(format, args...)
	if b.work != "" {
		cmd = strings.Replace(cmd, b.work, "$WORK", -1)
	}
	cmd = strings.Replace(cmd, gobin, "$GOBIN", -1) // この行が削除
	cmd = strings.Replace(cmd, goroot, "$GOROOT", -1) // この行が削除
	return cmd
}

// 変更後
func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string {
	cmd := fmt.Sprintf(format, args...)
	if b.work != "" {
		cmd = strings.Replace(cmd, b.work, "$WORK", -1)
	}
	return cmd
}

コアとなるコードの解説

fmtcmd 関数は、cmd/go ツールが内部的に実行するシェルコマンドの文字列を整形する役割を担っています。この関数は、Goのビルドプロセス中に、コンパイラやリンカなどの外部ツールを呼び出す際に使用されるコマンドライン文字列を構築します。

変更前は、この関数は以下の3つの置換を行っていました。

  1. b.work (一時作業ディレクトリ) を $WORK に置換。
  2. gobin (Goバイナリのパス) を $GOBIN に置換。
  3. goroot (Goインストールルートのパス) を $GOROOT に置換。

これらの置換は、生成されるコマンド文字列が、特定の環境に依存しない「正規化された」形式になるように設計されていました。例えば、/home/user/go/bin/go というパスが $GOBIN/go と表示されることで、スクリプトの出力がより汎用的になり、異なるシステム上での実行を想定したドキュメントやログに適していました。

しかし、今回の変更で $GOBIN$GOROOT への置換が削除されたことにより、fmtcmd 関数はこれらのパスを具体的な値のまま出力するようになりました。これは、Goのビルドシステムが、もはやスクリプト出力の正規化のためにこれらの環境変数による抽象化を必要としなくなったことを示しています。

考えられる理由としては、以下のような点が挙げられます。

  • デバッグの容易性: 具体的なパスが出力されることで、問題発生時のデバッグが容易になる可能性があります。抽象化されたパスよりも、実際の実行パスが直接表示される方が、何が起こっているかを理解しやすいためです。
  • ビルドシステムの成熟: Goのビルドシステム自体が進化し、これらの環境変数を明示的に出力に含める必要がなくなった可能性があります。例えば、内部的なパス解決メカニズムが改善され、出力されるコマンド文字列が常に正しいパスを参照するようになったのかもしれません。
  • 冗長性の排除: コミットメッセージにある「getting in the way」という表現から、これらの置換がもはや有用ではなく、むしろ冗長であると判断されたことが伺えます。

この変更は、Goのツールチェインがより洗練され、内部的な複雑さをユーザーから隠蔽しつつ、必要に応じて具体的な情報を提供できるようになっていることを示唆しています。

関連リンク

参考にした情報源リンク

  • コミットメッセージ自体
  • Go言語の公式ドキュメント (一般的なGoの概念理解のため)
  • Go言語のソースコード (変更箇所の特定と理解のため)