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

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

このコミットは、Go言語プロジェクトのsrc/libディレクトリにおけるビルドシステムを、従来のシェルスクリプト(make.bashclean.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プロジェクトのビルドシステムは、おそらくシンプルなシェルスクリプトに依存していました。しかし、プロジェクトが成長し、より多くのライブラリやパッケージが追加されるにつれて、シェルスクリプトベースのビルドシステムでは以下のような課題が生じていたと考えられます。

  1. 依存関係の管理の複雑さ: シェルスクリプトでは、パッケージ間の複雑なビルド依存関係を効率的かつ正確に表現・管理することが困難です。
  2. 増分ビルドの非効率性: 変更がない部分の再ビルドを避けるための仕組みがシェルスクリプトでは実装しにくく、ビルド時間が長くなる傾向があります。
  3. 特定のターゲットの欠如: make bufio.installのように、特定のパッケージのみをビルド・インストールするといった、きめ細かい操作がシェルスクリプトでは難しいか、あるいは冗長なスクリプト記述が必要になります。
  4. 標準的なビルドツールの採用: makeはUnix系システムで広く使われている標準的なビルド自動化ツールであり、これに移行することで、ビルドプロセスの可読性、保守性、および開発者コミュニティへの親和性が向上します。

特に「make bufio.install」という記述から、bufioパッケージ(バッファリングされたI/Oを提供するパッケージ)のインストールを個別に制御したいという具体的なニーズがあったことが伺えます。これは、開発者が特定のコンポーネントのみを更新・テストしたい場合に、全体のビルドを待つ必要がなくなるため、開発効率の向上に寄与します。

前提知識の解説

このコミットを理解するためには、以下の技術的な前提知識が必要です。

  1. Makefileとmakeコマンド:
    • makeは、プログラムのコンパイルやインストールなどのタスクを自動化するためのユーティリティです。
    • Makefileは、makeコマンドが実行するタスクのルールと依存関係を記述したファイルです。ターゲット(目標)、依存関係(ターゲットを作成するために必要なファイル)、コマンド(ターゲットを作成するためのシェルコマンド)から構成されます。
    • 例: target: dependencies の後にコマンドが続く形式。
    • all, clean, installなどは慣習的なターゲット名です。
    • パターンルール(例: %.6: %.go)を使用することで、複数の類似したファイルに対するルールを簡潔に記述できます。
  2. Go言語の初期のビルドシステム:
    • 6gコンパイラ: Go言語の初期には、ターゲットアーキテクチャに応じて異なるコンパイラが使用されていました。6gはAMD64(64ビット)アーキテクチャ向けのGoコンパイラでした。同様に、8gは386(32ビット)向け、5gはARM向けでした。
    • .6ファイル: 6gコンパイラによって生成されるコンパイル済みGoコードのオブジェクトファイルには、.6という拡張子が付けられていました。これは現在の.oやGoモジュールシステムにおけるパッケージキャッシュとは異なります。
    • GOROOT: Goのインストールディレクトリを示す環境変数です。Goのツールチェインや標準ライブラリの場所を特定するために使用されます。このコミットの時点でも、コンパイルされたパッケージは$(GOROOT)/pkg/に配置されることが想定されていました。
  3. シェルスクリプト(Bash):
    • bashはUnix系OSで広く使われているコマンドラインインタープリタであり、スクリプト言語です。
    • 初期のGoプロジェクトでは、ビルドやクリーンアップのタスクを自動化するために、clean.bashmake.bashのようなシェルスクリプトが利用されていました。これらは、一連のコマンドを順次実行するシンプルな自動化に適しています。

技術的詳細

このコミットの技術的な変更は、主に以下の点に集約されます。

  1. src/lib/Makefileの新規追加:
    • このファイルがlibディレクトリの新しいビルドの心臓部となります。
    • 主要なターゲット:
      • all: デフォルトターゲット。installターゲットを実行します。
      • clean: ビルドによって生成された中間ファイルやオブジェクトファイルを削除します。clean.dirsclean.filesに依存します。
      • install: コンパイルされたパッケージを$(GOROOT)/pkg/にインストールします。install.dirsinstall.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リスト内のサブディレクトリに移動し、それぞれのMakefileclean, install, nukeターゲットを実行するためのルールです。+cd $* && make cleanのように、サブシェルで実行されます。
    • 依存関係の定義:
      • bignum.6: fmt.dirinstall: bignum.6をビルドする前にfmtパッケージがインストールされている必要があることを示します。
      • bufio.6: io.install os.dirinstall: bufio.6をビルドする前にioパッケージがインストールされ、osパッケージがディレクトリとしてインストールされている必要があることを示します。
      • これらの依存関係は、Goパッケージ間のインポート関係を反映しており、ビルド順序を正しく保証するために重要です。
  2. src/lib/clean.bashsrc/lib/make.bashの削除:
    • これらのシェルスクリプトは、libディレクトリのビルドとクリーンアップのロジックを担っていましたが、その機能は新しく追加されたsrc/lib/Makefileに完全に置き換えられました。
  3. src/clean.bashsrc/make.bashの変更:
    • トップレベルのclean.bashmake.bashスクリプトから、libディレクトリに対する特別な処理(bash clean.bashbash 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パッケージがioosパッケージに依存していることを明示し、makeがこれらの依存パッケージを先にビルド・インストールすることを保証します。これにより、ビルドの信頼性と再現性が向上します。

関連リンク

参考にした情報源リンク