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

[インデックス 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を記述する手間を省き、ビルドプロセスを標準化しようとする試みだったと考えられます。

この変更の背景には、おそらく以下の目的があったと推測されます。

  1. ビルドプロセスの自動化と標準化: 手動でMakefileを管理するのではなく、ツールによって生成することで、一貫性のあるビルドプロセスを確立し、エラーを減らす。
  2. 依存関係の管理の改善: gobuildがGoのパッケージ構造を理解し、適切なオブジェクトファイルの依存関係をMakefileに反映させることで、ビルドの効率性と正確性を向上させる。
  3. 将来のビルドシステムへの移行準備: 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)、シンボルテーブルを再構築(sgは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.aa1ターゲットに依存し、a1$(O1)に含まれるarray.$Ointarray.$Oの両方のオブジェクトファイルを一度にarray.aにアーカイブしていました。

変更後は、array.aのビルドプロセスがa1a2という二つのサブターゲットに分割されています。

  1. O1O2の分離:

    • O1変数にはarray.$Oのみが含まれるようになりました。
    • O2変数にはintarray.$Oのみが含まれるようになりました。
  2. array.aターゲットの変更:

    • array.aa1a2の両方に依存するようになりました。
  3. a1ターゲットの変更:

    • a1$(O1)(つまりarray.$O)のみをarray.aにアーカイブするようになりました。
    • rm -f $(O1)で一時ファイルを削除します。
  4. a2ターゲットの新規追加:

    • a2$(O2)(つまりintarray.$O)をarray.aにアーカイブするようになりました。
    • rm -f $(O2)で一時ファイルを削除します。
    • 注目すべきは、a2ターゲットの依存関係にa1が追加されている点です。これは、a1が先に実行され、array.aが初期化された後にintarray.$Oが追加されることを保証します。
  5. オブジェクトファイルの依存関係の変更:

    • $(O1)array.$O)はnewpkgに依存します。
    • $(O2)intarray.$O)はa1に依存します。これは、intarray.$Oがコンパイルされる前にarray.$Oがアーカイブされることを意味します。

この変更の意図は、おそらく以下のいずれか、または複数の組み合わせです。

  • 増分ビルドの改善: array.$Ointarray.$Oのどちらか一方だけが変更された場合に、必要な部分だけを再アーカイブすることで、ビルド時間を短縮する。
  • ビルドプロセスの明確化: 各オブジェクトファイルがどのようにアーカイブに追加されるかをより明示的にする。
  • gobuildの生成ロジックの反映: gobuildがより洗練されたMakefileを生成するようになった結果、その新しいロジックが反映された。

特に、a2a1に依存していることから、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という静的ライブラリのビルド方法の変更を示しています。

  1. O1O2変数の定義の変更:

    • 変更前: O1にはarray.$Ointarray.$Oの両方が含まれていました。
    • 変更後: O1にはarray.$Oのみが含まれ、新たにO2が定義され、intarray.$Oが含まれるようになりました。
    • これは、ビルド対象のオブジェクトファイルを論理的に分割し、個別に処理するための準備です。
  2. array.aターゲットの依存関係の変更:

    • 変更前: array.aa1にのみ依存していました。
    • 変更後: array.aa1a2の両方に依存するようになりました。
    • これにより、array.aをビルドするためには、a1a2の両方のターゲットが実行される必要があります。
  3. a1ターゲットのレシピの変更:

    • 変更前: a1array.$Ointarray.$Oの両方をarray.aにアーカイブしていました。
    • 変更後: a1array.$Oのみをarray.aにアーカイブするようになりました。
    • $(AR) grc array.a array.$Oは、array.$Oarray.aというアーカイブファイルに追加(または新規作成)します。
    • rm -f $(O1)は、array.$Oのオブジェクトファイルを削除します。
  4. 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.$Oarray.aにアーカイブされた後に、intarray.$Oがアーカイブに追加されるという順序が強制されます。

この変更により、array.aのビルドは以下の2段階で行われるようになります。

  1. array.$Oarray.aにアーカイブされる(a1ターゲット)。
  2. intarray.$Oarray.aにアーカイブされる(a2ターゲット)。

これは、ビルドプロセスの粒度を細かくし、特定のオブジェクトファイルの追加順序を制御するためのものです。

関連リンク

参考にした情報源リンク

  • 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を記述する手間を省き、ビルドプロセスを標準化しようとする試みだったと考えられます。

