[インデックス 14687] ファイルの概要
このコミットは、Go言語のビルドツールである cmd/go
における gccgo
ツールチェーンのフラグ処理に関する改善と、ユーザーが誤ったツールチェーンオプションを渡した場合の警告機能の追加を目的としています。具体的には、gccgo
コマンドラインの末尾に gccgoflags
を渡すように変更し、gc
と gccgo
の間で誤ったフラグ(例: gccgo
使用時に -gcflags
を使用)が指定された場合にユーザーに警告を表示するようになりました。
コミット
commit 326ccebec8986de534c8608ff6f8fe7bd0070b10
Author: Shenghou Ma <minux.ma@gmail.com>
Date: Wed Dec 19 01:48:09 2012 +0800
cmd/go: pass gccgoflags at the end of gccgo command line, warn if user passes the wrong toolchain options
R=iant
CC=golang-dev
https://golang.org/cl/6940082
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/326ccebec8986de534c8608ff6f8fe7bd0070b10
元コミット内容
cmd/go: pass gccgoflags at the end of gccgo command line, warn if user passes the wrong toolchain options
R=iant
CC=golang-dev
https://golang.org/cl/6940082
変更の背景
Go言語のビルドシステムでは、複数のコンパイラツールチェーンをサポートしています。主要なものはGoチームが開発している gc
(Go Compiler) と、GCCをベースにした gccgo
です。これらのツールチェーンは、それぞれ異なるコマンドラインフラグを受け入れます。
以前の go build
コマンドでは、gccgo
ツールチェーンを使用する際に、コンパイラやリンカに渡すためのカスタムフラグを buildGccgoflags
変数を通じて処理していました。しかし、これらのフラグが gccgo
コマンドラインの途中に挿入されることがあり、特定のシナリオで問題を引き起こす可能性がありました。特に、リンカフラグ (-Wl,...
) のような特定のオプションは、コマンドラインの末尾に配置されることがGCCベースのツールでは一般的であり、そうでない場合に予期せぬ挙動やエラーが発生することがあります。
また、ユーザーが go build
コマンドを使用する際に、現在選択されているツールチェーン(gc
または gccgo
)に対して不適切なフラグ(例: gccgo
を使用しているのに -gcflags
を指定する、または gc
を使用しているのに -gccgoflags
を指定する)を渡してしまうという問題がありました。これは混乱を招き、意図しないビルド結果につながる可能性がありました。
このコミットは、これらの問題を解決するために、gccgo
のフラグ処理を改善し、ユーザーへの警告を強化することを目的としています。
前提知識の解説
go build
コマンド: Go言語のソースコードをコンパイルして実行可能ファイルを生成するための主要なコマンドです。Goモジュール内のパッケージをビルドし、依存関係を解決します。- Goツールチェーン: Go言語のプログラムをビルドするために必要な一連のツール(コンパイラ、リンカ、アセンブラなど)の総称です。
gc
(Go Compiler): Go言語の公式コンパイラであり、Goチームによって開発されています。Go言語のソースコードを直接機械語にコンパイルします。gccgo
: GCC (GNU Compiler Collection) をバックエンドとして使用するGo言語のコンパイラです。gc
とは異なる実装であり、GCCの最適化やクロスコンパイル機能を利用できる場合があります。- コンパイラフラグ (
-gcflags
,-gccgoflags
): コンパイラの挙動を制御するためのオプションです。-gcflags
:gc
コンパイラに渡されるフラグを指定します。-gccgoflags
:gccgo
コンパイラに渡されるフラグを指定します。
- リンカフラグ (
-ldflags
): リンカの挙動を制御するためのオプションです。通常、生成される実行ファイルの特性(例: 埋め込み情報、ライブラリのリンク方法)に影響を与えます。-Wl,...
: GCC系のツールでリンカにオプションを渡すための一般的な方法です。
技術的詳細
このコミットは、src/cmd/go/build.go
ファイル内の runBuild
関数と gccgcToolchain.ld
関数に焦点を当てています。
-
フラグの誤用に対する警告:
runBuild
関数内に新しい「sanity check」セクションが追加されました。これは、ユーザーがgo build
コマンドに渡したフラグが、現在使用されているツールチェーンに対して適切であるかを検証します。gccgo
ツールチェーンが選択されている場合 (buildContext.Compiler == "gccgo"
):- もし
buildGcflags
(gcコンパイラ用のフラグ) が指定されていたら、「go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags
」という警告が表示されます。 - もし
buildLdflags
(gcリンカ用のフラグ) が指定されていたら、「go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags
」という警告が表示されます。
- もし
gc
ツールチェーンが選択されている場合 (buildContext.Compiler == "gc"
):- もし
buildGccgoflags
(gccgoコンパイラ用のフラグ) が指定されていたら、「go build: when using gc toolchain, please pass compile flags using -gcflags, and linker flags using -ldflags
」という警告が表示されます。 これらの警告は、ユーザーが正しいフラグを使用するように促し、ビルドの失敗や予期せぬ挙動を防ぐのに役立ちます。
- もし
-
gccgo
コマンドラインでのgccgoflags
の配置変更:gccgcToolchain.ld
関数は、gccgo
ツールチェーンを使用して最終的な実行ファイルをリンクする際のコマンドラインを構築します。以前はbuildGccgoflags
がgccgo
コマンドラインの途中に配置されていました。 変更後、buildGccgoflags
はgccgo
コマンドラインの末尾に移動されました。これは、GCCベースのリンカがリンカ固有のオプション(特に-Wl,...
のようなもの)をコマンドラインの最後に期待する一般的な慣習に合わせたものです。これにより、gccgo
を使用したビルドの堅牢性が向上し、特定のリンカフラグが正しく解釈されるようになります。
コアとなるコードの変更箇所
src/cmd/go/build.go
ファイルの以下の部分が変更されました。
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -191,6 +191,21 @@ func runBuild(cmd *Command, args []string) {
*buildO += exeSuffix
}
+ // sanity check some often mis-used options
+ switch buildContext.Compiler {
+ case "gccgo":
+ if len(buildGcflags) != 0 {
+ fmt.Println("go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags")
+ }
+ if len(buildLdflags) != 0 {
+ fmt.Println("go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags")
+ }
+ case "gc":
+ if len(buildGccgoflags) != 0 {
+ fmt.Println("go build: when using gc toolchain, please pass compile flags using -gcflags, and linker flags using -ldflags")
+ }
+ }
+
if *buildO != "" {
if len(pkgs) > 1 {
fatalf("go build: cannot use -o with multiple packages")
@@ -1451,7 +1466,7 @@ func (tools gccgcToolchain) ld(b *builder, p *Package, out string, allactions []
if usesCgo && goos == "linux" {
ldflags = append(ldflags, "-Wl,-E")
}
- return b.run(".", p.ImportPath, "gccgo", "-o", out, buildGccgoflags, ofiles, "-Wl,-(\", ldflags, "-Wl,-)")
+ return b.run(".", p.ImportPath, "gccgo", "-o", out, ofiles, "-Wl,-(\", ldflags, "-Wl,-)", buildGccgoflags)
}
func (gccgcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
コアとなるコードの解説
runBuild
関数内の変更
// sanity check some often mis-used options
switch buildContext.Compiler {
case "gccgo":
if len(buildGcflags) != 0 {
fmt.Println("go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags")
}
if len(buildLdflags) != 0 {
fmt.Println("go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags")
}
case "gc":
if len(buildGccgoflags) != 0 {
fmt.Println("go build: when using gc toolchain, please pass compile flags using -gcflags, and linker flags using -ldflags")
}
}
このコードブロックは、go build
コマンドが実行される際に、ユーザーが指定したコンパイラフラグが現在のビルドコンテキスト(使用されているツールチェーン)と一致しているかをチェックします。
buildContext.Compiler
は、現在使用されているGoコンパイラ(gc
またはgccgo
)を示します。gccgo
が使用されているにもかかわらず、gc
用のフラグ (buildGcflags
やbuildLdflags
) が指定されている場合、適切なgccgoflags
を使用するよう警告します。- 同様に、
gc
が使用されているにもかかわらず、gccgo
用のフラグ (buildGccgoflags
) が指定されている場合、適切なgcflags
やldflags
を使用するよう警告します。 これにより、ユーザーの誤解を減らし、ビルドエラーを未然に防ぐことができます。
gccgcToolchain.ld
関数内の変更
- return b.run(".", p.ImportPath, "gccgo", "-o", out, buildGccgoflags, ofiles, "-Wl,-(\", ldflags, "-Wl,-)")
+ return b.run(".", p.ImportPath, "gccgo", "-o", out, ofiles, "-Wl,-(\", ldflags, "-Wl,-)", buildGccgoflags)
この行は、gccgo
リンカコマンドを構築する部分です。変更の核心は buildGccgoflags
の位置です。
- 変更前は
buildGccgoflags
がofiles
(オブジェクトファイル) の前に配置されていました。 - 変更後は
buildGccgoflags
がコマンドラインの末尾に移動されました。 これは、GCCベースのツール(gccgo
も含む)が、リンカに渡されるカスタムフラグや特殊なオプションをコマンドラインの最後に配置することを期待する一般的なパターンに準拠するためです。これにより、リンカがこれらのフラグを正しく解釈し、ビルドプロセスがより安定して予測可能になります。特に、-Wl,-(
や-Wl,-)
のようなリンカグループオプションの後にカスタムリンカフラグを配置することは、GCCリンカの動作において重要です。
関連リンク
このコミットに関連するGo Gerritの変更リスト (CL) は https://golang.org/cl/6940082
ですが、現在のツールでは直接その内容を取得できませんでした。
参考にした情報源リンク
- コミットの差分情報 (
git diff
) - Go言語のビルドシステムとツールチェーンに関する一般的な知識
- GCCおよび
gccgo
のコマンドラインオプションに関する一般的な知識