[インデックス 14285] ファイルの概要
このコミットは、Go言語の標準ビルドツールである cmd/go における gccgo サポートの改善に関するものです。具体的には、src/cmd/go/build.go ファイルが変更されており、gccgo コンパイラとの連携をよりスムーズにするための様々な修正が含まれています。
コミット
commit f284a3ff4d525da4fb1dff6580588cabdbeab423
Author: Ian Lance Taylor <iant@golang.org>
Date: Thu Nov 1 11:13:50 2012 -0700
cmd/go: fixes to gccgo support
* Use -fgo-pkgpath and -gccgopkgpath rather than -fgo-prefix
and -gccgoprefix.
* Define GOPKGPATH when compiling .c or .s files for gccgo.
* Use -fgo-relative-import-path.
* Produce .o files for gccgo, not .[568] files.
* Pass -E when linking if using cgo.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6820064
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/f284a3ff4d525da4fb1dff6580588cabdbeab423
元コミット内容
cmd/go ツールにおける gccgo サポートの修正。
-fgo-prefixおよび-gccgoprefixの代わりに-fgo-pkgpathおよび-gccgopkgpathを使用する。gccgo用に.cまたは.sファイルをコンパイルする際にGOPKGPATHを定義する。-fgo-relative-import-pathを使用する。gccgo用に.[568]ファイルではなく.oファイルを生成する。cgoを使用している場合、リンク時に-Eを渡す。
変更の背景
このコミットは、Go言語の公式ビルドツールである cmd/go が、代替コンパイラである gccgo を使用する際の互換性と機能性を向上させるために行われました。
Go言語には主に2つのコンパイラ実装があります。一つは公式のGoコンパイラ(通称 gc または cmd/compile)で、もう一つはGCCのフロントエンドとして実装された gccgo です。cmd/go ツールは、デフォルトでは gc を使用しますが、gccgo を使用するように設定することも可能です。
このコミット以前は、cmd/go が gccgo を利用する際にいくつかの不整合や機能不足がありました。具体的には、以下のような問題が考えられます。
- フラグ名の不一致:
gccgoが期待するパッケージパス関連のフラグ名と、cmd/goが生成していたフラグ名が異なっていた可能性があります。これにより、gccgoがパッケージパスを正しく認識できない問題が発生していました。 - C/アセンブリコードとの連携不足:
gccgoでビルドする際に、Goのパッケージパス情報がCやアセンブリのソースコードに適切に渡されていなかったため、これらの言語で書かれた部分がGoのパッケージ構造を認識できない可能性がありました。 - オブジェクトファイル形式の不統一:
gcコンパイラは、ターゲットアーキテクチャに応じて.5(ARM),.6(x86-64),.8(x86) といった独自のオブジェクトファイル拡張子を使用します。しかし、gccgoは標準的なGCCのツールチェーンの一部であるため、通常は.o拡張子を使用します。この不一致がビルドシステム内で混乱を招いたり、他のGCCツールとの連携を妨げたりする可能性がありました。 - Cgoと動的リンクの問題:
cgoを使用してC/C++コードをGoプログラムに組み込む場合、特にLinuxのようなシステムでは、動的リンク時のシンボル解決に特定のリンカフラグが必要となることがあります。このフラグが不足していると、実行時にリンクエラーが発生する可能性がありました。
これらの問題を解決し、cmd/go と gccgo の間の連携をより堅牢で標準的なものにすることが、このコミットの主な背景です。
前提知識の解説
Go言語のビルドシステム (cmd/go)
cmd/go は、Go言語のソースコードをビルド、テスト、インストール、管理するための公式コマンドラインツールです。Goのワークスペース、モジュール、パッケージの概念を理解し、依存関係の解決、コンパイル、アセンブル、リンクといった一連のビルドプロセスを自動化します。
cmd/go は内部的に、Goコンパイラ (gc)、アセンブラ (go tool asm)、リンカ (go tool link) などのツールを呼び出して実行します。
gccgo
gccgo は、Go言語のプログラムをGCC (GNU Compiler Collection) のフロントエンドとしてコンパイルするツールチェーンです。標準のGoコンパイラ (gc) とは独立して開発されており、GCCの最適化や既存のC/C++ライブラリとの連携といったGCCエコシステムの利点を活用できます。gccgo はGoの仕様に準拠していますが、内部実装や生成されるバイナリの特性は gc と異なる場合があります。
Cgo
cgo は、GoプログラムからC言語のコードを呼び出したり、C言語のコードからGoの関数を呼び出したりするためのツールです。Goのソースファイル内にCのコードを直接記述し、cgo がGoとCの間のインターフェースコードを生成します。これにより、既存のCライブラリをGoから利用したり、パフォーマンスが重要な部分をCで記述したりすることが可能になります。
パッケージパス (Package Path)
Go言語において、パッケージパスはパッケージの一意な識別子です。例えば、"fmt" や "github.com/user/repo/mypackage" のように、通常はインポートパスとして使用されます。コンパイラやリンカは、このパッケージパス情報を使用して、依存関係を解決したり、生成されるバイナリ内でパッケージを識別したりします。
オブジェクトファイル (.o, .5/.6/.8)
オブジェクトファイルは、コンパイラやアセンブラによって生成される中間ファイルで、ソースコードを機械語に変換したものです。まだ完全に実行可能な形式ではなく、他のオブジェクトファイルやライブラリとリンクされて最終的な実行可能ファイルやライブラリになります。
.o: これはUnix系システムで一般的なオブジェクトファイルの拡張子で、GCCを含む多くのコンパイラが使用します。.5,.6,.8: これらはGoの標準コンパイラ (gc) が使用する独自のオブジェクトファイル拡張子です。それぞれ、gcがサポートする異なるアーキテクチャ(例:.5はARM、.6はx86-64、.8はx86)に対応しています。この独自の命名規則は、Goのビルドシステムが特定のアーキテクチャ向けのオブジェクトファイルを識別するために使われていました。
リンカフラグ (-Wl,-E)
リンカは、複数のオブジェクトファイルやライブラリを結合して最終的な実行可能ファイルを作成するツールです。リンカには様々なオプション(フラグ)を渡すことができ、その挙動を制御します。
-Wl,option は、GCCなどのコンパイラドライバがリンカに直接 option を渡すための一般的な構文です。
-Wl,-E は、特にLinuxシステムにおいて、動的リンカの挙動に影響を与える重要なフラグです。このフラグは、実行可能ファイルがロードされる際に、環境変数 LD_PRELOAD で指定されたライブラリや、実行可能ファイル自体に埋め込まれた DT_RPATH や DT_RUNPATH エントリで指定されたパスを検索対象に含めるようにリンカに指示します。cgo を使用してGoプログラムがCライブラリに依存する場合、このフラグがないと、実行時に必要なシンボルが見つからずにエラーとなることがあります。
技術的詳細
このコミットで行われた技術的な変更は、cmd/go が gccgo ツールチェーンとより密接に、かつ標準的な方法で連携できるようにするためのものです。
-
フラグ名の統一 (
-fgo-prefix->-fgo-pkgpath):- 以前は
gccgoにパッケージパスを渡す際に-fgo-prefixというフラグが使われていましたが、これはgccgoの内部的な命名規則や他のGCCフロントエンドとの整合性を考慮して-fgo-pkgpathに変更されました。この変更は、gccgoコンパイラ (gcメソッド内) とcgoツール (cgoメソッド内) の両方に適用されています。 gccgoPrefix関数は削除され、より汎用的なgccgoPkgpath関数が導入されました。gccgoPkgpathは、コマンドではないパッケージや強制的にライブラリとして扱われるパッケージに対してはp.ImportPathをそのまま返し、それ以外の場合は空文字列を返します。これにより、パッケージパスの概念がより直接的にgccgoに伝わるようになります。
- 以前は
-
GOPKGPATHマクロの定義:gccgoで.cまたは.s(Cまたはアセンブリ) ファイルをコンパイルする際、プリプロセッサマクロGOPKGPATHが定義されるようになりました。このマクロの値は、Goのパッケージパスをサニタイズ(非英数字をアンダースコアに変換)したものです。- これは
gccgcToolchain.asmおよびgccgcToolchain.ccメソッドで行われます。Cやアセンブリのコード内で#ifdef GOPKGPATHのような形でこのマクロを利用することで、Goのパッケージパスに基づいて条件付きコンパイルを行ったり、デバッグ情報を埋め込んだりすることが可能になります。これにより、GoとC/アセンブリの間の連携が強化されます。
-
相対インポートパスのサポート (
-fgo-relative-import-path):gccgcToolchain.gcメソッドにおいて、パッケージにp.localPrefixが設定されている場合、-fgo-relative-import-pathフラグがgccgoに渡されるようになりました。これは、Goモジュール内で相対的なインポートパスが使用されるシナリオに対応するためのものです。gccgoがこれらの相対パスを正しく解決できるようになり、より複雑なプロジェクト構造をサポートします。
-
オブジェクトファイル拡張子の統一 (
.[568]->.o):cmd/goは、gccgoを使用する場合、C (.c) およびアセンブリ (.s) ファイルのコンパイル結果として、Goの標準コンパイラが使用する.5,.6,.8ではなく、標準的な.o拡張子のオブジェクトファイルを生成するようになりました。- これは
build.goのobjExt変数の設定と、ccおよびasmメソッドの出力ファイル名生成ロジックの変更によって実現されています。この変更により、gccgoが生成するオブジェクトファイルが他のGCCツールや標準的なビルドシステムと互換性を持つようになり、ビルドプロセスの整合性が向上します。
-
リンカの
-Eフラグの追加:gccgcToolchain.ldメソッドにおいて、cgoファイルが使用されている (usesCgoが true) かつOSがLinux (goos == "linux") の場合、リンカに-Wl,-Eフラグが渡されるようになりました。- このフラグは、特にLinux環境で
cgoを介して動的にリンクされるCライブラリのシンボル解決を助けます。これにより、cgoを使用したGoプログラムが、実行時に必要な共有ライブラリを正しく見つけられるようになり、リンクエラーや実行時エラーのリスクが低減されます。
-
gccgoCleanPkgpath関数の導入:- 新しいヘルパー関数
gccgoCleanPkgpathが追加されました。この関数は、gccgoPkgpathから得られたパッケージパスを受け取り、英数字以外の文字をアンダースコア (_) に置換します。これは、パッケージパスをCプリプロセッサマクロ (-D) の値として安全に使用できるようにするためです。マクロ名やその値には特定の文字しか使用できないため、このサニタイズ処理は必須です。
- 新しいヘルパー関数
これらの変更は、cmd/go が gccgo をバックエンドとして使用する際のビルドの信頼性、互換性、および機能性を大幅に向上させるものです。
コアとなるコードの変更箇所
変更は主に src/cmd/go/build.go ファイルに集中しています。
-
オブジェクトファイル拡張子の決定ロジックの変更 (L745-760):
--- a/src/cmd/go/build.go +++ b/src/cmd/go/build.go @@ -745,8 +745,13 @@ func (b *builder) build(a *action) (err error) { } } + objExt := archChar + if _, ok := buildToolchain.(gccgcToolchain); ok { + objExt = "o" + } + for _, file := range cfiles { - out := file[:len(file)-len(".c")] + "." + archChar + out := file[:len(file)-len(".c")] + "." + objExt if err := buildToolchain.cc(b, a.p, obj, obj+out, file); err != nil { return err } @@ -755,7 +760,7 @@ func (b *builder) build(a *action) (err error) { // Assemble .s files. for _, file := range sfiles { - out := file[:len(file)-len(".s")] + "." + archChar + out := file[:len(file)-len(".s")] + "." + objExt if err := buildToolchain.asm(b, a.p, obj, obj+out, file); err != nil { return err }gccgcToolchainを使用する場合、オブジェクトファイルの拡張子をarchChar(例:5,6,8) から"o"に変更。 -
gccgcToolchain.gc(Goコンパイラ) のフラグ変更 (L1355-1364):--- a/src/cmd/go/build.go +++ b/src/cmd/go/build.go @@ -1355,8 +1360,11 @@ func (gccgcToolchain) gc(b *builder, p *Package, obj string, importArgs []string out := p.Name + ".o" ofile = obj + out gcargs := []string{"-g"} - if prefix := gccgoPrefix(p); prefix != "" { - gcargs = append(gcargs, "-fgo-prefix="+gccgoPrefix(p)) + if pkgpath := gccgoPkgpath(p); pkgpath != "" { + gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath) + } + if p.localPrefix != "" { + gcargs = append(gcargs, "-fgo-relative-import-path="+p.localPrefix) } args := stringList("gccgo", importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags) for _, f := range gofiles {-fgo-prefixを-fgo-pkgpathに変更し、p.localPrefixがあれば-fgo-relative-import-pathを追加。 -
gccgcToolchain.asm(アセンブラ) でのGOPKGPATH定義 (L1367-1373):--- a/src/cmd/go/build.go +++ b/src/cmd/go/build.go @@ -1367,7 +1375,11 @@ func (gccgcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error { func (gccgcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error { sfile = mkAbs(p.Dir, sfile) return b.run(p.Dir, p.ImportPath, "gccgo", "-I", obj, "-o", ofile, "-DGOOS_"+goos, "-DGOARCH_"+goarch, sfile) + defs := []string{"-DGOOS_" + goos, "-DGOARCH_" + goarch} + if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" { + defs = append(defs, `-DGOPKGPATH="`+pkgpath+`"`)\n+ } + return b.run(p.Dir, p.ImportPath, "gccgo", "-I", obj, "-o", ofile, defs, sfile) }.sファイルコンパイル時にGOPKGPATHマクロを定義。 -
gccgcToolchain.ld(リンカ) でのcgo検出と-Eフラグ追加 (L1392-1433):--- a/src/cmd/go/build.go +++ b/src/cmd/go/build.go @@ -1392,6 +1404,7 @@ func (tools gccgcToolchain) ld(b *builder, p *Package, out string, allactions [] sfiles := make(map[*Package][]string) ldflags := []string{} cgoldflags := []string{} + usesCgo := false for _, a := range allactions { if a.p != nil { if !a.p.Standard { @@ -1400,12 +1413,16 @@ func (tools gccgcToolchain) ld(b *builder, p *Package, out string, allactions [] } } cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...) + if len(a.p.CgoFiles) > 0 { + usesCgo = true + } if a.p.usesSwig() { sd := a.p.swigDir(&buildContext) for _, f := range stringList(a.p.SwigFiles, a.p.SwigCXXFiles) { soname := a.p.swigSoname(f) sfiles[a.p] = append(sfiles[a.p], filepath.Join(sd, soname)) } + usesCgo = true } } } @@ -1416,25 +1433,40 @@ func (tools gccgcToolchain) ld(b *builder, p *Package, out string, allactions [] ldflags = append(ldflags, sfiles...) } ldflags = append(ldflags, cgoldflags...) + if usesCgo && goos == "linux" { + ldflags = append(ldflags, "-Wl,-E") + } return b.run(".", p.ImportPath, "gccgo", "-o", out, buildGccgoflags, ofiles, "-Wl,-(", ldflags, "-Wl,)") }usesCgoフラグを導入し、cgoまたはswigが使用され、かつLinuxの場合にリンカに-Wl,-Eを追加。 -
gccgcToolchain.cc(Cコンパイラ) でのGOPKGPATH定義 (L1435-1444):--- a/src/cmd/go/build.go +++ b/src/cmd/go/build.go @@ -1435,8 +1444,11 @@ func (tools gccgcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error { func (gccgcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error { inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch)) cfile = mkAbs(p.Dir, cfile) + defs := []string{"-DGOOS_" + goos, "-DGOARCH_" + goarch} + if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" { + defs = append(defs, `-DGOPKGPATH="`+pkgpath+`"`)\n+ } return b.run(p.Dir, p.ImportPath, "gcc", "-Wall", "-g", - "-I", objdir, "-I", inc, "-o", ofile, - "-DGOOS_"+goos, "-DGOARCH_"+goarch, "-c", cfile) + "-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile) }.cファイルコンパイル時にGOPKGPATHマクロを定義。 -
gccgoPrefixの削除とgccgoPkgpath,gccgoCleanPkgpathの追加 (L1446-1466):--- a/src/cmd/go/build.go +++ b/src/cmd/go/build.go @@ -1446,14 +1455,23 @@ func (gccgcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error { return b.run(p.Dir, p.ImportPath, "gcc", "-Wall", "-g", "-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile) } -func gccgoPrefix(p *Package) string { - switch { - case p.build.IsCommand() && !p.forceLibrary: +func gccgoPkgpath(p *Package) string { + if p.build.IsCommand() && !p.forceLibrary { return "" - case p.fake: - return "fake_" + p.ImportPath } - return "go_" + p.ImportPath + return p.ImportPath +} + +func gccgoCleanPkgpath(p *Package) string { + clean := func(r rune) rune { + switch { + case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z', + '0' <= r && r <= '9': + return r + } + return '_' + } + return strings.Map(clean, gccgoPkgpath(p)) } // libgcc returns the filename for libgcc, as determined by invoking gcc withgccgoPrefix関数を削除し、gccgoPkgpathとgccgoCleanPkgpathを新しく定義。 -
builder.cgoでのフラグ変更とオブジェクト拡張子設定 (L1563-1570):--- a/src/cmd/go/build.go +++ b/src/cmd/go/build.go @@ -1563,8 +1595,8 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,\ if _, ok := buildToolchain.(gccgcToolchain); ok { cgoflags = append(cgoflags, "-gccgo") - if prefix := gccgoPrefix(p); prefix != "" { - cgoflags = append(cgoflags, "-gccgoprefix="+gccgoPrefix(p)) + if pkgpath := gccgoPkgpath(p); pkgpath != "" { + cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath) } objExt = "o" }-gccgoprefixを-gccgopkgpathに変更し、objExtを"o"に設定。
コアとなるコードの解説
オブジェクトファイル拡張子の統一
objExt := archChar
if _, ok := buildToolchain.(gccgcToolchain); ok {
objExt = "o"
}
// ...
out := file[:len(file)-len(".c")] + "." + objExt
// ...
out := file[:len(file)-len(".s")] + "." + objExt
この変更は、cmd/go が gccgo ツールチェーンを使用しているかどうかを buildToolchain.(gccgcToolchain) で確認し、もし gccgo であれば、C (.c) およびアセンブリ (.s) ファイルから生成されるオブジェクトファイルの拡張子を標準的な .o に設定します。Goの標準コンパイラ (gc) はアーキテクチャ固有の拡張子(例: .5, .6, .8)を使用しますが、gccgo はGCCの慣習に従うため、この統一は互換性にとって重要です。
gccgcToolchain.gc (Goコンパイラ) のフラグ変更
if pkgpath := gccgoPkgpath(p); pkgpath != "" {
gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath)
}
if p.localPrefix != "" {
gcargs = append(gcargs, "-fgo-relative-import-path="+p.localPrefix)
}
gccgo コンパイラを呼び出す際に渡す引数 (gcargs) が変更されました。
gccgoPkgpath(p)は、パッケージのインポートパスを返します。これが空でなければ、-fgo-pkgpath=フラグが追加されます。これは、gccgoがGoのパッケージパスを正しく認識し、内部的なシンボル名や依存関係の解決に利用できるようにするためです。以前の-fgo-prefixよりも、その意図が明確になりました。p.localPrefixは、Goモジュールにおける相対的なインポートパスのプレフィックスを示す可能性があります。これが存在する場合、-fgo-relative-import-path=フラグが追加され、gccgoが相対インポートを適切に処理できるようになります。
gccgcToolchain.asm および gccgcToolchain.cc での GOPKGPATH 定義
defs := []string{"-DGOOS_" + goos, "-DGOARCH_" + goarch}
if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
defs = append(defs, `-DGOPKGPATH="`+pkgpath+`"`)
}
return b.run(p.Dir, p.ImportPath, "gccgo", /* ... */, defs, sfile) // for .s files
// ...
return b.run(p.Dir, p.ImportPath, "gcc", /* ... */, defs, "-c", cfile) // for .c files
アセンブリ (.s) およびC (.c) ファイルをコンパイルする際、gccgoCleanPkgpath(p) でサニタイズされたGoのパッケージパスが、プリプロセッサマクロ GOPKGPATH として定義されます。例えば、パッケージパスが "github.com/foo/bar" であれば、GOPKGPATH は "github_com_foo_bar" のような値になります。これにより、Cやアセンブリのソースコード内で #ifdef GOPKGPATH や GOPKGPATH の値を利用して、Goのパッケージ情報に基づいた処理を行うことが可能になります。これは、GoとC/アセンブリの間のより深い連携を可能にします。
gccgcToolchain.ld (リンカ) での cgo 検出と -E フラグ追加
usesCgo := false
// ...
if len(a.p.CgoFiles) > 0 {
usesCgo = true
}
// ...
if a.p.usesSwig() {
// ...
usesCgo = true
}
// ...
if usesCgo && goos == "linux" {
ldflags = append(ldflags, "-Wl,-E")
}
このセクションでは、ビルド対象のパッケージが cgo ファイル (a.p.CgoFiles) を含んでいるか、または swig を使用しているか (a.p.usesSwig()) を usesCgo フラグで追跡します。
もし cgo または swig が使用されており、かつオペレーティングシステムがLinuxである場合、リンカに -Wl,-E フラグが追加されます。このフラグは、Linuxの動的リンカに対して、実行可能ファイルがロードされる際に環境変数 LD_PRELOAD や DT_RPATH/DT_RUNPATH で指定されたパスを検索対象に含めるように指示します。これは、cgo を使用してGoプログラムがCの共有ライブラリに依存する場合に、実行時のシンボル解決を確実に行うために非常に重要です。
gccgoPkgpath および gccgoCleanPkgpath 関数の導入
func gccgoPkgpath(p *Package) string {
if p.build.IsCommand() && !p.forceLibrary {
return ""
}
return p.ImportPath
}
func gccgoCleanPkgpath(p *Package) string {
clean := func(r rune) rune {
switch {
case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
'0' <= r && r <= '9':
return r
}
return '_'
}
return strings.Map(clean, gccgoPkgpath(p))
}
gccgoPkgpathは、与えられたGoパッケージpのインポートパスを返します。ただし、それがコマンドであり、かつ強制的にライブラリとして扱われていない場合は空文字列を返します。これは、実行可能ファイル自体には特定のパッケージパスが不要であるというgccgoのセマンティクスに合わせたものです。gccgoCleanPkgpathは、gccgoPkgpathから得られた文字列を受け取り、それを「クリーン」にします。具体的には、英数字以外のすべての文字をアンダースコア (_) に置換します。この関数は、パッケージパスをCプリプロセッサマクロ (-Dフラグで渡される値) の一部として使用する際に必要です。Cプリプロセッサマクロの名前や値には、特定の文字セットしか使用できないため、このサニタイズ処理が不可欠です。
builder.cgo でのフラグ変更とオブジェクト拡張子設定
if _, ok := buildToolchain.(gccgcToolchain); ok {
cgoflags = append(cgoflags, "-gccgo")
if pkgpath := gccgoPkgpath(p); pkgpath != "" {
cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
}
objExt = "o"
}
cgo ツールを呼び出す際にも、gccgo ツールチェーンが使用されている場合は、-gccgo フラグが追加されます。また、gccgoPkgpath から得られたパッケージパスが空でなければ、-gccgopkgpath= フラグが追加されます。これは、cgo が gccgo と連携してGoとCの間のバインディングを生成する際に、正しいパッケージパス情報を利用できるようにするためです。さらに、cgo が生成するオブジェクトファイルの拡張子も .o に設定されます。
これらの変更は、cmd/go が gccgo を利用する際のビルドプロセス全体にわたる整合性を高め、より堅牢で標準的なGoプログラムのビルドを可能にしています。
関連リンク
- https://golang.org/cl/6820064 (Gerrit Code Review)
参考にした情報源リンク
- Go言語公式ドキュメント (Go Command, cgo, build modesなど)
- GCCgo ドキュメント (特にコマンドラインオプションに関する情報)
- Linux man pages (ld, gccなど)
- Go言語のソースコード (特に
src/cmd/goディレクトリ) - Go言語のビルドシステムについて (一般的なGoのビルドに関する情報)
- GCCgoの概要 (GCCgoに関する公式ドキュメント)
- Cgoのドキュメント (Cgoに関する公式ブログ記事)
- Linuxの動的リンカに関する情報 (ld.so man page)
- GCCのリンカオプションに関する情報 (GCC Link Options)