[インデックス 1190] ファイルの概要
このコミットは、Go言語プロジェクトの初期段階におけるビルドシステムの一部変更を示しています。具体的には、src/lib/container/array/Makefile
ファイルが、gobuild
ツールによって新しく生成された内容に更新されています。これにより、array.a
というアーカイブ(静的ライブラリ)のビルドプロセスが調整され、よりモジュール化された方法でオブジェクトファイルが結合されるようになっています。
コミット
- コミットハッシュ:
93dcc2c248619ffa5cb512705ba92f34b966252b
- 作者: Robert Griesemer gri@golang.org
- コミット日時: Wed Nov 19 14:24:53 2008 -0800
- 変更ファイル:
src/lib/container/array/Makefile
- 変更行数: 9行追加、0行削除、2行変更 (合計9行の差分)
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/93dcc2c248619ffa5cb512705ba92f34b966252b
元コミット内容
new Makefile generated by gobuild
R=rsc
DELTA=9 (7 added, 0 deleted, 2 changed)
OCL=19613
CL=19613
変更の背景
このコミットは、Go言語の初期開発フェーズにおいて、ビルドシステムが進化していたことを示しています。コミットメッセージにある「new Makefile generated by gobuild
」という記述から、当時のGoプロジェクトではgobuild
というツールがMakefileを生成する役割を担っていたことが推測されます。
初期のGo言語は、現在のGo Modulesのような洗練されたビルドシステムを持っておらず、C言語のプロジェクトで一般的に使われるmake
ユーティリティとMakefileに大きく依存していました。gobuild
は、Goのソースコードから必要な依存関係を解決し、コンパイルとリンクのためのMakefileを自動生成することで、開発者が手動でMakefileを記述する手間を省き、ビルドプロセスを標準化しようとする試みだったと考えられます。
この変更の背景には、おそらく以下の目的があったと推測されます。
- ビルドプロセスの自動化と標準化: 手動でMakefileを管理するのではなく、ツールによって生成することで、一貫性のあるビルドプロセスを確立し、エラーを減らす。
- 依存関係の管理の改善:
gobuild
がGoのパッケージ構造を理解し、適切なオブジェクトファイルの依存関係をMakefileに反映させることで、ビルドの効率性と正確性を向上させる。 - 将来のビルドシステムへの移行準備:
gobuild
のようなツールによるMakefile生成は、後のGo Modulesやgo build
コマンドのような、より統合されたビルドツールへの過渡期的なステップであった可能性があります。
この特定の変更は、container/array
パッケージのビルド方法を調整し、おそらくはビルドの並列性や増分ビルドの効率を改善するためのものであったと考えられます。
前提知識の解説
MakefileとMakeユーティリティ
Makefile
は、プログラムのコンパイルやその他のタスクを自動化するためのルールを記述するファイルです。make
ユーティリティは、このMakefileを読み込み、記述されたルールに従ってコマンドを実行します。
- ターゲット (Target): 実行したいタスクの名前(例:
all
,clean
,array.a
)。 - 依存関係 (Prerequisites): ターゲットを生成するために必要なファイルや他のターゲット。
- レシピ (Recipe): ターゲットを生成するために実行されるコマンド。
例:
target: prerequisites
recipe
AR
コマンド
AR
(Archiver)コマンドは、Unix系システムで静的ライブラリ(アーカイブファイル)を作成、変更、抽出するために使用されるユーティリティです。静的ライブラリは、複数のオブジェクトファイル(.o
ファイル)を一つにまとめたもので、プログラムのリンク時に実行ファイルに直接組み込まれます。
ar grc <archive_name> <object_files>
:<object_files>
を<archive_name>
というアーカイブファイルに挿入(r
)、既存のメンバーを置き換え(r
)、アーカイブが存在しない場合は作成(c
)、シンボルテーブルを再構築(s
、g
はGNU arのデフォルト動作)。
Go言語の初期のビルドプロセスとgobuild
Go言語の初期(2008年頃)は、現在のgo build
コマンドのような統合されたビルドツールが存在しませんでした。代わりに、C言語のプロジェクトと同様に、make
とMakefileが主要なビルドメカニズムとして使用されていました。
gobuild
は、Goプロジェクトのソースコードを解析し、コンパイルとリンクに必要なMakefileを自動的に生成するツールでした。これは、Goのパッケージシステムと依存関係を理解し、それらをMakefileのルールに変換する役割を担っていました。gobuild
は、Go言語のビルドシステムが成熟するまでの過渡期的なツールであり、最終的にはgo build
コマンドにその機能が統合され、開発者が直接Makefileを扱う必要はなくなりました。
オブジェクトファイル (.o
ファイル)
オブジェクトファイルは、ソースコード(この場合はGo言語のコード)がコンパイラによって機械語に変換された中間ファイルです。これらはまだ実行可能なプログラムではありませんが、リンカによって他のオブジェクトファイルやライブラリと結合されて最終的な実行可能ファイルやライブラリが生成されます。
技術的詳細
このコミットにおけるMakefileの変更は、src/lib/container/array/Makefile
内のarray.a
という静的ライブラリのビルド方法を最適化しています。
変更前は、array.a
はa1
ターゲットに依存し、a1
は$(O1)
に含まれるarray.$O
とintarray.$O
の両方のオブジェクトファイルを一度にarray.a
にアーカイブしていました。
変更後は、array.a
のビルドプロセスがa1
とa2
という二つのサブターゲットに分割されています。
-
O1
とO2
の分離:O1
変数にはarray.$O
のみが含まれるようになりました。O2
変数にはintarray.$O
のみが含まれるようになりました。
-
array.a
ターゲットの変更:array.a
はa1
とa2
の両方に依存するようになりました。
-
a1
ターゲットの変更:a1
は$(O1)
(つまりarray.$O
)のみをarray.a
にアーカイブするようになりました。rm -f $(O1)
で一時ファイルを削除します。
-
a2
ターゲットの新規追加:a2
は$(O2)
(つまりintarray.$O
)をarray.a
にアーカイブするようになりました。rm -f $(O2)
で一時ファイルを削除します。- 注目すべきは、
a2
ターゲットの依存関係にa1
が追加されている点です。これは、a1
が先に実行され、array.a
が初期化された後にintarray.$O
が追加されることを保証します。
-
オブジェクトファイルの依存関係の変更:
$(O1)
(array.$O
)はnewpkg
に依存します。$(O2)
(intarray.$O
)はa1
に依存します。これは、intarray.$O
がコンパイルされる前にarray.$O
がアーカイブされることを意味します。
この変更の意図は、おそらく以下のいずれか、または複数の組み合わせです。
- 増分ビルドの改善:
array.$O
とintarray.$O
のどちらか一方だけが変更された場合に、必要な部分だけを再アーカイブすることで、ビルド時間を短縮する。 - ビルドプロセスの明確化: 各オブジェクトファイルがどのようにアーカイブに追加されるかをより明示的にする。
gobuild
の生成ロジックの反映:gobuild
がより洗練されたMakefileを生成するようになった結果、その新しいロジックが反映された。
特に、a2
がa1
に依存していることから、array.a
がまずarray.$O
で作成され、その後intarray.$O
が追加されるという順序が強制されています。これは、アーカイブの構造や、特定のオブジェクトファイルが先に処理される必要がある場合に重要となる可能性があります。
コアとなるコードの変更箇所
--- a/src/lib/container/array/Makefile
+++ b/src/lib/container/array/Makefile
@@ -33,18 +33,25 @@ coverage: packages
O1=\
array.$O\\\
+
+O2=\
intarray.$O\\\
-array.a: a1
+array.a: a1 a2
a1: $(O1)
- $(AR) grc array.a array.$O intarray.$O
+ $(AR) grc array.a array.$O
rm -f $(O1)
+a2: $(O2)
+ $(AR) grc array.a intarray.$O
+ rm -f $(O2)
+
newpkg: clean
$(AR) grc array.a
$(O1): newpkg
+$(O2): a1
nuke: clean
rm -f $(GOROOT)/pkg/array.a
コアとなるコードの解説
上記のdiffは、src/lib/container/array/Makefile
におけるarray.a
という静的ライブラリのビルド方法の変更を示しています。
-
O1
とO2
変数の定義の変更:- 変更前:
O1
にはarray.$O
とintarray.$O
の両方が含まれていました。 - 変更後:
O1
にはarray.$O
のみが含まれ、新たにO2
が定義され、intarray.$O
が含まれるようになりました。 - これは、ビルド対象のオブジェクトファイルを論理的に分割し、個別に処理するための準備です。
- 変更前:
-
array.a
ターゲットの依存関係の変更:- 変更前:
array.a
はa1
にのみ依存していました。 - 変更後:
array.a
はa1
とa2
の両方に依存するようになりました。 - これにより、
array.a
をビルドするためには、a1
とa2
の両方のターゲットが実行される必要があります。
- 変更前:
-
a1
ターゲットのレシピの変更:- 変更前:
a1
はarray.$O
とintarray.$O
の両方をarray.a
にアーカイブしていました。 - 変更後:
a1
はarray.$O
のみをarray.a
にアーカイブするようになりました。 $(AR) grc array.a array.$O
は、array.$O
をarray.a
というアーカイブファイルに追加(または新規作成)します。rm -f $(O1)
は、array.$O
のオブジェクトファイルを削除します。
- 変更前:
-
a2
ターゲットの新規追加:a2
は$(O2)
(つまりintarray.$O
)に依存します。$(AR) grc array.a intarray.$O
は、intarray.$O
を既存のarray.a
アーカイブに追加します。rm -f $(O2)
は、intarray.$O
のオブジェクトファイルを削除します。- 重要な点:
$(O2): a1
という行が追加されています。これは、intarray.$O
がコンパイルされる前にa1
ターゲットが完了している必要があることを示しています。つまり、array.$O
がarray.a
にアーカイブされた後に、intarray.$O
がアーカイブに追加されるという順序が強制されます。
この変更により、array.a
のビルドは以下の2段階で行われるようになります。
array.$O
がarray.a
にアーカイブされる(a1
ターゲット)。intarray.$O
がarray.a
にアーカイブされる(a2
ターゲット)。
これは、ビルドプロセスの粒度を細かくし、特定のオブジェクトファイルの追加順序を制御するためのものです。
関連リンク
- Go言語の初期の歴史に関する情報: https://go.dev/doc/history
make
ユーティリティの公式ドキュメント: https://www.gnu.org/software/make/manual/ar
コマンドのマニュアルページ(例:man ar
)
参考にした情報源リンク
- Go言語の公式ドキュメント
- GNU Makeの公式ドキュメント
- Unix/Linuxの
ar
コマンドに関するドキュメント - Go言語の初期のビルドシステムに関するコミュニティの議論やブログ記事 (具体的なURLは特定できませんでしたが、
gobuild
に関する言及は初期のGo関連の資料に見られます)
[インデックス 1190] ファイルの概要
このコミットは、Go言語プロジェクトの初期段階におけるビルドシステムの一部変更を示しています。具体的には、src/lib/container/array/Makefile
ファイルが、gobuild
ツールによって新しく生成された内容に更新されています。これにより、array.a
というアーカイブ(静的ライブラリ)のビルドプロセスが調整され、よりモジュール化された方法でオブジェクトファイルが結合されるようになっています。
コミット
- コミットハッシュ:
93dcc2c248619ffa5cb512705ba92f34b966252b
- 作者: Robert Griesemer gri@golang.org
- コミット日時: Wed Nov 19 14:24:53 2008 -0800
- 変更ファイル:
src/lib/container/array/Makefile
- 変更行数: 9行追加、0行削除、2行変更 (合計9行の差分)
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/93dcc2c248619ffa5cb512705ba92f34b966252b
元コミット内容
new Makefile generated by gobuild
R=rsc
DELTA=9 (7 added, 0 deleted, 2 changed)
OCL=19613
CL=19613
変更の背景
このコミットは、Go言語の初期開発フェーズにおいて、ビルドシステムが進化していたことを示しています。コミットメッセージにある「new Makefile generated by gobuild
」という記述から、当時のGoプロジェクトではgobuild
というツールがMakefileを生成する役割を担っていたことが推測されます。
初期のGo言語は、現在のGo Modulesのような洗練されたビルドシステムを持っておらず、C言語のプロジェクトで一般的に使われるmake
ユーティリティとMakefileに大きく依存していました。gobuild
は、Goのソースコードから必要な依存関係を解決し、コンパイルとリンクのためのMakefileを自動生成することで、開発者が手動でMakefileを記述する手間を省き、ビルドプロセスを標準化しようとする試みだったと考えられます。
この変更の背景には、おそらく以下の目的があったと推測されます。
- ビルドプロセスの自動化と標準化: 手動でMakefileを管理するのではなく、ツールによって生成することで、一貫性のあるビルドプロセスを確立し、エラーを減らす。
- 依存関係の管理の改善:
gobuild
がGoのパッケージ構造を理解し、適切なオブジェクトファイルの依存関係をMakefileに反映させることで、ビルドの効率性と正確性を向上させる。 - 将来のビルドシステムへの移行準備:
gobuild
のようなツールによるMakefile生成は、後のGo Modulesやgo build
コマンドのような、より統合されたビルドツールへの過渡期的なステップであった可能性があります。
この特定の変更は、container/array
パッケージのビルド方法を調整し、おそらくはビルドの並列性や増分ビルドの効率を改善するためのものであったと考えられます。
前提知識の解説
MakefileとMakeユーティリティ
Makefile
は、プログラムのコンパイルやその他のタスクを自動化するためのルールを記述するファイルです。make
ユーティリティは、このMakefileを読み込み、記述されたルールに従ってコマンドを実行します。
- ターゲット (Target): 実行したいタスクの名前(例:
all
,clean
,array.a
)。 - 依存関係 (Prerequisites): ターゲットを生成するために必要なファイルや他のターゲット。
- レシピ (Recipe): ターゲットを生成するために実行されるコマンド。
例:
target: prerequisites
recipe
AR
コマンド
AR
(Archiver)コマンドは、Unix系システムで静的ライブラリ(アーカイブファイル)を作成、変更、抽出するために使用されるユーティリティです。静的ライブラリは、複数のオブジェクトファイル(.o
ファイル)を一つにまとめたもので、プログラムのリンク時に実行ファイルに直接組み込まれます。
ar grc <archive_name> <object_files>
:<object_files>
を<archive_name>
というアーカイブファイルに挿入(r
)、既存のメンバーを置き換え(r
)、アーカイブが存在しない場合は作成(c
)、シンボルテーブルを再構築(s
、g
はGNU arのデフォルト動作)。
Go言語の初期のビルドプロセスとgobuild
Go言語の初期(2008年頃)は、現在のgo build
コマンドのような統合されたビルドツールが存在しませんでした。代わりに、C言語のプロジェクトと同様に、make
とMakefileが主要なビルドメカニズムとして使用されていました。
gobuild
は、Goプロジェクトのソースコードを解析し、コンパイルとリンクに必要なMakefileを自動的に生成するツールでした。これは、Goのパッケージシステムと依存関係を理解し、それらをMakefileのルールに変換する役割を担っていました。gobuild
は、Go言語のビルドシステムが成熟するまでの過渡期的なツールであり、最終的にはgo build
コマンドにその機能が統合され、開発者が直接Makefileを扱う必要はなくなりました。Web検索の結果からも、Go 1.11以降でGo Modulesが導入され、go build
コマンドがより強力な依存関係管理とビルド機能を提供するようになったことが分かります。
オブジェクトファイル (.o
ファイル)
オブジェクトファイルは、ソースコード(この場合はGo言語のコード)がコンパイラによって機械語に変換された中間ファイルです。これらはまだ実行可能なプログラムではありませんが、リンカによって他のオブジェクトファイルやライブラリと結合されて最終的な実行可能ファイルやライブラリが生成されます。
技術的詳細
このコミットにおけるMakefileの変更は、src/lib/container/array/Makefile
内のarray.a
という静的ライブラリのビルド方法を最適化しています。
変更前は、array.a
はa1
ターゲットに依存し、a1
は$(O1)
に含まれるarray.$O
とintarray.$O
の両方のオブジェクトファイルを一度にarray.a
にアーカイブしていました。
変更後は、array.a
のビルドプロセスがa1
とa2
という二つのサブターゲットに分割されています。
-
O1
とO2
の分離:O1
変数にはarray.$O
のみが含まれるようになりました。O2
変数にはintarray.$O
のみが含まれるようになりました。
-
array.a
ターゲットの変更:array.a
はa1
とa2
の両方に依存するようになりました。
-
a1
ターゲットの変更:a1
は$(O1)
(つまりarray.$O
)のみをarray.a
にアーカイブするようになりました。rm -f $(O1)
で一時ファイルを削除します。
-
a2
ターゲットの新規追加:a2
は$(O2)
(つまりintarray.$O
)をarray.a
にアーカイブするようになりました。rm -f $(O2)
で一時ファイルを削除します。- 注目すべきは、
a2
ターゲットの依存関係にa1
が追加されている点です。これは、a1
が先に実行され、array.a
が初期化された後にintarray.$O
が追加されることを保証します。
-
オブジェクトファイルの依存関係の変更:
$(O1)
(array.$O
)はnewpkg
に依存します。$(O2)
(intarray.$O
)はa1
に依存します。これは、intarray.$O
がコンパイルされる前にarray.$O
がアーカイブされることを意味します。
この変更の意図は、おそらく以下のいずれか、または複数の組み合わせです。
- 増分ビルドの改善:
array.$O
とintarray.$O
のどちらか一方だけが変更された場合に、必要な部分だけを再アーカイブすることで、ビルド時間を短縮する。 - ビルドプロセスの明確化: 各オブジェクトファイルがどのようにアーカイブに追加されるかをより明示的にする。
gobuild
の生成ロジックの反映:gobuild
がより洗練されたMakefileを生成するようになった結果、その新しいロジックが反映された。
特に、a2
がa1
に依存していることから、array.a
がまずarray.$O
で作成され、その後intarray.$O
が追加されるという順序が強制されています。これは、アーカイブの構造や、特定のオブジェクトファイルが先に処理される必要がある場合に重要となる可能性があります。
コアとなるコードの変更箇所
--- a/src/lib/container/array/Makefile
+++ b/src/lib/container/array/Makefile
@@ -33,18 +33,25 @@ coverage: packages
O1=\
array.$O\\\
+
+O2=\
intarray.$O\\\
-array.a: a1
+array.a: a1 a2
a1: $(O1)
- $(AR) grc array.a array.$O intarray.$O
+ $(AR) grc array.a array.$O
rm -f $(O1)
+a2: $(O2)
+ $(AR) grc array.a intarray.$O
+ rm -f $(O2)
+
newpkg: clean
$(AR) grc array.a
$(O1): newpkg
+$(O2): a1
nuke: clean
rm -f $(GOROOT)/pkg/array.a
コアとなるコードの解説
上記のdiffは、src/lib/container/array/Makefile
におけるarray.a
という静的ライブラリのビルド方法の変更を示しています。
-
O1
とO2
変数の定義の変更:- 変更前:
O1
にはarray.$O
とintarray.$O
の両方が含まれていました。 - 変更後:
O1
にはarray.$O
のみが含まれ、新たにO2
が定義され、intarray.$O
が含まれるようになりました。 - これは、ビルド対象のオブジェクトファイルを論理的に分割し、個別に処理するための準備です。
- 変更前:
-
array.a
ターゲットの依存関係の変更:- 変更前:
array.a
はa1
にのみ依存していました。 - 変更後:
array.a
はa1
とa2
の両方に依存するようになりました。 - これにより、
array.a
をビルドするためには、a1
とa2
の両方のターゲットが実行される必要があります。
- 変更前:
-
a1
ターゲットのレシピの変更:- 変更前:
a1
はarray.$O
とintarray.$O
の両方をarray.a
にアーカイブしていました。 - 変更後:
a1
はarray.$O
のみをarray.a
にアーカイブするようになりました。 $(AR) grc array.a array.$O
は、array.$O
をarray.a
というアーカイブファイルに追加(または新規作成)します。rm -f $(O1)
は、array.$O
のオブジェクトファイルを削除します。
- 変更前:
-
a2
ターゲットの新規追加:a2
は$(O2)
(つまりintarray.$O
)に依存します。$(AR) grc array.a intarray.$O
は、intarray.$O
を既存のarray.a
アーカイブに追加します。rm -f $(O2)
は、intarray.$O
のオブジェクトファイルを削除します。- 重要な点:
$(O2): a1
という行が追加されています。これは、intarray.$O
がコンパイルされる前にa1
ターゲットが完了している必要があることを示しています。つまり、array.$O
がarray.a
にアーカイブされた後に、intarray.$O
がアーカイブに追加されるという順序が強制されます。
この変更により、array.a
のビルドは以下の2段階で行われるようになります。
array.$O
がarray.a
にアーカイブされる(a1
ターゲット)。intarray.$O
がarray.a
にアーカイブされる(a2
ターゲット)。
これは、ビルドプロセスの粒度を細かくし、特定のオブジェクトファイルの追加順序を制御するためのものです。
関連リンク
- Go言語の初期の歴史に関する情報: https://go.dev/doc/history
make
ユーティリティの公式ドキュメント: https://www.gnu.org/software/make/manual/ar
コマンドのマニュアルページ(例:man ar
)
参考にした情報源リンク
- Go言語の公式ドキュメント
- GNU Makeの公式ドキュメント
- Unix/Linuxの
ar
コマンドに関するドキュメント - Web検索: "golang gobuild history" (Go言語のビルドシステムの歴史に関する情報)