[インデックス 18317] ファイルの概要
このコミットは、Go言語のコマンドラインツール cmd/go
におけるビルドプロセスに関する修正です。具体的には、gccgo
コンパイラを使用する際に、archChar
(アーキテクチャ特性を示す文字) の有効性チェックを不要にすることで、特定のビルドエラーを解消することを目的としています。
コミット
commit db37050f21466d4890dbe31362b7090a63ad3d8c
Author: Dave Cheney <dave@cheney.net>
Date: Wed Jan 22 12:19:11 2014 +1100
cmd/go: do not require a valid archChar when using -compiler gccgo
Fixes #7152.
R=iant, rsc, gobot
CC=golang-codereviews
https://golang.org/cl/54790044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/db37050f21466d4890dbe31362b7090a63ad3d8c
元コミット内容
cmd/go: do not require a valid archChar when using -compiler gccgo
このコミットは、cmd/go
ツールが gccgo
コンパイラを使用する場合に、有効な archChar
(アーキテクチャ文字) を要求しないようにする変更です。これにより、Goの標準コンパイラ (gc
) 以外のコンパイラを使用する際のビルドエラーが修正されます。
変更の背景
Go言語のビルドシステムでは、コンパイラがターゲットとするアーキテクチャを識別するために、内部的に archChar
と呼ばれる一文字の識別子を使用していました。例えば、amd64
アーキテクチャには '6'
、arm
には '5'
といった文字が割り当てられていました。
しかし、Goの標準コンパイラである gc
とは異なり、gccgo
はGCC (GNU Compiler Collection) のフロントエンドとして機能するため、Goのビルドシステムが期待する archChar
の概念に必ずしも厳密に従う必要がありませんでした。特に、gccgo
はGCCの広範なアーキテクチャサポートを利用するため、Goのビルドシステムが認識しない、あるいは archChar
を割り当てていないような特定のアーキテクチャをターゲットにする場合がありました。
この不一致が原因で、gccgo
を使用してGoプログラムをビルドしようとすると、cmd/go
が archChar
の有効性をチェックし、認識できないアーキテクチャに対してエラーを発生させていました。これは、gccgo
が実際にそのアーキテクチャでビルド可能であるにもかかわらず、cmd/go
の内部的な制約によってビルドが妨げられるという問題を引き起こしていました。
このコミットは、この問題を解決するために、gccgo
を使用する場合には archChar
の有効性チェックをスキップするように cmd/go
のロジックを変更しています。これにより、gccgo
の柔軟性を損なうことなく、より多くの環境でGoプログラムをビルドできるようになります。
前提知識の解説
Go言語のビルドシステム (cmd/go
)
cmd/go
は、Go言語のソースコードをコンパイル、テスト、インストール、フォーマットなどを行うための公式コマンドラインツールです。開発者がGoプロジェクトを管理する上で中心的な役割を担っています。go build
コマンドは、このツールの一部であり、Goのソースファイルを実行可能なバイナリに変換するプロセスを管理します。
Goコンパイラ: gc
と gccgo
Go言語には主に2つのコンパイラが存在します。
-
gc
(Go Compiler):- Go言語の公式かつ主要なコンパイラです。Goの配布物に含まれており、通常
go build
コマンドを実行するとデフォルトで使用されます。 - Goチームによって開発されており、Go言語の最新の機能や最適化が最も早く取り入れられます。
- Go 1.5以降、コンパイラ自体もGo言語で書かれており、自己ホスト型コンパイラとなっています。
- 高速なコンパイル時間と、Goプログラムに最適化されたランタイム性能が特徴です。
- Go言語の公式かつ主要なコンパイラです。Goの配布物に含まれており、通常
-
gccgo
:- GCC (GNU Compiler Collection) のフロントエンドとしてGo言語をサポートするコンパイラです。
- GCCの成熟した最適化技術を利用できるため、場合によっては
gc
よりも優れた実行時性能を持つバイナリを生成することがあります。 - GCCがサポートする幅広いアーキテクチャに対応できるため、
gc
が直接サポートしないようなニッチなアーキテクチャへのクロスコンパイルに特に有用です。 - ただし、
gc
に比べてGo言語の最新機能への対応が遅れる傾向があり、コンパイル時間も長くなることがあります。 go build
コマンドでgccgo
を使用するには、-compiler=gccgo
フラグを指定します。
archChar
(アーキテクチャ文字)
Goの初期のビルドシステムでは、コンパイラやリンカがターゲットとするCPUアーキテクチャを識別するために、archChar
と呼ばれる単一の文字を使用していました。これは、Goの内部ビルドツールが特定のアーキテクチャに特化したファイルや設定を扱う際に利用されていました。例えば、GOARCH=amd64
の場合は 6
、GOARCH=arm
の場合は 5
といった文字が対応していました。
この archChar
は、主に gc
ツールチェーンの内部的な整合性を保つために使用されていました。しかし、gccgo
のような外部のコンパイラを使用する場合、この archChar
の概念が必ずしも適用されない、あるいは cmd/go
が認識しない archChar
を持つアーキテクチャを gccgo
がサポートする、という状況が発生しました。
技術的詳細
このコミットの技術的な核心は、src/cmd/go/build.go
ファイル内の init
関数における archChar
の検証ロジックの変更にあります。
元のコードでは、build.ArchChar(goarch)
を呼び出して現在の GOARCH
(ターゲットアーキテクチャ) に対応する archChar
を取得し、もしエラーが発生した場合は fatalf
(致命的なエラーとしてプログラムを終了) していました。これは、gc
ツールチェーンを使用している場合に、認識できないアーキテクチャが指定された場合に早期にエラーを検出するためのものでした。
変更後のコードでは、このエラーハンドリングに条件分岐が追加されています。
if err != nil {
if _, isgc := buildToolchain.(gcToolchain); isgc {
fatalf("%s", err)
}
// archChar is only required for gcToolchain, if we're using
// another toolchain leave it blank.
archChar = ""
}
この変更のポイントは以下の通りです。
buildToolchain
の型チェック:buildToolchain.(gcToolchain)
という型アサーションを使用して、現在使用されているビルドツールチェーンがgcToolchain
(Goの標準コンパイラ) であるかどうかをチェックしています。isgc
はその結果が真偽値で格納されます。- 条件付きエラーハンドリング:
- もし
buildToolchain
がgcToolchain
であり (isgc
がtrue
)、かつarchChar
の取得でエラーが発生した場合は、これまで通りfatalf
を呼び出してプログラムを終了させます。これは、gc
コンパイラが有効なarchChar
を必要とするためです。 - しかし、もし
buildToolchain
がgcToolchain
ではない場合 (isgc
がfalse
)、つまりgccgo
のような別のツールチェーンが使用されている場合は、archChar
の取得でエラーが発生してもfatalf
を呼び出しません。
- もし
archChar
の空文字列への設定:gcToolchain
以外の場合でエラーが発生した際には、archChar
を空文字列 (""
) に設定しています。これは、archChar
がgcToolchain
のみに必要であり、他のツールチェーンではその値が不要であることを示しています。これにより、archChar
の有効性チェックがスキップされ、gccgo
が認識しないアーキテクチャでもビルドが続行できるようになります。
この修正により、gccgo
を使用する際に cmd/go
が archChar
の有効性を不必要に強制することがなくなり、gccgo
の柔軟なアーキテクチャサポートを最大限に活用できるようになりました。
コアとなるコードの変更箇所
src/cmd/go/build.go
ファイルの init
関数内、archChar
の初期化部分が変更されています。
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -350,7 +350,12 @@ func init() {
var err error
archChar, err = build.ArchChar(goarch)
if err != nil {
- fatalf("%s", err)
+ if _, isgc := buildToolchain.(gcToolchain); isgc {
+ fatalf("%s", err)
+ }
+ // archChar is only required for gcToolchain, if we're using
+ // another toolchain leave it blank.
+ archChar = ""
}
}
コアとなるコードの解説
この変更は、go build
コマンドが起動時に実行される init
関数の一部です。
-
archChar, err = build.ArchChar(goarch)
:build.ArchChar
関数は、現在のターゲットアーキテクチャ (goarch
、例: "amd64", "arm") に対応するarchChar
を取得しようとします。- もし
goarch
がbuild.ArchChar
が認識しないアーキテクチャである場合、err
にエラーが格納されます。
-
if err != nil { ... }
:archChar
の取得中にエラーが発生した場合の処理ブロックです。
-
if _, isgc := buildToolchain.(gcToolchain); isgc { ... }
:- この行が追加された主要なロジックです。
buildToolchain
は、現在cmd/go
が使用しているコンパイラツールチェーンを表す変数です。.(gcToolchain)
は型アサーションで、buildToolchain
がgcToolchain
型(Goの標準コンパイラ)であるかどうかをチェックします。isgc
は、その型アサーションが成功したかどうか(つまり、gc
コンパイラが使用されているか)を示す真偽値です。- もし
gc
コンパイラが使用されている場合 (isgc
がtrue
)、archChar
が必須であるため、エラー (fatalf("%s", err)
) を発生させてビルドを停止します。
-
// archChar is only required for gcToolchain, if we're using
:// another toolchain leave it blank.
- これはコメントで、
gcToolchain
以外の場合にarchChar
が不要であることを説明しています。
- これはコメントで、
-
archChar = ""
:gc
コンパイラ以外が使用されている場合(例:gccgo
)、archChar
の取得でエラーが発生しても、archChar
を空文字列に設定して処理を続行します。これにより、gccgo
がサポートするがgc
が認識しないアーキテクチャでもビルドが可能になります。
この修正により、cmd/go
は使用するコンパイラの種類に応じて archChar
の要件を動的に調整し、gccgo
のような代替コンパイラの柔軟性を尊重するようになりました。
関連リンク
- Go issue #7152 (このコミットが修正したとされる問題のトラッカー): 残念ながら、Goの公式GitHubリポジトリではこの番号のIssueは直接見つかりませんでした。これは古い内部トラッカーの番号であるか、または別のリポジトリのIssueである可能性があります。
- Go CL 54790044 (このコミットに対応するGo Code Review): https://golang.org/cl/54790044
参考にした情報源リンク
- Go言語の公式ドキュメント (特に
cmd/go
やgo/build
パッケージに関するもの) - GCCGoに関するドキュメントや記事
- Goのビルドプロセスに関する技術ブログや解説記事
- Stack Overflowなどの開発者コミュニティでの議論 (Goの
archChar
やコンパイラに関するもの)