[インデックス 18866] ファイルの概要
このコミットは、Go言語のコマンドラインツール cmd/go
における go build -x
コマンドの出力に関するバグ修正です。具体的には、go build -x
が表示する go pack
コマンドラインが不正であった問題を修正しています。
コミット
commit 22aa54965e1cc7f0a2b194588c1bd8c7c627182d
Author: Jan Ziak <0xe2.0x9a.0x9b@gmail.com>
Date: Fri Mar 14 16:44:54 2014 +0100
cmd/go: fix invalid go pack command line in the output of go build -x
Fixes #7262
LGTM=iant
R=golang-codereviews, iant
CC=golang-codereviews
https://golang.org/cl/76110043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/22aa54965e1cc7f0a2b194588c1bd8c7c627182d
元コミット内容
cmd/go: fix invalid go pack command line in the output of go build -x
Fixes #7262
LGTM=iant
R=golang-codereviews, iant
CC=golang-codereviews
https://golang.org/cl/76110043
変更の背景
このコミットは、Goのビルドプロセスにおける内部コマンド go pack
の呼び出しに関する表示上の問題を修正することを目的としています。go build -x
コマンドは、ビルド中に実行されるすべてのコマンドを詳細に表示するデバッグオプションです。しかし、このオプションを使用した場合に表示される go pack
コマンドの引数が、実際に実行されるコマンドと異なっていました。
具体的には、既存のアーカイブファイルにオブジェクトファイルを「追加 (append)」する際に go pack
コマンドに渡される引数が rqP
と表示されていましたが、これは正しくありませんでした。正しい引数は r
であり、q
や P
は不要でした。この不一致は、ユーザーが go build -x
の出力を解析したり、ビルドプロセスを理解しようとしたりする際に混乱を招く可能性がありました。
この問題は、GoのIssueトラッカーで #7262 として報告されていました。このコミットは、その報告された問題を解決するためのものです。
前提知識の解説
go build
コマンド
go build
は、Goのソースコードをコンパイルして実行可能ファイルやパッケージアーカイブを生成するための主要なコマンドです。
go build -x
オプション
-x
オプションは、go build
が内部的に実行するすべてのコマンド(コンパイラ、アセンブラ、リンカ、アーカイブツールなど)を標準エラー出力に表示します。これは、ビルドプロセスの詳細をデバッグしたり、理解したりするのに非常に役立ちます。
go pack
コマンド
go pack
は、Goツールチェーンの一部として使用されるアーカイブツールです。これは、Unix系のシステムにおける ar
コマンドに似た機能を提供し、オブジェクトファイル(.o
ファイル)をまとめてライブラリアーカイブ(.a
ファイル)を作成したり、既存のアーカイブにファイルを追加したりするために使用されます。
go pack
の一般的な使用法は以下の通りです。
go pack r <archive_file> <object_files>
: 指定されたオブジェクトファイルをアーカイブファイルに追加します。アーカイブファイルが存在しない場合は新しく作成されます。go pack rq <archive_file> <object_files>
:r
と同様ですが、既存のメンバーを置き換えます。go pack rqP <archive_file> <object_files>
:rq
と同様ですが、P
オプションは、アーカイブ内のメンバー名にパス名を含めることを意味します。
このコミットの文脈では、既存のアーカイブにオブジェクトファイルを追加する際に go pack
が使用されます。
Goのビルドプロセス
Goのビルドプロセスは、複数のステップから構成されます。
- コンパイル: Goのソースファイル(
.go
)がコンパイラによってオブジェクトファイル(.o
)にコンパイルされます。 - アーカイブ: コンパイルされたオブジェクトファイルは、
go pack
などのツールによってライブラリアーカイブ(.a
)にまとめられます。これは、パッケージの依存関係を解決し、リンクを効率化するために行われます。 - リンク: 最終的に、すべてのライブラリアーカイブと必要なランタイムライブラリがリンカによって結合され、実行可能ファイルが生成されます。
go build -x
は、これらの各ステップで実際に実行されるコマンドを表示することで、ビルドプロセスの透明性を提供します。
技術的詳細
この修正は、src/cmd/go/build.go
ファイル内の pack
メソッドにあります。このメソッドは、go build
コマンドが内部的に go pack
ツールを呼び出す際のロジックをカプセル化しています。
問題は、既存のアーカイブファイルにオブジェクトファイルを追加する際に、appending
というフラグが true
に設定されるロジックにありました。この appending
が true
の場合、go pack
に渡すコマンド引数として cmd = "rqP"
が設定されていました。しかし、実際に必要なのは r
オプションのみでした。q
(quiet) や P
(pathnames) は、この文脈では不要であり、go build -x
の出力に誤った情報として表示されていました。
修正は、appending
が true
の場合に cmd
変数を "r"
に変更するだけです。これにより、go pack
コマンドラインが正しく pack r <archive_file> <object_files>
の形式で表示されるようになります。
stringList
関数は、与えられた文字列スライスを結合してコマンドライン文字列を生成するために使用されます。修正前は、pack
, cmd
, b.work
, absAfile
, absOfiles
の順で引数が渡されていましたが、修正後は b.work
(作業ディレクトリ) が削除され、pack
, cmd
, absAfile
, absOfiles
の順で引数が渡されるようになりました。これは、go pack
コマンド自体が作業ディレクトリを引数として必要としないため、go build -x
の出力から不要な情報を削除し、より正確なコマンドラインを表示するための変更です。
コアとなるコードの変更箇所
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -1625,10 +1625,10 @@ func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []s
appending := false
if _, err := os.Stat(absAfile); err == nil {
appending = true
- cmd = "rqP"
+ cmd = "r"
}
- cmdline := stringList("pack", cmd, b.work, absAfile, absOfiles)
+ cmdline := stringList("pack", cmd, absAfile, absOfiles)
if appending {
if buildN || buildX {
コアとなるコードの解説
変更前
appending := false
if _, err := os.Stat(absAfile); err == nil {
appending = true
cmd = "rqP" // 既存のアーカイブファイルが存在する場合、"rqP" を設定
}
cmdline := stringList("pack", cmd, b.work, absAfile, absOfiles) // b.work もコマンドラインに含める
os.Stat(absAfile)
: 指定されたパスabsAfile
(アーカイブファイルの絶対パス) のファイル情報を取得しようとします。err == nil
: ファイルが存在する場合、エラーはnil
となり、appending
がtrue
に設定されます。cmd = "rqP"
:appending
がtrue
の場合、go pack
に渡すコマンド引数として"rqP"
が設定されます。これは、既存のアーカイブにファイルを追加する際に使用されるオプションです。しかし、このq
(quiet) とP
(pathnames) は、go build -x
の出力において不要な情報でした。stringList("pack", cmd, b.work, absAfile, absOfiles)
:go pack
コマンドラインを構築します。このとき、b.work
(ビルドの作業ディレクトリ) も引数として含まれていました。
変更後
appending := false
if _, err := os.Stat(absAfile); err == nil {
appending = true
cmd = "r" // 既存のアーカイブファイルが存在する場合、"r" に修正
}
cmdline := stringList("pack", cmd, absAfile, absOfiles) // b.work を削除
cmd = "r"
:appending
がtrue
の場合、go pack
に渡すコマンド引数が"r"
に修正されました。r
オプションは、既存のアーカイブにメンバーを追加または置き換えるための標準的なオプションであり、q
やP
はこの文脈では冗長でした。これにより、go build -x
の出力がより正確になります。stringList("pack", cmd, absAfile, absOfiles)
:go pack
コマンドラインの構築からb.work
が削除されました。go pack
コマンド自体は作業ディレクトリを引数として必要としないため、この変更はgo build -x
の出力をより簡潔で正確なものにします。
この修正により、go build -x
の出力は、実際に go pack
が実行される際のコマンドラインを正確に反映するようになり、デバッグやビルドプロセスの理解が容易になります。
関連リンク
- Go issue #7262:
cmd/go: fix invalid go pack command line in the output of go build -x
(このコミットが修正した問題の報告)- 直接的なリンクは見つかりませんでしたが、コミットメッセージに記載されています。
- Go CL 76110043:
cmd/go: fix invalid go pack command line in the output of go build -x
(このコミットの変更リスト)
参考にした情報源リンク
- Goの公式ドキュメント(
go build
、go tool pack
などに関する情報) ar
コマンドのmanページ(go pack
の動作を理解するための参考)- Goのソースコード(
src/cmd/go/build.go
) - GoのIssueトラッカー(過去のIssueの検索)
- Goのコードレビューシステム(Gerrit)