[インデックス 1215] ファイルの概要
このコミットは、Go言語プロジェクトのsrc/lib
ディレクトリにおけるビルドシステムを、従来のシェルスクリプト(make.bash
とclean.bash
)からMakefile
ベースのシステムへと移行するものです。これにより、ビルドプロセスの構造化と、特にmake bufio.install
のような個別のコンポーネントのインストールをより柔軟に制御できるようになりました。
コミット
commit 5a863a4ece7e23f77e89cc4c9420df73e5d786ae
Author: Russ Cox <rsc@golang.org>
Date: Fri Nov 21 12:36:16 2008 -0800
convert lib to a Makefile,
mainly for "make bufio.install".
R=r
DELTA=144 (80 added, 62 deleted, 2 changed)
OCL=19760
CL=19799
---
src/clean.bash | 2 +-\n src/lib/Makefile | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++\n src/lib/clean.bash | 13 ---------\n src/lib/make.bash | 56 ------------------------------------\n src/make.bash | 2 +-\n 5 files changed, 86 insertions(+), 71 deletions(-)\n
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/5a863a4ece7e23f77e89cc4c9420df73e5d786ae
元コミット内容
このコミットの目的は、「lib
ディレクトリをMakefile
に変換すること」であり、その主な動機は「make bufio.install
」のような特定のインストールコマンドを可能にすることです。これは、lib
ディレクトリ内のライブラリのビルドとインストールプロセスを、より構造化されたMakefile
システムに移行し、個々のコンポーネントに対するよりきめ細かい制御を可能にすることを示しています。
変更の背景
このコミットは2008年11月に行われており、Go言語がまだ初期開発段階にあったことを示しています。当時のGoプロジェクトのビルドシステムは、おそらくシンプルなシェルスクリプトに依存していました。しかし、プロジェクトが成長し、より多くのライブラリやパッケージが追加されるにつれて、シェルスクリプトベースのビルドシステムでは以下のような課題が生じていたと考えられます。
- 依存関係の管理の複雑さ: シェルスクリプトでは、パッケージ間の複雑なビルド依存関係を効率的かつ正確に表現・管理することが困難です。
- 増分ビルドの非効率性: 変更がない部分の再ビルドを避けるための仕組みがシェルスクリプトでは実装しにくく、ビルド時間が長くなる傾向があります。
- 特定のターゲットの欠如:
make bufio.install
のように、特定のパッケージのみをビルド・インストールするといった、きめ細かい操作がシェルスクリプトでは難しいか、あるいは冗長なスクリプト記述が必要になります。 - 標準的なビルドツールの採用:
make
はUnix系システムで広く使われている標準的なビルド自動化ツールであり、これに移行することで、ビルドプロセスの可読性、保守性、および開発者コミュニティへの親和性が向上します。
特に「make bufio.install
」という記述から、bufio
パッケージ(バッファリングされたI/Oを提供するパッケージ)のインストールを個別に制御したいという具体的なニーズがあったことが伺えます。これは、開発者が特定のコンポーネントのみを更新・テストしたい場合に、全体のビルドを待つ必要がなくなるため、開発効率の向上に寄与します。
前提知識の解説
このコミットを理解するためには、以下の技術的な前提知識が必要です。
- Makefileとmakeコマンド:
make
は、プログラムのコンパイルやインストールなどのタスクを自動化するためのユーティリティです。Makefile
は、make
コマンドが実行するタスクのルールと依存関係を記述したファイルです。ターゲット(目標)、依存関係(ターゲットを作成するために必要なファイル)、コマンド(ターゲットを作成するためのシェルコマンド)から構成されます。- 例:
target: dependencies
の後にコマンドが続く形式。 all
,clean
,install
などは慣習的なターゲット名です。- パターンルール(例:
%.6: %.go
)を使用することで、複数の類似したファイルに対するルールを簡潔に記述できます。
- Go言語の初期のビルドシステム:
6g
コンパイラ: Go言語の初期には、ターゲットアーキテクチャに応じて異なるコンパイラが使用されていました。6g
はAMD64(64ビット)アーキテクチャ向けのGoコンパイラでした。同様に、8g
は386(32ビット)向け、5g
はARM向けでした。.6
ファイル:6g
コンパイラによって生成されるコンパイル済みGoコードのオブジェクトファイルには、.6
という拡張子が付けられていました。これは現在の.o
やGoモジュールシステムにおけるパッケージキャッシュとは異なります。GOROOT
: Goのインストールディレクトリを示す環境変数です。Goのツールチェインや標準ライブラリの場所を特定するために使用されます。このコミットの時点でも、コンパイルされたパッケージは$(GOROOT)/pkg/
に配置されることが想定されていました。
- シェルスクリプト(Bash):
bash
はUnix系OSで広く使われているコマンドラインインタープリタであり、スクリプト言語です。- 初期のGoプロジェクトでは、ビルドやクリーンアップのタスクを自動化するために、
clean.bash
やmake.bash
のようなシェルスクリプトが利用されていました。これらは、一連のコマンドを順次実行するシンプルな自動化に適しています。
技術的詳細
このコミットの技術的な変更は、主に以下の点に集約されます。
src/lib/Makefile
の新規追加:- このファイルが
lib
ディレクトリの新しいビルドの心臓部となります。 - 主要なターゲット:
all
: デフォルトターゲット。install
ターゲットを実行します。clean
: ビルドによって生成された中間ファイルやオブジェクトファイルを削除します。clean.dirs
とclean.files
に依存します。install
: コンパイルされたパッケージを$(GOROOT)/pkg/
にインストールします。install.dirs
とinstall.files
に依存します。nuke
:clean
よりも強力なクリーンアップを行い、$(GOROOT)/pkg/
以下の全てのGoパッケージファイルを削除します。
- 変数定義:
GC=6g
: 使用するGoコンパイラを指定します。DIRS
: サブディレクトリとして存在するGoパッケージ(例:container/array
,fmt
,http
など)のリストです。これらはそれぞれ独自のMakefile
を持つか、このMakefile
からmake install
などが呼び出されます。FILES
:lib
ディレクトリ直下に存在するGoソースファイル(例:bignum
,bufio
,vector
など)のリストです。
- パターンルール:
%.6: container/%.go
および%.6: %.go
:.go
ソースファイルから.6
オブジェクトファイルをコンパイルするためのルールです。$(GC)
(6g
)コマンドが使用されます。%.clean
:.6
ファイルを削除するルールです。%.install: %.6
: コンパイルされた.6
ファイルを$(GOROOT)/pkg/
にコピーするルールです。%.dirclean
,%.dirinstall
,%.dirnuke
:DIRS
リスト内のサブディレクトリに移動し、それぞれのMakefile
のclean
,install
,nuke
ターゲットを実行するためのルールです。+cd $* && make clean
のように、サブシェルで実行されます。
- 依存関係の定義:
bignum.6: fmt.dirinstall
:bignum.6
をビルドする前にfmt
パッケージがインストールされている必要があることを示します。bufio.6: io.install os.dirinstall
:bufio.6
をビルドする前にio
パッケージがインストールされ、os
パッケージがディレクトリとしてインストールされている必要があることを示します。- これらの依存関係は、Goパッケージ間のインポート関係を反映しており、ビルド順序を正しく保証するために重要です。
- このファイルが
src/lib/clean.bash
とsrc/lib/make.bash
の削除:- これらのシェルスクリプトは、
lib
ディレクトリのビルドとクリーンアップのロジックを担っていましたが、その機能は新しく追加されたsrc/lib/Makefile
に完全に置き換えられました。
- これらのシェルスクリプトは、
src/clean.bash
とsrc/make.bash
の変更:- トップレベルの
clean.bash
とmake.bash
スクリプトから、lib
ディレクトリに対する特別な処理(bash clean.bash
やbash make.bash
の呼び出し)が削除されました。これは、lib
ディレクトリのビルドがトップレベルのmake
コマンドによって、そのMakefile
を通じて処理されるようになったためです。
- トップレベルの
コアとなるコードの変更箇所
このコミットのコアとなる変更は、以下のファイルの追加と削除、および既存ファイルの修正です。
- 追加:
src/lib/Makefile
(84行追加) - 削除:
src/lib/clean.bash
(13行削除)src/lib/make.bash
(56行削除)
- 変更:
src/clean.bash
(1行追加, 1行削除)src/make.bash
(1行追加, 1行削除)
特に、src/lib/Makefile
の追加が最も重要であり、このコミットの目的を達成するための主要な実装です。
コアとなるコードの解説
新しく追加されたsrc/lib/Makefile
は、Go言語の初期のライブラリビルドプロセスを明確に定義しています。
# Copyright 2009 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
all: install
GC=6g # 64ビットGoコンパイラを指定
DIRS=\ # サブディレクトリとして存在するGoパッケージのリスト
container/array\
fmt\
http\
math\
net\
os\
reflect\
regexp\
strconv\
time\
FILES=\ # libディレクトリ直下のGoソースファイルのリスト
bignum\
bufio\
vector\
flag\
io\
once\
rand\
sort\
strings\
testing\
clean.dirs: $(addsuffix .dirclean, $(DIRS)) # 各サブディレクトリのcleanターゲットを呼び出す
install.dirs: $(addsuffix .dirinstall, $(DIRS)) # 各サブディレクトリのinstallターゲットを呼び出す
install.files: $(addsuffix .install, $(FILES)) # 各ファイルのinstallターゲットを呼び出す
nuke.dirs: $(addsuffix .dirnuke, $(DIRS)) # 各サブディレクトリのnukeターゲットを呼び出す
%.6: container/%.go # container/ディレクトリ内のGoファイルから.6ファイルをコンパイル
$(GC) container/$*.go
%.6: %.go # libディレクトリ直下のGoファイルから.6ファイルをコンパイル
$(GC) $*.go
%.clean: # .6ファイルを削除
rm -f $*.6
%.install: %.6 # .6ファイルをGOROOT/pkgにコピー
cp $*.6 $(GOROOT)/pkg/$*.6
%.dirclean: # サブディレクトリに移動してmake cleanを実行
+cd $* && make clean
%.dirinstall: # サブディレクトリに移動してmake installを実行
+cd $* && make install
%.dirnuke: # サブディレクトリに移動してmake nukeを実行
+cd $* && make nuke
clean.files: # libディレクトリ直下の.6ファイルと6.outを削除
rm -f 6.out *.6
clean: clean.dirs clean.files # 全体のクリーンアップ
install: install.dirs install.files # 全体のインストール
nuke: nuke.dirs clean.files # 全体の強力なクリーンアップ
rm -f $(GOROOT)/pkg/* # GOROOT/pkg以下の全てのファイルを削除
# dependencies - should auto-generate # 依存関係の定義(手動で記述されているが、将来的には自動生成が望ましいと示唆)
bignum.6: fmt.dirinstall
bufio.6: io.install os.dirinstall # bufio.6のビルドにはioとosのインストールが必要
flag.6: fmt.dirinstall
io.6: os.dirinstall syscall.dirinstall
testing.6: flag.install fmt.dirinstall
fmt.dirinstall: io.install reflect.dirinstall strconv.dirinstall
http.dirinstall: bufio.install io.install net.dirinstall os.dirinstall strings.install
net.dirinstall: once.install os.dirinstall strconv.dirinstall
os.dirinstall: syscall.dirinstall
regexp.dirinstall: os.dirinstall
reflect.dirinstall: strconv.dirinstall
strconv.dirinstall: os.dirinstall
time.dirinstall: once.install os.dirinstall
このMakefile
は、Goパッケージのビルドとインストールを自動化するための包括的なルールセットを提供しています。特に注目すべきは、bufio.6: io.install os.dirinstall
のような依存関係の記述です。これは、bufio
パッケージがio
とos
パッケージに依存していることを明示し、make
がこれらの依存パッケージを先にビルド・インストールすることを保証します。これにより、ビルドの信頼性と再現性が向上します。
関連リンク
- Go言語の公式ドキュメント(現在のビルドシステムについて):https://go.dev/doc/
- GNU Makeの公式ドキュメント:https://www.gnu.org/software/make/manual/
参考にした情報源リンク
- コミット情報:
/home/orange/Project/comemo/commit_data/1215.txt
- GitHub上のコミットページ: https://github.com/golang/go/commit/5a863a4ece7e23f77e89cc4c9420df73e5d786ae
- Go言語の歴史に関する一般的な知識
- Makefileの一般的な知識