Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 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/goarchChar の有効性をチェックし、認識できないアーキテクチャに対してエラーを発生させていました。これは、gccgo が実際にそのアーキテクチャでビルド可能であるにもかかわらず、cmd/go の内部的な制約によってビルドが妨げられるという問題を引き起こしていました。

このコミットは、この問題を解決するために、gccgo を使用する場合には archChar の有効性チェックをスキップするように cmd/go のロジックを変更しています。これにより、gccgo の柔軟性を損なうことなく、より多くの環境でGoプログラムをビルドできるようになります。

前提知識の解説

Go言語のビルドシステム (cmd/go)

cmd/go は、Go言語のソースコードをコンパイル、テスト、インストール、フォーマットなどを行うための公式コマンドラインツールです。開発者がGoプロジェクトを管理する上で中心的な役割を担っています。go build コマンドは、このツールの一部であり、Goのソースファイルを実行可能なバイナリに変換するプロセスを管理します。

Goコンパイラ: gcgccgo

Go言語には主に2つのコンパイラが存在します。

  1. gc (Go Compiler):

    • Go言語の公式かつ主要なコンパイラです。Goの配布物に含まれており、通常 go build コマンドを実行するとデフォルトで使用されます。
    • Goチームによって開発されており、Go言語の最新の機能や最適化が最も早く取り入れられます。
    • Go 1.5以降、コンパイラ自体もGo言語で書かれており、自己ホスト型コンパイラとなっています。
    • 高速なコンパイル時間と、Goプログラムに最適化されたランタイム性能が特徴です。
  2. gccgo:

    • GCC (GNU Compiler Collection) のフロントエンドとしてGo言語をサポートするコンパイラです。
    • GCCの成熟した最適化技術を利用できるため、場合によっては gc よりも優れた実行時性能を持つバイナリを生成することがあります。
    • GCCがサポートする幅広いアーキテクチャに対応できるため、gc が直接サポートしないようなニッチなアーキテクチャへのクロスコンパイルに特に有用です。
    • ただし、gc に比べてGo言語の最新機能への対応が遅れる傾向があり、コンパイル時間も長くなることがあります。
    • go build コマンドで gccgo を使用するには、-compiler=gccgo フラグを指定します。

archChar (アーキテクチャ文字)

Goの初期のビルドシステムでは、コンパイラやリンカがターゲットとするCPUアーキテクチャを識別するために、archChar と呼ばれる単一の文字を使用していました。これは、Goの内部ビルドツールが特定のアーキテクチャに特化したファイルや設定を扱う際に利用されていました。例えば、GOARCH=amd64 の場合は 6GOARCH=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 = ""
}

この変更のポイントは以下の通りです。

  1. buildToolchain の型チェック: buildToolchain.(gcToolchain) という型アサーションを使用して、現在使用されているビルドツールチェーンが gcToolchain (Goの標準コンパイラ) であるかどうかをチェックしています。isgc はその結果が真偽値で格納されます。
  2. 条件付きエラーハンドリング:
    • もし buildToolchaingcToolchain であり (isgctrue)、かつ archChar の取得でエラーが発生した場合は、これまで通り fatalf を呼び出してプログラムを終了させます。これは、gc コンパイラが有効な archChar を必要とするためです。
    • しかし、もし buildToolchaingcToolchain ではない場合 (isgcfalse)、つまり gccgo のような別のツールチェーンが使用されている場合は、archChar の取得でエラーが発生しても fatalf を呼び出しません。
  3. archChar の空文字列への設定: gcToolchain 以外の場合でエラーが発生した際には、archChar を空文字列 ("") に設定しています。これは、archChargcToolchain のみに必要であり、他のツールチェーンではその値が不要であることを示しています。これにより、archChar の有効性チェックがスキップされ、gccgo が認識しないアーキテクチャでもビルドが続行できるようになります。

この修正により、gccgo を使用する際に cmd/goarchChar の有効性を不必要に強制することがなくなり、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 関数の一部です。

  1. archChar, err = build.ArchChar(goarch):

    • build.ArchChar 関数は、現在のターゲットアーキテクチャ (goarch、例: "amd64", "arm") に対応する archChar を取得しようとします。
    • もし goarchbuild.ArchChar が認識しないアーキテクチャである場合、err にエラーが格納されます。
  2. if err != nil { ... }:

    • archChar の取得中にエラーが発生した場合の処理ブロックです。
  3. if _, isgc := buildToolchain.(gcToolchain); isgc { ... }:

    • この行が追加された主要なロジックです。
    • buildToolchain は、現在 cmd/go が使用しているコンパイラツールチェーンを表す変数です。
    • .(gcToolchain) は型アサーションで、buildToolchaingcToolchain 型(Goの標準コンパイラ)であるかどうかをチェックします。
    • isgc は、その型アサーションが成功したかどうか(つまり、gc コンパイラが使用されているか)を示す真偽値です。
    • もし gc コンパイラが使用されている場合 (isgctrue)、archChar が必須であるため、エラー (fatalf("%s", err)) を発生させてビルドを停止します。
  4. // archChar is only required for gcToolchain, if we're using: // another toolchain leave it blank.

    • これはコメントで、gcToolchain 以外の場合に archChar が不要であることを説明しています。
  5. 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/gogo/build パッケージに関するもの)
  • GCCGoに関するドキュメントや記事
  • Goのビルドプロセスに関する技術ブログや解説記事
  • Stack Overflowなどの開発者コミュニティでの議論 (Goの archChar やコンパイラに関するもの)