[インデックス 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など)