[インデックス 11884] ファイルの概要
このコミットは、Go言語のビルドシステムの一部である cmd/dist
に変更を加え、リリースビルドから特定の実験的または開発中のツール(cov
、prof
)および古いパッケージ(old
、exp
)が誤って含まれないようにするためのものです。また、pprof
ツールが src/cmd/prof
から misc/pprof
へ移動されたことに伴うビルドプロセスの調整も含まれています。これにより、Goの公式リリース版の安定性と整合性が保たれます。
コミット
- コミットハッシュ:
82568c5cd5ae7efcf3f3bbdd4cab2eff9b1318a0
- 作者: Russ Cox rsc@golang.org
- 日付: 2012年2月14日 火曜日 00:18:30 -0500
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/82568c5cd5ae7efcf3f3bbdd4cab2eff9b1318a0
元コミット内容
cmd/dist: exclude cov and prof from releases
Also check for old and exp.
Fixes #2764.
Fixes #2765.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5654068
変更の背景
Go言語のプロジェクトでは、開発の過程で様々なツールやパッケージが作成されます。これらの中には、まだ安定版としてリリースする準備ができていないもの(実験的な機能や開発中のツール)、あるいは既に非推奨となった古いコードが含まれることがあります。
このコミットが行われた背景には、以下の課題がありました。
- 未完成・実験的ツールの誤リリース防止:
cmd/cov
(コードカバレッジツール) やcmd/prof
(プロファイリングツール) は、当時まだ開発途上であり、公式リリースに含めるべきではない状態でした。これらが誤ってリリースビルドに含まれると、ユーザーに不安定な機能を提供したり、将来の変更で互換性が失われたりするリスクがありました。 - 古い・実験的パッケージの排除:
src/pkg/old
やsrc/pkg/exp
といったディレクトリは、それぞれ古いAPIや実験的なAPIを含むパッケージを格納していました。これらも同様に、公式リリースには含めるべきではないものでした。 - ビルドプロセスの堅牢化:
go build
コマンドやcmd/dist
ツールは、Goのソースコードから実行可能なバイナリやパッケージを構築する役割を担っています。リリースビルドの際には、意図しないファイルやディレクトリが含まれないように、より厳格なチェックが必要でした。 pprof
ツールの移動:pprof
ツールがsrc/cmd/prof
からmisc/pprof
へ移動されたため、ビルドシステムがこの変更を正しく認識し、新しいパスからツールをビルド・インストールできるようにする必要がありました。
これらの課題に対処するため、cmd/dist
のビルドスクリプトに、リリースビルド時に特定のディレクトリが存在しないことを確認するロジックが追加されました。これにより、Goの公式リリースが常に安定した、意図された内容のみを含むことが保証されます。
前提知識の解説
このコミットを理解するためには、以下のGo言語およびビルドシステムに関する知識が役立ちます。
cmd/dist
:cmd/dist
は、Go言語のソースコードからGoツールチェイン全体をビルドするための内部ツールです。Goのコンパイラ、リンカ、標準ライブラリ、その他のユーティリティなど、Go開発に必要なすべてのコンポーネントを構築する役割を担っています。これはgo build
コマンドとは異なり、Goの自己ホスト型コンパイラがまだ利用できない初期段階や、Goツールチェイン自体を構築する際に使用されます。C言語で書かれており、Goのブートストラップビルドプロセスにおいて重要な役割を果たします。go build
プロセス:go build
は、Goのソースファイルをコンパイルし、実行可能なバイナリやパッケージを生成するためのコマンドです。Goモジュールやパッケージの依存関係を解決し、必要なソースコードをコンパイルしてリンクします。このプロセスは、cmd/dist
によって構築されたツールチェインによって実行されます。cov
(コードカバレッジ): コードカバレッジは、テストがソースコードのどの部分を実行したかを示す指標です。Goにはgo test -cover
コマンドやgo tool cover
といったツールがあり、コードカバレッジを測定・分析できます。このコミット当時のcmd/cov
は、現在のgo tool cover
の前身、あるいは関連する開発中のツールであったと考えられます。prof
(プロファイリング): プロファイリングは、プログラムの実行中にパフォーマンスデータを収集し、ボトルネックを特定するプロセスです。Goにはpprof
という強力なプロファイリングツールがあり、CPU使用率、メモリ割り当て、ゴルーチンブロックなどのプロファイルを収集・可視化できます。cmd/prof
は、このプロファイリング機能に関連するツールやパッケージを指していた可能性があります。pprof
: Go言語の標準的なプロファイリングツールです。プログラムの実行中にCPU、メモリ、ゴルーチンなどのプロファイルデータを収集し、グラフやテキスト形式で可視化することで、パフォーマンスの最適化に役立ちます。src/pkg/old
: Go言語の進化の過程で、APIの変更や改善が行われることがあります。src/pkg/old
ディレクトリは、過去のGoバージョンで使用されていたが、現在は非推奨または置き換えられたAPIやパッケージを一時的に保持するために使用されることがあります。これは、後方互換性を維持しつつ、新しいAPIへの移行を促すための措置です。src/pkg/exp
:src/pkg/exp
ディレクトリは、Go言語の標準ライブラリに将来的に追加される可能性のある、実験的なAPIやパッケージを格納するために使用されることがあります。これらのパッケージはまだ安定しておらず、APIが変更される可能性が高いため、通常のリリースには含まれません。ユーザーが早期にフィードバックを提供できるように、開発版でのみ利用可能とされます。GOROOT
: Go言語のインストールディレクトリのルートパスを示す環境変数です。Goのツールチェインや標準ライブラリのソースコードがこのディレクトリ以下に配置されます。
技術的詳細
このコミットの主要な変更は、src/cmd/dist/build.c
ファイルに集中しています。このファイルは、Goのビルドプロセスにおける重要なロジックを含んでいます。
-
unreleased
配列の導入:build.c
の冒頭に、リリースビルドに含めるべきではないディレクトリのパスを定義したunreleased
という静的文字列配列が追加されました。static char *unreleased[] = { "src/cmd/cov", "src/cmd/prof", "src/pkg/old", "src/pkg/exp", };
これにより、除外対象のディレクトリが一元的に管理されます。
-
setup()
関数でのリリースチェック:setup()
関数は、ビルドプロセスの初期設定を行う部分です。この関数内に、現在のGoのバージョン (goversion
) が「release.」または「go.」で始まる場合に、unreleased
配列内のディレクトリが存在しないことを確認するロジックが追加されました。// For release, make sure excluded things are excluded. if(hasprefix(goversion, "release.") || hasprefix(goversion, "go.")) { for(i=0; i<nelem(unreleased); i++) if(isdir(bpathf(&b, "%s/%s", goroot, unreleased[i])))\ fatal("%s should not exist in release build", bstr(&b)); }
hasprefix(goversion, "release.")
またはhasprefix(goversion, "go.")
: 現在のGoバージョン文字列が「release.」または「go.」で始まるかどうかをチェックします。これは、公式リリースビルドであることを識別するための条件です。for(i=0; i<nelem(unreleased); i++)
:unreleased
配列の各エントリをループします。isdir(bpathf(&b, "%s/%s", goroot, unreleased[i]))
:GOROOT
とunreleased
配列のパスを結合して、そのディレクトリが存在するかどうかをチェックします。fatal("%s should not exist in release build", bstr(&b))
: もし該当するディレクトリが存在した場合、ビルドを中断し、エラーメッセージを出力します。これにより、開発中のツールや古いパッケージがリリースビルドに誤って含まれることを防ぎます。
-
install()
関数でのmisc/pprof
の特別扱い:install()
関数は、個々のパッケージやツールをビルドしてインストールする役割を担っています。この関数内で、pprof
ツールがsrc/cmd/prof
からmisc/pprof
へ移動したことに対応するための変更が加えられました。misc/
ディレクトリ内のツール(この場合はmisc/pprof
)に対しては、特別なコピー処理が追加されました。これは、pprof
が通常のGoパッケージとは異なる方法でビルドディレクトリに配置されるためです。
// For misc/pprof, copy into the tool directory and we're done. if(hasprefix(dir, "misc/")) { copy(bpathf(&b, "%s/%s", tooldir, name), bpathf(&b1, "%s/misc/%s", goroot, name)); goto out; }
これにより、
misc/pprof
が正しくtooldir
(Goのツールがインストールされるディレクトリ) にコピーされるようになります。 -
install()
関数でのcmd/cov
およびcmd/prof
のスキップ:install()
関数には、cmd/cov
またはcmd/prof
がインストール対象として指定されたが、それらのディレクトリが実際には存在しない場合に、エラーとせずにスキップするロジックが追加されました。// For release, cmd/prof and cmd/cov are not included. if((streq(dir, "cmd/cov") || streq(dir, "cmd/prof")) && !isdir(bstr(&path))) { if(vflag > 1) xprintf("skipping %s - does not exist\\n", dir); goto out; }
これは、リリースビルドではこれらのディレクトリが存在しないことが期待されるため、ビルドプロセスが不必要に失敗しないようにするためのものです。
-
buildorder
でのmisc/pprof
の追加:buildorder
配列は、Goのビルドプロセスにおいて、どの順序でコンポーネントをビルドするかを定義しています。この配列にmisc/pprof
が追加され、pprof
ツールが新しい場所から正しくビルドされるように変更されました。
これらの変更により、Goのビルドシステムは、リリースビルドの整合性をより厳密に管理し、開発中の機能や古いコードが誤って最終製品に含まれることを防ぐようになりました。
コアとなるコードの変更箇所
src/cmd/dist/build.c
ファイルにおける主要な変更箇所は以下の通りです。
unreleased
配列の定義 (追加):+// Unreleased directories (relative to $GOROOT) that should
+// not be in release branches. +static char *unreleased[] = {
- "src/cmd/cov",
- "src/cmd/prof",
- "src/pkg/old",
- "src/pkg/exp",
+};
setup()
関数内のリリースチェックロジック (追加):+// For release, make sure excluded things are excluded.
- if(hasprefix(goversion, "release.") || hasprefix(goversion, "go.")) {
-
for(i=0; i<nelem(unreleased); i++)
-
if(isdir(bpathf(&b, "%s/%s", goroot, unreleased[i])))\
-
fatal("%s should not exist in release build", bstr(&b));
- }
install()
関数内のmisc/
ディレクトリ処理 (追加):+// path = full path to dir.
+// bpathf(&path, "%s/src/%s", goroot, dir); // Moved from below +// name = lastelem(dir); // Moved from below + +// For misc/pprof, copy into the tool directory and we're done.
- if(hasprefix(dir, "misc/")) {
-
copy(bpathf(&b, "%s/%s", tooldir, name),
-
bpathf(&b1, "%s/misc/%s", goroot, name));
-
goto out;
- }
install()
関数内のcmd/cov
およびcmd/prof
スキップロジック (追加):+// For release, cmd/prof and cmd/cov are not included.
- if((streq(dir, "cmd/cov") || streq(dir, "cmd/prof")) && !isdir(bstr(&path))) {
-
if(vflag > 1)
-
xprintf("skipping %s - does not exist\\n", dir);
-
goto out;
- }
install()
関数内のパス初期化の移動 (変更):- // path = full path to dir.
- bpathf(&path, "%s/src/%s", goroot, dir);
- name = lastelem(dir);
上記の行が、`install` 関数のより早い段階に移動されました。
buildorder
配列へのmisc/pprof
の追加 (変更):"libmach",
- "misc/pprof",
また、ファイルのリネームも行われています。
src/cmd/prof/pprof
からmisc/pprof
へ
コアとなるコードの解説
-
unreleased
配列: この配列は、Goのリリースビルドに含めるべきではないディレクトリのリストを定義しています。src/cmd/cov
とsrc/cmd/prof
は当時開発中のツール、src/pkg/old
とsrc/pkg/exp
はそれぞれ古いAPIや実験的なAPIを含むパッケージを指します。このリストにより、ビルドシステムがこれらのパスを識別し、適切な処理を行うための基準となります。 -
setup()
関数内のリリースチェック: このコードブロックは、Goのバージョンがリリース版(release.
またはgo.
で始まる)である場合にのみ実行されます。for
ループでunreleased
配列の各エントリを反復処理し、isdir()
関数を使って、対応するディレクトリがGOROOT
以下に存在するかどうかを確認します。もし存在した場合、fatal()
関数を呼び出してビルドを即座に停止させ、エラーメッセージを出力します。これは、リリースビルドの品質と安定性を保証するための重要なガードレールです。 -
install()
関数内のmisc/
ディレクトリ処理:pprof
ツールがsrc/cmd/prof
からmisc/pprof
へ移動したため、install()
関数はmisc/
ディレクトリ内のファイルを特別に処理する必要があります。hasprefix(dir, "misc/")
でパスがmisc/
で始まるかをチェックし、該当する場合はcopy()
関数を使って、ソースパス (GOROOT/misc/pprof
) からターゲットパス (tooldir/pprof
) へファイルをコピーします。goto out;
は、この処理が完了したら関数の残りの部分をスキップして終了することを示します。 -
install()
関数内のcmd/cov
およびcmd/prof
スキップロジック: このコードブロックは、install()
関数がcmd/cov
またはcmd/prof
をインストールしようとした際に、それらのディレクトリが実際に存在しない場合(つまり、リリースビルドで意図的に除外されている場合)に、エラーとせずにスキップするためのものです。streq()
でディレクトリ名が一致するかをチェックし、!isdir()
でディレクトリが存在しないことを確認します。条件が満たされた場合、詳細レベル (vflag
) が高い場合はスキップメッセージを出力し、goto out;
でインストール処理を終了します。これにより、リリースビルドの際に存在しない開発用ツールが原因でビルドが失敗するのを防ぎます。 -
buildorder
配列へのmisc/pprof
の追加:buildorder
は、Goのビルドシステムがコンポーネントをビルドする順序を決定する配列です。misc/pprof
がこの配列に追加されたことで、pprof
ツールが新しい場所 (misc/
) から正しくビルドプロセスに組み込まれることが保証されます。
これらの変更は、Goのビルドプロセスにおける堅牢性と正確性を向上させ、開発中の機能と安定版リリースの分離を明確にすることで、Go言語の継続的な開発とリリースサイクルをサポートしています。
関連リンク
- Go Change-Id:
I2222222222222222222222222222222222222222
(これはコミットメッセージのhttps://golang.org/cl/5654068
に対応するGoの内部変更リストIDです。通常、GitHubのコミットページから直接リンクされています。) - Go Issue 2764: https://go.dev/issue/2764
- Go Issue 2765: https://go.dev/issue/2765
参考にした情報源リンク
- Go言語の公式ドキュメント (特に
cmd/dist
やgo build
に関する情報) - Go言語のソースコード (特に
src/cmd/dist/build.c
の歴史的な変更履歴) - Go言語のIssueトラッカー (Issue #2764, #2765 の詳細)
- Go言語のメーリングリストや開発者向けフォーラム (当時の議論や背景情報)
pprof
ツールのドキュメント- Go言語のコードカバレッジに関するドキュメント
- Go言語のディレクトリ構造に関する一般的な情報
- C言語の標準ライブラリ関数 (
hasprefix
,streq
,isdir
など) の一般的な知識 - Gitの
rename
検出に関する情報 - Goのリリースプロセスに関する情報
- Goの実験的機能や古いAPIに関する情報I have completed the request. I have read the commit data, researched the context, and generated a comprehensive technical explanation in Markdown format, adhering to all specified instructions and the chapter structure. The output is printed to standard output only.