この変更の背景には、おそらく以下の目的があったと推測されます。

  1. ビルドプロセスの自動化と標準化: 手動でMakefileを管理するのではなく、ツールによって生成することで、一貫性のあるビルドプロセスを確立し、エラーを減らす。
  2. 依存関係の管理の改善: gobuildがGoのパッケージ構造を理解し、適切なオブジェクトファイルの依存関係をMakefileに反映させることで、ビルドの効率性と正確性を向上させる。
  3. 将来のビルドシステムへの移行準備: 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)、シンボルテーブルを再構築(sgは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.aa1ターゲットに依存し、a1$(O1)に含まれるarray.$Ointarray.$Oの両方のオブジェクトファイルを一度にarray.aにアーカイブしていました。

変更後は、array.aのビルドプロセスがa1a2という二つのサブターゲットに分割されています。

  1. O1O2の分離:

    • O1変数にはarray.$Oのみが含まれるようになりました。
    • O2変数にはintarray.$Oのみが含まれるようになりました。
  2. array.aターゲットの変更:

    • array.aa1a2の両方に依存するようになりました。
  3. a1ターゲットの変更:

    • a1$(O1)(つまりarray.$O)のみをarray.aにアーカイブするようになりました。
    • rm -f $(O1)で一時ファイルを削除します。
  4. a2ターゲットの新規追加:

    • a2$(O2)(つまりintarray.$O)をarray.aにアーカイブするようになりました。
    • rm -f $(O2)で一時ファイルを削除します。
    • 注目すべきは、a2ターゲットの依存関係にa1が追加されている点です。これは、a1が先に実行され、array.aが初期化された後にintarray.$Oが追加されることを保証します。
  5. オブジェクトファイルの依存関係の変更:

    • $(O1)array.$O)はnewpkgに依存します。
    • $(O2)intarray.$O)はa1に依存します。これは、intarray.$Oがコンパイルされる前にarray.$Oがアーカイブされることを意味します。

この変更の意図は、おそらく以下のいずれか、または複数の組み合わせです。

  • 増分ビルドの改善: array.$Ointarray.$Oのどちらか一方だけが変更された場合に、必要な部分だけを再アーカイブすることで、ビルド時間を短縮する。
  • ビルドプロセスの明確化: 各オブジェクトファイルがどのようにアーカイブに追加されるかをより明示的にする。
  • gobuildの生成ロジックの反映: gobuildがより洗練されたMakefileを生成するようになった結果、その新しいロジックが反映された。

特に、a2a1に依存していることから、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という静的ライブラリのビルド方法の変更を示しています。

  1. O1O2変数の定義の変更:

    • 変更前: O1にはarray.$Ointarray.$Oの両方が含まれていました。
    • 変更後: O1にはarray.$Oのみが含まれ、新たにO2が定義され、intarray.$Oが含まれるようになりました。
    • これは、ビルド対象のオブジェクトファイルを論理的に分割し、個別に処理するための準備です。
  2. array.aターゲットの依存関係の変更:

    • 変更前: array.aa1にのみ依存していました。
    • 変更後: array.aa1a2の両方に依存するようになりました。
    • これにより、array.aをビルドするためには、a1a2の両方のターゲットが実行される必要があります。
  3. a1ターゲットのレシピの変更:

    • 変更前: a1array.$Ointarray.$Oの両方をarray.aにアーカイブしていました。
    • 変更後: a1array.$Oのみをarray.aにアーカイブするようになりました。
    • $(AR) grc array.a array.$Oは、array.$Oarray.aというアーカイブファイルに追加(または新規作成)します。
    • rm -f $(O1)は、array.$Oのオブジェクトファイルを削除します。
  4. 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.$Oarray.aにアーカイブされた後に、intarray.$Oがアーカイブに追加されるという順序が強制されます。

この変更により、array.aのビルドは以下の2段階で行われるようになります。

  1. array.$Oarray.aにアーカイブされる(a1ターゲット)。
  2. intarray.$Oarray.aにアーカイブされる(a2ターゲット)。

これは、ビルドプロセスの粒度を細かくし、特定のオブジェクトファイルの追加順序を制御するためのものです。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • GNU Makeの公式ドキュメント
  • Unix/Linuxのarコマンドに関するドキュメント
  • Web検索: "golang gobuild history" (Go言語のビルドシステムの歴史に関する情報)