[インデックス 1741] ファイルの概要
このコミットは、Go言語の初期開発段階において、src/lib/lang/
ディレクトリに Makefile
を追加するものです。この Makefile
は、gobuild
ツールによって自動生成されることを意図しており、token
パッケージと scanner
パッケージのビルド、テスト、インストールに関するルールを定義しています。
コミット
commit bd4f5af1073bb36948047909aed9501f7bec2db9
Author: Robert Griesemer <gri@golang.org>
Date: Wed Mar 4 17:16:58 2009 -0800
- missing makefile
R=r
OCL=25714
CL=25714
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/bd4f5af1073bb36948047909aed9501f7bec2db9
元コミット内容
このコミットの元々の内容は、src/lib/lang/
ディレクトリに不足していた Makefile
を追加することです。コミットメッセージは非常に簡潔で、「- missing makefile」とだけ記されています。これは、このディレクトリのビルドプロセスを確立するために、このファイルが不可欠であったことを示唆しています。
変更の背景
Go言語の初期段階では、現在の go build
コマンドのような統合されたビルドシステムはまだ存在していませんでした。代わりに、各パッケージやコンポーネントは Makefile
を使用してビルドされていました。このコミットは、src/lib/lang
ディレクトリ、特に token
および scanner
パッケージが適切にビルドされるようにするために、必要な Makefile
を追加するものです。
Makefile
のコメントには「DO NOT EDIT. Automatically generated by gobuild. gobuild -m >Makefile」とあり、これは gobuild
というツールが Makefile
を生成していたことを示しています。これは、Goのビルドシステムが進化する過程で、自動化された Makefile
生成が一時的に採用されていたことを示唆しています。
前提知識の解説
MakefileとMake
Makefile
は、make
ユーティリティがプログラムのコンパイルやその他のタスクを自動化するために使用するファイルです。make
は、ファイルの依存関係を追跡し、変更されたファイルのみを再ビルドすることで、ビルドプロセスを効率化します。Makefile
には、ターゲット(生成されるファイルや実行されるアクション)、依存関係(ターゲットを生成するために必要なファイル)、およびコマンド(ターゲットを生成するためのシェルコマンド)が記述されます。
Go言語の初期ビルドシステム
Go言語の初期は、現在の go
コマンドのような統一されたツールチェインが確立されていませんでした。代わりに、C言語のコンパイラ(6g
, 6c
, 6a
など、アーキテクチャを示す数字がプレフィックスとして付く)や、カスタムのビルドスクリプト、そして Makefile
が使用されていました。この時期のGoのビルドは、C言語のプロジェクトのビルドプロセスに似ていました。
gobuild
ツール
Makefile
のコメントに登場する gobuild
は、Go言語の初期に存在したビルドツールの一つと考えられます。これは、Goのソースコードから Makefile
を自動生成する役割を担っていたようです。現在の go build
コマンドがGoのビルドプロセスを完全に抽象化しているのに対し、gobuild
はより低レベルな Makefile
の生成を通じてビルドを管理していました。
token
および scanner
パッケージ
Go言語のコンパイラやツールにおいて、token
パッケージと scanner
パッケージは非常に基本的な役割を担っています。
token
パッケージ: ソースコードを構成する最小単位である「トークン」(キーワード、識別子、演算子など)を定義します。scanner
パッケージ: ソースコードの文字列を読み込み、それをトークンのストリームに変換する字句解析器(lexer)を提供します。これはコンパイラの最初のフェーズであり、後続の構文解析(parser)の入力となります。
これらのパッケージは、Go言語のコンパイラや他のツールがGoのソースコードを理解し、処理するために不可欠な基盤コンポーネントです。
技術的詳細
この Makefile
は、Go言語の初期のビルドプロセスにおける重要な側面を示しています。
-
コンパイラとツールの指定:
O=6
: これは、当時のGoのツールチェインが特定のアーキテクチャ(おそらく32-bit x86)をターゲットにしていたことを示唆しています。6g
(Goコンパイラ),6c
(Cコンパイラ),6a
(アセンブラ),6ar
(アーカイバ) といったツールが使用されています。GC=$(O)g
,CC=$(O)c -w
,AS=$(O)a
,AR=$(O)ar
: これらの変数は、Goのコンパイラ、Cコンパイラ、アセンブラ、アーカイバへのパスを定義しています。-w
フラグはCコンパイラの警告を抑制しています。
-
ビルドルール:
%.$O: %.go
: Goソースファイル (.go
) をGoオブジェクトファイル (.$O
) にコンパイルするルール。$(GC)
(Goコンパイラ) が使用されます。%.$O: %.c
: Cソースファイル (.c
) をGoオブジェクトファイル (.$O
) にコンパイルするルール。$(CC)
(Cコンパイラ) が使用されます。%.$O: %.s
: アセンブリソースファイル (.s
) をGoオブジェクトファイル (.$O
) にアセンブルするルール。$(AS)
(アセンブラ) が使用されます。
-
パッケージの定義とビルド:
O1
とO2
変数で、token
パッケージとscanner
パッケージを構成するオブジェクトファイルが定義されています。token.a
とscanner.a
は、それぞれtoken
パッケージとscanner
パッケージのアーカイブファイル(ライブラリ)です。a1
とa2
ターゲットは、それぞれのパッケージのオブジェクトファイルをコンパイルし、$(AR) grc
コマンド(Goのアーカイバ)を使ってアーカイブファイルを作成しています。grc
はg
(Goアーカイブ),r
(置換),c
(作成) のオプションを意味します。
-
クリーンアップとテスト:
clean
ターゲットは、ビルドによって生成された中間ファイルや最終ファイルを削除します。test
ターゲットは、gotest
コマンドを実行してテストを行います。coverage
ターゲットは、gotest
の後に6cov
コマンドを実行してカバレッジ情報を生成します。
-
インストール:
install
ターゲットは、ビルドされたscanner.a
とtoken.a
を$(GOROOT)/pkg/
ディレクトリにコピーします。これは、他のGoプロジェクトがこれらのパッケージをインポートして使用できるようにするためです。
この Makefile
は、Go言語の初期のビルドプロセスが、C言語のビルドシステムと類似したアプローチを採用していたことを明確に示しています。各パッケージが個別の Makefile
を持ち、それらが依存関係に基づいてビルドされるという、より分散されたビルドモデルでした。
コアとなるコードの変更箇所
このコミットは、src/lib/lang/Makefile
という新しいファイルを追加するものです。変更はすべて追加行であり、既存のファイルの変更はありません。
--- /dev/null
+++ b/src/lib/lang/Makefile
@@ -0,0 +1,66 @@
+# 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.
+
+# DO NOT EDIT. Automatically generated by gobuild.
+# gobuild -m >Makefile
+O=6
+GC=$(O)g
+CC=$(O)c -w
+AS=$(O)a
+AR=$(O)ar
+
+default: packages
+
+clean:
+ rm -f *.$O *.a $O.out
+
+test: packages
+ gotest
+
+coverage: packages
+ gotest
+ 6cov -g `pwd` | grep -v '_test\\.go:'
+
+%.$O: %.go
+ $(GC) $*.go
+
+%.$O: %.c
+ $(CC) $*.c
+
+%.$O: %.s
+ $(AS) $*.s
+
+O1=\
+ token.$O\
+
+O2=\
+ scanner.$O\
+
+scanner.a: a1 a2
+token.a: a1 a2
+
+a1: $(O1)
+ $(AR) grc token.a token.$O
+ rm -f $(O1)
+
+a2: $(O2)
+ $(AR) grc scanner.a scanner.$O
+ rm -f $(O2)
+
+newpkg: clean
+ $(AR) grc scanner.a
+ $(AR) grc token.a
+
+$(O1): newpkg
+$(O2): a1
+
+nuke: clean
+ rm -f $(GOROOT)/pkg/scanner.a $(GOROOT)/pkg/token.a
+
+packages: scanner.a token.a
+
+install: packages
+ cp scanner.a $(GOROOT)/pkg/scanner.a
+ cp token.a $(GOROOT)/pkg/token.a
コアとなるコードの解説
この Makefile
は、token
および scanner
パッケージのビルドプロセスを定義しています。
- ヘッダー: Go Authorsの著作権表示と、BSDスタイルのライセンスに関する記述があります。また、「DO NOT EDIT. Automatically generated by gobuild. gobuild -m >Makefile」というコメントがあり、このファイルが
gobuild
ツールによって自動生成されたものであることを示しています。 - 変数定義:
O=6
: ビルドターゲットのアーキテクチャ(例: 6 for 32-bit x86)を示します。GC
,CC
,AS
,AR
: それぞれGoコンパイラ、Cコンパイラ、アセンブラ、アーカイバのコマンドを定義しています。これらはO
の値に基づいて6g
,6c
,6a
,6ar
となります。
- デフォルトターゲット:
default: packages
は、make
コマンドが引数なしで実行された場合にpackages
ターゲットが実行されることを意味します。 - クリーンアップターゲット:
clean
は、ビルドによって生成されたオブジェクトファイル (.O
)、アーカイブファイル (.a
)、およびその他の出力ファイル ($O.out
) を削除します。 - テストターゲット:
test
はgotest
コマンドを実行してテストを実行します。coverage
はgotest
の後に6cov
を実行してコードカバレッジを測定します。 - 汎用ビルドルール:
%.$O: %.go
:.go
ファイルをGoコンパイラ ($(GC)
) でコンパイルして.O
ファイルを生成します。%.$O: %.c
:.c
ファイルをCコンパイラ ($(CC)
) でコンパイルして.O
ファイルを生成します。%.$O: %.s
:.s
ファイルをアセンブラ ($(AS)
) でアセンブルして.O
ファイルを生成します。
- パッケージオブジェクトファイルリスト:
O1
:token.$O
を含み、token
パッケージのオブジェクトファイルを指定します。O2
:scanner.$O
を含み、scanner
パッケージのオブジェクトファイルを指定します。
- パッケージアーカイブターゲット:
scanner.a: a1 a2
とtoken.a: a1 a2
: これらの行は、scanner.a
とtoken.a
がa1
とa2
に依存していることを示していますが、これは論理的に正しくありません。おそらくscanner.a
はa2
に、token.a
はa1
に依存するという意図だったと思われます。a1
:token
パッケージのオブジェクトファイル ($(O1)
) をビルドし、それらをtoken.a
というアーカイブファイルにまとめます。その後、中間オブジェクトファイルを削除します。a2
:scanner
パッケージのオブジェクトファイル ($(O2)
) をビルドし、それらをscanner.a
というアーカイブファイルにまとめます。その後、中間オブジェクトファイルを削除します。
newpkg
ターゲット:clean
を実行した後、空のscanner.a
とtoken.a
を作成します。これは、新しいパッケージのビルドを開始する際の初期化ステップとして機能する可能性があります。- 依存関係:
$(O1): newpkg
:token
パッケージのオブジェクトファイルがnewpkg
に依存していることを示します。$(O2): a1
:scanner
パッケージのオブジェクトファイルがa1
に依存していることを示します。これは、scanner
がtoken
に依存していることを反映している可能性があります。
nuke
ターゲット:clean
を実行した後、$(GOROOT)/pkg/
ディレクトリにあるscanner.a
とtoken.a
を削除します。これは、システム全体からこれらのパッケージを完全に削除するためのものです。packages
ターゲット:scanner.a
とtoken.a
をビルドします。これは、このディレクトリ内のすべてのパッケージをビルドするための主要なターゲットです。install
ターゲット: ビルドされたscanner.a
とtoken.a
を$(GOROOT)/pkg/
ディレクトリにコピーします。これにより、これらのパッケージがGoの標準ライブラリの一部として利用可能になります。
この Makefile
は、Go言語の初期のビルドシステムが、C言語のプロジェクトで一般的に見られるような、明示的な依存関係とビルドルールを持つ Makefile
を使用していたことを示しています。これは、現在の go build
コマンドが提供する、より抽象化されたシンプルなビルド体験とは対照的です。
関連リンク
- Go言語の初期のビルドシステムに関する議論やドキュメントは、Goの公式リポジトリの初期のコミット履歴や、Goのメーリングリストのアーカイブで確認できる可能性があります。
make
ユーティリティの公式ドキュメント: https://www.gnu.org/software/make/manual/
参考にした情報源リンク
- Go言語の公式リポジトリ (GitHub): https://github.com/golang/go
make
ユーティリティに関する一般的な知識- Go言語の初期のビルドプロセスに関する歴史的情報(Web検索を通じて得られる可能性のある情報)
- Go言語の
token
およびscanner
パッケージに関する一般的な知識 - Go言語の初期のツールチェインに関する情報(
6g
,6c
,6a
など)