[インデックス 13589] ファイルの概要
このコミットは、Go言語のビルドツールであるcmd/go
において、生成されるバイナリファイルから一時的な作業ディレクトリのパス($WORK
パス)が埋め込まれる問題を修正するものです。これにより、ビルドの再現性が向上し、デバッグ情報のクリーンアップが図られます。
コミット
commit df623d03ab2518e691d198b51380a005332d251d
Author: Shenghou Ma <minux.ma@gmail.com>
Date: Tue Aug 7 10:00:58 2012 +0800
cmd/go: remove $WORK paths in generated binaries
Fixes #3748.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6357064
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/df623d03ab2518e691d198b51380a005332d251d
元コミット内容
cmd/go: remove $WORK paths in generated binaries
Fixes #3748.
このコミットは、Goのビルドプロセスによって生成されるバイナリファイルに、ビルド時の一時作業ディレクトリのパス($WORK
パス)が埋め込まれる問題を解決します。これは、GoのIssue #3748で報告された問題の修正です。
変更の背景
Go言語のビルドシステムは、コンパイルやリンクの際に一時的な作業ディレクトリ($WORK
)を使用します。このディレクトリは、ソースファイルからオブジェクトファイル、アーカイブファイル、最終的な実行可能ファイルが生成される過程で中間ファイルを格納するために利用されます。
しかし、Go 1.0のリリース後、生成されたバイナリファイル(特にアーカイブファイルやデバッグ情報)に、この一時的な$WORK
ディレクトリの絶対パスが埋め込まれてしまうという問題が報告されました(Issue #3748)。この問題は、以下のような影響を引き起こしました。
- ビルドの再現性の低下: 同じソースコードからビルドしても、ビルドを実行する環境やタイミングによって
$WORK
ディレクトリのパスが異なるため、生成されるバイナリが完全に同一にならないという問題が発生しました。これは、ソフトウェアの検証や配布において望ましくありません。 - デバッグ情報のノイズ: デバッグ情報に一時的なパスが含まれることで、デバッグ時の情報が冗長になったり、環境依存性が発生したりする可能性がありました。
- セキュリティとプライバシー: ビルド環境のファイルシステム構造に関する情報がバイナリに漏洩する可能性がありました。
このコミットは、これらの問題を解決し、生成されるバイナリのクリーンさと再現性を向上させることを目的としています。
前提知識の解説
Goのビルドプロセスと$WORK
ディレクトリ
Goのビルドプロセスは、go build
コマンドによって実行されます。このコマンドは、内部的に以下のステップを踏みます。
- 依存関係の解決: 必要なパッケージを特定し、ダウンロードします。
- コンパイル: 各Goソースファイル(
.go
)をコンパイルし、オブジェクトファイル(.o
)を生成します。 - アーカイブ: オブジェクトファイルをまとめてアーカイブファイル(
.a
)を生成します。これは、C/C++における静的ライブラリに相当します。 - リンク: アーカイブファイルと必要なランタイムライブラリをリンクし、最終的な実行可能ファイルまたは共有ライブラリを生成します。
このプロセス中、Goツールチェーンは一時的な作業ディレクトリを作成します。このディレクトリは通常、$TMPDIR/go-buildXXXXX
のような形式で、ビルドが完了すると削除されます。この一時ディレクトリが、本コミットで問題となっている$WORK
パスに該当します。
pack
コマンド
pack
コマンドは、Goツールチェーンの一部であり、オブジェクトファイルをアーカイブファイルにまとめるために使用されます。これは、ar
コマンド(Unix系のシステムでアーカイブを作成・管理するためのユーティリティ)に似た機能を提供します。
Goのビルドプロセスにおいて、pack
コマンドはコンパイルされたオブジェクトファイルを収集し、それらを単一のアーカイブファイル(.a
)に結合します。このアーカイブファイルは、後続のリンクステップで利用されます。
grc
とgrcP
オプション
pack
コマンドには、アーカイブの作成方法を制御するための様々なオプションがあります。
grc
: これは、Goのツールチェーンが内部的に使用するpack
コマンドのオプションの一つで、"create" (作成) を意味します。grcP
: このコミットで導入された、または既存のpack
コマンドのオプションの利用方法を変更したものです。P
は"prefix" (プレフィックス) を意味し、アーカイブ内のパスから特定のプレフィックス(この場合は$WORK
パス)を取り除くことを指示します。
技術的詳細
このコミットの技術的な核心は、Goツールチェーンが内部的にpack
コマンドを呼び出す際の引数を変更することによって、生成されるアーカイブファイルから$WORK
パスを削除する点にあります。
変更前は、pack
コマンドはgrc
オプションを使用してアーカイブを作成していました。この際、オブジェクトファイルのパスはそのままアーカイブに埋め込まれていました。もしオブジェクトファイルが$WORK
ディレクトリ内にあった場合、その絶対パスがアーカイブに記録されていました。
変更後は、pack
コマンドの呼び出しにgrcP
オプションと、b.work
という引数が追加されました。
grcP
: このオプションは、pack
コマンドに対して、アーカイブに含めるファイルのパスから指定されたプレフィックス(b.work
、つまり$WORK
ディレクトリのパス)を取り除くように指示します。b.work
: これは、現在のビルドプロセスで使用されている一時的な$WORK
ディレクトリの絶対パスを表します。
これにより、pack
コマンドはアーカイブを作成する際に、各オブジェクトファイルのパスから$WORK
ディレクトリのプレフィックスを削除します。例えば、オブジェクトファイルが/tmp/go-build12345/src/pkg/foo.o
というパスにあった場合、pack
コマンドはアーカイブ内にsrc/pkg/foo.o
として記録するようになります。結果として、生成されるアーカイブファイルには、ビルド環境に依存しない相対パスのみが埋め込まれることになります。
この変更は、src/cmd/go/build.go
ファイル内のgcToolchain.pack
メソッドに適用されています。このメソッドは、Goの標準コンパイラ(gc
)ツールチェーンがパッケージをアーカイブする際のロジックを定義しています。
コアとなるコードの変更箇所
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -1299,7 +1299,7 @@ func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []s
for _, f := range ofiles {
absOfiles = append(absOfiles, mkAbs(objDir, f))\n }
-\treturn b.run(p.Dir, p.ImportPath, tool("pack"), "grc", mkAbs(objDir, afile), absOfiles)\n+\treturn b.run(p.Dir, p.ImportPath, tool("pack"), "grcP", b.work, mkAbs(objDir, afile), absOfiles)\n }\n
func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
コアとなるコードの解説
変更はsrc/cmd/go/build.go
ファイルのgcToolchain.pack
メソッド内の一行に集約されています。
元のコード:
return b.run(p.Dir, p.ImportPath, tool("pack"), "grc", mkAbs(objDir, afile), absOfiles)
この行では、pack
コマンドをgrc
オプションと共に実行し、オブジェクトファイル(absOfiles
)をアーカイブファイル(mkAbs(objDir, afile)
)にまとめる処理を行っていました。
変更後のコード:
return b.run(p.Dir, p.ImportPath, tool("pack"), "grcP", b.work, mkAbs(objDir, afile), absOfiles)
この変更では、pack
コマンドのオプションが"grc"
から"grcP"
に変更され、さらにb.work
という新しい引数が追加されています。
tool("pack")
:pack
コマンドの実行可能ファイルへのパスを取得します。"grcP"
:pack
コマンドに渡される新しいオプションです。前述の通り、これはアーカイブ内のパスから指定されたプレフィックス(b.work
)を取り除くことを指示します。b.work
:builder
構造体(b
)のwork
フィールドは、現在のビルドプロセスで使用されている一時的な$WORK
ディレクトリの絶対パスを保持しています。このパスがgrcP
オプションの引数としてpack
コマンドに渡されます。mkAbs(objDir, afile)
: 生成されるアーカイブファイルの絶対パスです。absOfiles
: アーカイブに含めるオブジェクトファイルの絶対パスのリストです。
この変更により、pack
コマンドはabsOfiles
内の各パスからb.work
で指定されたプレフィックスを削除した上で、アーカイブに格納するようになります。これにより、生成されるアーカイブファイルには、ビルド環境に依存しない相対パスのみが記録され、Issue #3748で報告された問題が解決されます。
関連リンク
- Go Issue #3748: https://github.com/golang/go/issues/3748
- Go CL 6357064: https://golang.org/cl/6357064
参考にした情報源リンク
- Web search results for "Go issue 3748": https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFuHA-u9stUHjV9D4fxgs_-Qd3WW1ysNsYKMxCWg0OxSBQWHYZivmWjDHifNxarRIvWIK9y48PoOVvuD2qLLtPFEWHrpOhHBpZvvzy6p-zWAzN3ebfDTuvhD3x0CsMI1Auz
- Go言語の公式ドキュメントおよびソースコード (Go 1.0当時のビルドシステムに関する情報)