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

[インデックス 11621] ファイルの概要

このコミットは、Go言語のビルドシステムにおけるARMアーキテクチャ(5lリンカ)のビルド問題を修正するものです。具体的には、cmd/distツールが5lリンカをビルドする際に、必要なリンカ関連のソースファイル(../ld/*.c)を正しく含めていなかった問題を解決しています。以前はワイルドカード../ld/*を使用していたため、特定の環境やビルドシステムにおいて必要なファイルが欠落し、ARMビルドが失敗する可能性がありました。このコミットでは、ワイルドカードを具体的なファイルリストに置き換えることで、この問題を恒久的に修正しています。

コミット

  • コミットハッシュ: a19ab9d1ccb038df9e564f10d2f688499c864698
  • 作者: Russ Cox (rsc@golang.org)
  • コミット日時: 2012年2月4日 土曜日 02:01:58 -0500

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/a19ab9d1ccb038df9e564f10d2f688499c864698

元コミット内容

cmd/dist: fix arm build

5l does not use the whole set of ld files
like the other linkers do.

TBR=golang-dev
CC=golang-dev
https://golang.org/cl/5629052

変更の背景

この変更は、Go言語のARMアーキテクチャ向けビルドプロセスにおける具体的な問題を解決するために行われました。当時のGoのビルドシステム(cmd/dist)は、各アーキテクチャ(例: 5lはARM、6lはx86-64、8lはx86-32)に対応するリンカをビルドする際に、必要なソースファイルを指定していました。

問題は、ARMアーキテクチャ用のリンカである5lのビルド設定において、リンカの共通部分を構成する../ld/ディレクトリ内のソースファイルをワイルドカード../ld/*で指定していた点にありました。このワイルドカードの展開が、特定のビルド環境やファイルシステムの挙動によっては、期待通りに全ての必要な.cファイルを含まない場合がありました。結果として、5lリンカのビルドが不完全になり、ARM環境でのGoプログラムのコンパイルやリンクが失敗するという問題が発生していました。

他のリンカ(6l, 8lなど)は、既に必要なldファイルを明示的にリストアップして指定しており、同様の問題は発生していませんでした。このコミットは、5lリンカのビルドプロセスも他のリンカと同様に、必要なファイルを明示的に指定することで、ワイルドカード展開の不確実性を排除し、ARMビルドの堅牢性を向上させることを目的としています。

前提知識の解説

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

Go言語の初期のビルドシステムは、cmd/distというツールによって管理されていました。これはGoのソースコードからコンパイラ、リンカ、アセンブラなどのツールチェイン自体をビルドするための重要なコンポーネントです。cmd/distは、Goのソースツリーのルートに位置し、make.bash(Unix系)やmake.bat(Windows)などのスクリプトから呼び出され、Goのツールチェイン全体をブートストラップビルドする役割を担っていました。 src/cmd/dist/build.cファイルは、このcmd/distツールの一部であり、Goの各ツール(コンパイラ、リンカなど)をビルドする際の依存関係やソースファイルのリストを定義していました。

Go言語のリンカ (5l, 6l, 8l)

Go言語の初期のツールチェインでは、各CPUアーキテクチャに対応するリンカが、そのアーキテクチャのビット数とGoのバージョン番号(Go 1.x時代)を組み合わせたような命名規則を持っていました。

  • 5l: ARMアーキテクチャ用のリンカ。Goの初期のバージョンでは、ARMプロセッサの命令セットが32ビットであることから「5」が使われていました。
  • 6l: x86-64(AMD64)アーキテクチャ用のリンカ。64ビットアーキテクチャであることから「6」が使われていました。
  • 8l: x86-32(386)アーキテクチャ用のリンカ。32ビットアーキテクチャであることから「8」が使われていました。 これらのリンカは、Goのコンパイラによって生成されたオブジェクトファイル(.oファイル)を結合し、実行可能なバイナリを生成する役割を担います。

ldファイル群

ldは「linker」の略であり、Goのリンカの共通部分を構成するソースファイル群が格納されているディレクトリです。これらのファイルは、リンカの基本的な機能(シンボルテーブルの処理、セクションの配置、リロケーションなど)を実装しており、特定のアーキテクチャに依存しない共通ロジックを提供します。 例えば、data.cはデータセクションの処理、elf.cはELF形式のバイナリ生成、go.cはGo固有のランタイム初期化、symtab.cはシンボルテーブルの管理など、リンカの様々な側面を扱います。

ワイルドカード (*) の問題

Unix系のシェルやビルドシステムにおいて、ワイルドカード*はファイル名の一致パターンとして非常に便利です。しかし、その展開はシェルやビルドツールの実装に依存し、予期せぬ挙動を引き起こすことがあります。特に、特定の順序でファイルが展開されなかったり、隠しファイル(.で始まるファイル)が含まれなかったり、あるいは将来的に追加されるファイルが自動的に含まれることを期待していても、ビルドシステムがそのワイルドカードを適切に解釈しない場合に問題が生じます。このケースでは、../ld/*../ld/ディレクトリ内の全ての必要な.cファイルを確実に含める保証がなかったことが問題の根源でした。

技術的詳細

このコミットの技術的な核心は、Goのビルドシステムが5lリンカをビルドする際に、リンカの共通ソースファイル群をどのように指定するかという点にあります。

src/cmd/dist/build.cファイル内には、Goの各ツール(コンパイラ、リンカ、アセンブラなど)をビルドするために必要なソースファイルのリストが定義されています。これは通常、static struct { ... }のような構造体配列として表現され、各ツールの名前と、それに紐づくソースファイルのパスのリストが含まれています。

変更前のcmd/5lリンカのエントリは以下のようになっていました。

{"cmd/5l", {
    "../ld/*", // ここがワイルドカード
    "enam.c",
}},

ここで"../ld/*"というワイルドカードが使用されていました。これは、src/cmd/distから見て相対パスである../ld/ディレクトリ内の全てのファイルをリンカのビルド対象として含めることを意図していました。しかし、前述の通り、このワイルドカードの展開が常に期待通りに行われるとは限りませんでした。特に、ビルドシステムがワイルドカードを適切に処理しない場合や、特定のファイルがリストから漏れる場合に、リンカのビルドが失敗したり、不完全なリンカが生成されたりする原因となっていました。

このコミットでは、このワイルドカードを、../ld/ディレクトリ内のリンカに必要な具体的な.cファイル群のリストに置き換えることで、この問題を解決しました。

変更後のcmd/5lリンカのエントリは以下のようになります。

{"cmd/5l", {
    "../ld/data.c",
    "../ld/elf.c",
    "../ld/go.c",
    "../ld/ldelf.c",
    "../ld/ldmacho.c",
    "../ld/ldpe.c",
    "../ld/lib.c",
    "../ld/symtab.c",
    "enam.c",
}},

このように明示的にファイルを列挙することで、ビルドシステムはワイルドカードの展開に依存することなく、必要な全てのソースファイルを確実にリンカのビルドに含めることができるようになります。これにより、ARMアーキテクチャにおける5lリンカのビルドの信頼性と堅牢性が大幅に向上しました。

この変更は、Goのビルドプロセスにおける「明示的な指定」の原則を強化するものであり、ワイルドカードのような暗黙的な依存関係の利用を避けることで、ビルドの再現性と安定性を高める典型的な改善策と言えます。

コアとなるコードの変更箇所

変更はsrc/cmd/dist/build.cファイルの一箇所のみです。

--- a/src/cmd/dist/build.c
+++ b/src/cmd/dist/build.c
@@ -429,7 +429,14 @@ static struct {
 		"$GOROOT/pkg/obj/libgc.a",
 	}},
 	{"cmd/5l", {
-		"../ld/*",
+		"../ld/data.c",
+		"../ld/elf.c",
+		"../ld/go.c",
+		"../ld/ldelf.c",
+		"../ld/ldmacho.c",
+		"../ld/ldpe.c",
+		"../ld/lib.c",
+		"../ld/symtab.c",
 		"enam.c",
 	}},
 	{"cmd/6l", {

コアとなるコードの解説

このコードスニペットは、src/cmd/dist/build.cファイル内の、Goのツールチェインを構成する各コマンドのビルド設定を定義している部分です。具体的には、cmd/5l(ARMリンカ)のエントリが変更されています。

  • 変更前:

    {"cmd/5l", {
        "../ld/*",
        "enam.c",
    }},
    

    この部分では、cmd/5lリンカをビルドするために、../ld/ディレクトリ内の全てのファイル(ワイルドカード*で指定)とenam.cファイルが必要であると定義されていました。

  • 変更後:

    {"cmd/5l", {
        "../ld/data.c",
        "../ld/elf.c",
        "../ld/go.c",
        "../ld/ldelf.c",
        "../ld/ldmacho.c",
        "../ld/ldpe.c",
        "../ld/lib.c",
        "../ld/symtab.c",
        "enam.c",
    }},
    

    変更後では、ワイルドカード"../ld/*"が削除され、代わりに../ld/ディレクトリ内のリンカに必要な具体的なC言語ソースファイルが一つずつ明示的にリストアップされています。これには、data.c, elf.c, go.c, ldelf.c, ldmacho.c, ldpe.c, lib.c, symtab.cが含まれます。enam.cは元々明示的に指定されていたため、変更後もそのまま残っています。

この変更により、cmd/distツールが5lリンカをビルドする際に、必要な全てのソースファイルを確実に取得できるようになり、ワイルドカード展開の不確実性に起因するARMビルドの問題が解消されました。これは、ビルドの信頼性と再現性を高めるための重要な修正です。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメントやソースコード(src/cmd/dist/src/cmd/5l/src/cmd/ld/ディレクトリ構造)
  • Go言語の初期のビルドシステムに関する一般的な知識
  • Go言語のリンカの命名規則(5l, 6l, 8l)に関する情報
  • ワイルドカード展開の挙動に関する一般的なプログラミング知識
  • Go言語のコミット履歴と関連する議論(Gerrit Code Review)# [インデックス 11621] ファイルの概要

このコミットは、Go言語のビルドシステムにおけるARMアーキテクチャ(5lリンカ)のビルド問題を修正するものです。具体的には、cmd/distツールが5lリンカをビルドする際に、必要なリンカ関連のソースファイル(../ld/*.c)を正しく含めていなかった問題を解決しています。以前はワイルドカード../ld/*を使用していたため、特定の環境やビルドシステムにおいて必要なファイルが欠落し、ARMビルドが失敗する可能性がありました。このコミットでは、ワイルドカードを具体的なファイルリストに置き換えることで、この問題を恒久的に修正しています。

コミット

  • コミットハッシュ: a19ab9d1ccb038df9e564f10d2f688499c864698
  • 作者: Russ Cox (rsc@golang.org)
  • コミット日時: 2012年2月4日 土曜日 02:01:58 -0500

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/a19ab9d1ccb038df9e564f10d2f688499c864698

元コミット内容

cmd/dist: fix arm build

5l does not use the whole set of ld files
like the other linkers do.

TBR=golang-dev
CC=golang-dev
https://golang.org/cl/5629052

変更の背景

この変更は、Go言語のARMアーキテクチャ向けビルドプロセスにおける具体的な問題を解決するために行われました。当時のGoのビルドシステム(cmd/dist)は、各アーキテクチャ(例: 5lはARM、6lはx86-64、8lはx86-32)に対応するリンカをビルドする際に、必要なソースファイルを指定していました。

問題は、ARMアーキテクチャ用のリンカである5lのビルド設定において、リンカの共通部分を構成する../ld/ディレクトリ内のソースファイルをワイルドカード../ld/*で指定していた点にありました。このワイルドカードの展開が、特定のビルド環境やファイルシステムの挙動によっては、期待通りに全ての必要な.cファイルを含まない場合がありました。結果として、5lリンカのビルドが不完全になり、ARM環境でのGoプログラムのコンパイルやリンクが失敗するという問題が発生していました。

他のリンカ(6l, 8lなど)は、既に必要なldファイルを明示的にリストアップして指定しており、同様の問題は発生していませんでした。このコミットは、5lリンカのビルドプロセスも他のリンカと同様に、必要なファイルを明示的に指定することで、ワイルドカード展開の不確実性を排除し、ARMビルドの堅牢性を向上させることを目的としています。

前提知識の解説

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

Go言語の初期のビルドシステムは、cmd/distというツールによって管理されていました。これはGoのソースコードからコンパイラ、リンカ、アセンブラなどのツールチェイン自体をビルドするための重要なコンポーネントです。cmd/distは、Goのソースツリーのルートに位置し、make.bash(Unix系)やmake.bat(Windows)などのスクリプトから呼び出され、Goのツールチェイン全体をブートストラップビルドする役割を担っていました。 src/cmd/dist/build.cファイルは、このcmd/distツールの一部であり、Goの各ツール(コンパイラ、リンカなど)をビルドする際の依存関係やソースファイルのリストを定義していました。

Go言語のリンカ (5l, 6l, 8l)

Go言語の初期のツールチェインでは、各CPUアーキテクチャに対応するリンカが、そのアーキテクチャのビット数とGoのバージョン番号(Go 1.x時代)を組み合わせたような命名規則を持っていました。

  • 5l: ARMアーキテクチャ用のリンカ。Goの初期のバージョンでは、ARMプロセッサの命令セットが32ビットであることから「5」が使われていました。
  • 6l: x86-64(AMD64)アーキテクチャ用のリンカ。64ビットアーキテクチャであることから「6」が使われていました。
  • 8l: x86-32(386)アーキテクチャ用のリンカ。32ビットアーキテクチャであることから「8」が使われていました。 これらのリンカは、Goのコンパイラによって生成されたオブジェクトファイル(.oファイル)を結合し、実行可能なバイナリを生成する役割を担います。

ldファイル群

ldは「linker」の略であり、Goのリンカの共通部分を構成するソースファイル群が格納されているディレクトリです。これらのファイルは、リンカの基本的な機能(シンボルテーブルの処理、セクションの配置、リロケーションなど)を実装しており、特定のアーキテクチャに依存しない共通ロジックを提供します。 例えば、data.cはデータセクションの処理、elf.cはELF形式のバイナリ生成、go.cはGo固有のランタイム初期化、symtab.cはシンボルテーブルの管理など、リンカの様々な側面を扱います。

ワイルドカード (*) の問題

Unix系のシェルやビルドシステムにおいて、ワイルドカード*はファイル名の一致パターンとして非常に便利です。しかし、その展開はシェルやビルドツールの実装に依存し、予期せぬ挙動を引き起こすことがあります。特に、特定の順序でファイルが展開されなかったり、隠しファイル(.で始まるファイル)が含まれなかったり、あるいは将来的に追加されるファイルが自動的に含まれることを期待していても、ビルドシステムがそのワイルドカードを適切に解釈しない場合に問題が生じます。このケースでは、../ld/*../ld/ディレクトリ内の全ての必要な.cファイルを確実に含める保証がなかったことが問題の根源でした。

技術的詳細

このコミットの技術的な核心は、Goのビルドシステムが5lリンカをビルドする際に、リンカの共通ソースファイル群をどのように指定するかという点にあります。

src/cmd/dist/build.cファイル内には、Goの各ツール(コンパイラ、リンカ、アセンブラなど)をビルドするために必要なソースファイルのリストが定義されています。これは通常、static struct { ... }のような構造体配列として表現され、各ツールの名前と、それに紐づくソースファイルのパスのリストが含まれています。

変更前のcmd/5lリンカのエントリは以下のようになっていました。

{"cmd/5l", {
    "../ld/*", // ここがワイルドカード
    "enam.c",
}},

ここで"../ld/*"というワイルドカードが使用されていました。これは、src/cmd/distから見て相対パスである../ld/ディレクトリ内の全てのファイルをリンカのビルド対象として含めることを意図していました。しかし、前述の通り、このワイルドカードの展開が常に期待通りに行われるとは限りませんでした。特に、ビルドシステムがワイルドカードを適切に処理しない場合や、特定のファイルがリストから漏れる場合に、リンカのビルドが失敗したり、不完全なリンカが生成されたりする原因となっていました。

このコミットでは、このワイルドカードを、../ld/ディレクトリ内のリンカに必要な具体的な.cファイル群のリストに置き換えることで、この問題を解決しました。

変更後のcmd/5lリンカのエントリは以下のようになります。

{"cmd/5l", {
    "../ld/data.c",
    "../ld/elf.c",
    "../ld/go.c",
    "../ld/ldelf.c",
    "../ld/ldmacho.c",
    "../ld/ldpe.c",
    "../ld/lib.c",
    "../ld/symtab.c",
    "enam.c",
}},

このように明示的にファイルを列挙することで、ビルドシステムはワイルドカードの展開に依存することなく、必要な全てのソースファイルを確実にリンカのビルドに含めることができるようになります。これにより、ARMアーキテクチャにおける5lリンカのビルドの信頼性と堅牢性が大幅に向上しました。

この変更は、Goのビルドプロセスにおける「明示的な指定」の原則を強化するものであり、ワイルドカードのような暗黙的な依存関係の利用を避けることで、ビルドの再現性と安定性を高める典型的な改善策と言えます。

コアとなるコードの変更箇所

変更はsrc/cmd/dist/build.cファイルの一箇所のみです。

--- a/src/cmd/dist/build.c
+++ b/src/cmd/dist/build.c
@@ -429,7 +429,14 @@ static struct {
 		"$GOROOT/pkg/obj/libgc.a",
 	}},
 	{"cmd/5l", {
-		"../ld/*",
+		"../ld/data.c",
+		"../ld/elf.c",
+		"../ld/go.c",
+		"../ld/ldelf.c",
+		"../ld/ldmacho.c",
+		"../ld/ldpe.c",
+		"../ld/lib.c",
+		"../ld/symtab.c",
 		"enam.c",
 	}},
 	{"cmd/6l", {

コアとなるコードの解説

このコードスニペットは、src/cmd/dist/build.cファイル内の、Goのツールチェインを構成する各コマンドのビルド設定を定義している部分です。具体的には、cmd/5l(ARMリンカ)のエントリが変更されています。

  • 変更前:

    {"cmd/5l", {
        "../ld/*",
        "enam.c",
    }},
    

    この部分では、cmd/5lリンカをビルドするために、../ld/ディレクトリ内の全てのファイル(ワイルドカード*で指定)とenam.cファイルが必要であると定義されていました。

  • 変更後:

    {"cmd/5l", {
        "../ld/data.c",
        "../ld/elf.c",
        "../ld/go.c",
        "../ld/ldelf.c",
        "../ld/ldmacho.c",
        "../ld/ldpe.c",
        "../ld/lib.c",
        "../ld/symtab.c",
        "enam.c",
    }},
    

    変更後では、ワイルドカード"../ld/*"が削除され、代わりに../ld/ディレクトリ内のリンカに必要な具体的なC言語ソースファイルが一つずつ明示的にリストアップされています。これには、data.c, elf.c, go.c, ldelf.c, ldmacho.c, ldpe.c, lib.c, symtab.cが含まれます。enam.cは元々明示的に指定されていたため、変更後もそのまま残っています。

この変更により、cmd/distツールが5lリンカをビルドする際に、必要な全てのソースファイルを確実に取得できるようになり、ワイルドカード展開の不確実性に起因するARMビルドの問題が解消されました。これは、ビルドの信頼性と再現性を高めるための重要な修正です。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメントやソースコード(src/cmd/dist/src/cmd/5l/src/cmd/ld/ディレクトリ構造)
  • Go言語の初期のビルドシステムに関する一般的な知識
  • Go言語のリンカの命名規則(5l, 6l, 8l)に関する情報
  • ワイルドカード展開の挙動に関する一般的なプログラミング知識
  • Go言語のコミット履歴と関連する議論(Gerrit Code Review)