[インデックス 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.