[インデックス 10854] ファイルの概要
このコミットは、Go言語のランタイムビルドシステムにおける重要な変更、具体的には以前の変更をhg revert
コマンドで元に戻す操作を記録しています。これにより、ビルドの安定性を取り戻し、特にMakefile.auto
の役割を廃止し、その機能をsrc/pkg/runtime/Makefile
に統合する方向への過渡期を示しています。多数のファイルが変更されており、主にsrc/pkg/runtime
ディレクトリ内のビルド関連ファイル(Makefile、スクリプト、アセンブリファイル、定義ファイル)に影響があります。
コミット
- コミットハッシュ:
86dcc431e9282013eb8ce6cce22c882f37a05147
- Author: Russ Cox rsc@golang.org
- Date: Fri Dec 16 18:50:40 2011 -0500
- コミットメッセージ:
runtime: hg revert -r 6ec0a5c12d75 That was the last build that was close to working. I will try that change again next week. Make is being very subtle today. At the reverted-to CL, the ARM traceback appears to be broken. I'll look into that next week too. R=golang-dev, r CC=golang-dev https://golang.org/cl/5492063
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/86dcc431e9282013eb8ce6cce22c882f37a05147
元コミット内容
runtime: hg revert -r 6ec0a5c12d75
That was the last build that was close to working.
I will try that change again next week.
Make is being very subtle today.
At the reverted-to CL, the ARM traceback appears
to be broken. I'll look into that next week too.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5492063
変更の背景
このコミットの背景には、Go言語のランタイムビルドプロセスにおける不安定性がありました。コミットメッセージによると、以前の変更(リバート対象の6ec0a5c12d75
)がビルドを不安定にしていたようです。特に、Make
(おそらくGNU Make)の挙動が「非常に微妙」であり、ビルドが正常に完了しない問題が発生していました。また、リバート後の状態でもARMアーキテクチャでのトレースバックが壊れている可能性が指摘されており、これはGoランタイムのデバッグやエラー報告において重要な機能であるため、早急な対応が必要とされていました。
このhg revert
は、問題のある変更を一時的に取り消し、安定した状態に戻すことで、根本原因の特定と修正のための時間を確保するための措置です。Goプロジェクトでは、継続的な開発と同時に、ビルドの健全性を維持することが非常に重要であり、このようなリバートは開発プロセスにおける一般的なプラクティスです。
前提知識の解説
hg revert
コマンド
hg revert
は、Mercurial(Hg)バージョン管理システムにおけるコマンドで、指定したリビジョンやコミットの状態に作業ディレクトリのファイルを戻すために使用されます。Gitのgit revert
とは異なり、hg revert
は新しいコミットを作成するのではなく、指定されたリビジョンの状態にファイルを戻し、その変更を作業ディレクトリに適用します。このコミットでは、hg revert -r 6ec0a5c12d75
という形で、特定の変更セット(リビジョン)までファイルを巻き戻しています。これは、問題を引き起こしている可能性のある変更を一時的に取り消し、安定した状態に戻すための迅速な手段として用いられます。
Go言語のビルドシステムとMakefile
Go言語のビルドシステムは、初期の段階ではC言語のツールチェイン(5c
, 6c
, 8c
など、それぞれPlan 9 Cコンパイラの386, AMD64, ARM版)とmake
コマンドを多用していました。Goのランタイムは、Go、C、そしてアセンブリ言語で書かれたコードが混在しており、これらを適切にコンパイルしリンクするためには複雑なビルドプロセスが必要でした。
Makefile
:Makefile
は、make
ユーティリティがプロジェクトのビルドを自動化するために使用するスクリプトです。依存関係を定義し、それらを解決するためのコマンドシーケンスを指定します。Goのソースコード内には、src/Make.pkg
、src/cmd/Makefile
、src/pkg/runtime/Makefile
など、複数のMakefile
が存在し、それぞれが特定のパッケージやコンポーネントのビルドを担当していました。Makefile.auto
: このコミットで削除されたsrc/pkg/runtime/Makefile.auto
は、Goランタイムのビルドプロセスにおいて、OSやアーキテクチャに依存する自動生成ファイルを管理するための特別なMakefile
でした。これには、zmalloc_%.c
、zruntime1_%.c
、zgoarch_%.go
、zasm_%.h
などのファイル生成ルールが含まれていました。このファイルの存在は、ビルドプロセスの複雑さを増す要因の一つでした。make.bash
:src/make.bash
は、Goプロジェクト全体のビルドをオーケストレーションするシェルスクリプトです。これは、各サブディレクトリのMakefile
を呼び出し、Goツールチェインのビルド、標準ライブラリのコンパイル、テストの実行などを行います。
Goランタイムの構成要素
Goランタイムは、Goプログラムの実行をサポートする低レベルのコード群です。これには、ガベージコレクタ、スケジューラ、メモリ管理、システムコールインターフェースなどが含まれます。
- アセンブリファイル (
.s
): Goランタイムには、特定のアーキテクチャ(386, amd64, armなど)に特化したアセンブリコードが含まれています。これらは、コンテキストスイッチ、システムコール、低レベルのメモリ操作など、Go言語では直接記述できない処理を効率的に行うために使用されます。 - Cファイル (
.c
): 一部のランタイムコードはC言語で書かれています。これは、既存のCライブラリとの連携や、Go言語がまだ成熟していなかった初期の段階での実装の都合によるものです。 - Goファイル (
.go
): ランタイムの大部分はGo言語自体で書かれています。
自動生成ファイルとスクリプト
Goのビルドプロセスでは、異なるOSやアーキテクチャに対応するために、多くのファイルが自動生成されます。
goc2c
:.goc
ファイルを.c
ファイルに変換するツールです。.goc
ファイルは、C言語とGo言語の限定的な形式を組み合わせたもので、ランタイムの初期段階でCgoのような役割を果たしていました。mkgodefs.sh
: C言語で定義された構造体や定数をGo言語の定義に変換するためのシェルスクリプトです。これにより、CとGoの間でデータ構造の整合性を保ちます。mkasmh.sh
: アセンブリコードで使用される定数や構造体オフセットを定義したヘッダファイル(.h
)を生成するためのシェルスクリプトです。これにより、アセンブリコードがGoのデータ構造の変更に追従できるようになります。// +build ignore
: Goのビルドタグの一つで、このコメントがファイルの先頭にある場合、go build
コマンドはそのファイルをビルド対象から除外します。これは、ユーティリティスクリプトやテスト、一時的なファイルなど、メインのアプリケーションにはコンパイルされないファイルをマークするために使用されます。
技術的詳細
このコミットの技術的詳細は、Goランタイムのビルドプロセスにおける自動生成ファイルの管理方法の変更に集約されます。
-
Makefile.auto
の削除と機能統合: 最も大きな変更は、src/pkg/runtime/Makefile.auto
が完全に削除されたことです。このファイルは、Goランタイムのビルドにおいて、様々なOS/アーキテクチャ固有の自動生成ファイル(zmalloc_%.c
,zruntime1_%.c
,zgoarch_%.go
,zasm_%.h
など)の生成を担っていました。これらの生成ロジックは、src/pkg/runtime/Makefile
に直接統合されました。これにより、ビルド設定が一元化され、管理が簡素化されることが期待されます。 -
自動生成ファイルの命名規則の変更と直接的な生成:
- 以前は
zgoarch_$(GOARCH).go
やzgoos_$(GOOS).go
といったファイルがMakefile.auto
によって生成されていましたが、これらはそれぞれversion_$(GOARCH).go
とversion_$(GOOS).go
に名称が変更され、src/pkg/runtime/Makefile
内で直接生成されるようになりました。 zversion.go
はversion.go
に名称変更され、mkversion
ツールによって生成されます。- アセンブリファイルでインクルードされていた
zasm_GOOS_GOARCH.h
は、asm_$(GOARCH).h
というより簡潔な名前に変更され、mkasmh.sh
スクリプトによって生成されるようになりました。これにより、アセンブリファイル内のインクルードパスも簡素化されています。
- 以前は
-
// +build ignore
タグの削除:src/pkg/runtime
ディレクトリ内の複数のdefs*.go
ファイル(例:defs1_linux.go
,defs_darwin.go
など)やgoc2c.c
,lock_futex.c
,lock_sema.c
,mkversion.c
から// +build ignore
タグが削除されました。これは、これらのファイルがビルドプロセスにおいて直接処理されるようになったことを示唆しています。以前は、これらのファイルは特定のツール(cgo -cdefs
など)の入力としてのみ使用され、Goコンパイラによる直接のビルド対象ではなかったため、ignore
タグが付与されていました。タグの削除は、ビルドシステムがこれらのファイルをより直接的に扱うようになったことを意味します。 -
mkasmh.sh
とmkgodefs.sh
の変更: これらのスクリプトは、OSやアーキテクチャの情報を引数として受け取るのではなく、環境変数GOOS
とGOARCH
を直接利用するように変更されました。また、一時ファイルのコピーや削除のロジックが簡素化され、よりクリーンなスクリプトになりました。特にmkasmh.sh
は、runtime.acid.$GOARCH
というファイルからアセンブリ定数を抽出するようになりました。これは、Cコンパイラが生成するデバッグ情報から構造体オフセットなどを取得する新しいメカニズムを示唆しています。 -
src/Make.pkg
、src/cmd/Makefile
、src/make.bash
の調整:src/Make.pkg
では、アセンブリファイルのコンパイル時に$(AFLAGS)
が不要になり、よりシンプルなコマンドになりました。src/cmd/Makefile
では、Cコンパイラのビルドターゲットが5c
,6c
,8c
から$(O)c
に統合され、より汎用的な記述になりました。src/make.bash
では、pkg/runtime
の自動生成ファイルをMakefile.auto
でビルドするステップが削除され、pkg
ディレクトリ全体のビルドがより早い段階で行われるようになりました。
これらの変更は、Goのビルドシステムがより洗練され、自動生成ファイルの管理が効率化される方向への一歩を示しています。特に、Makefile.auto
の廃止は、ビルドプロセスの複雑性を軽減し、メインのMakefile
にロジックを集約することで、保守性を向上させる狙いがあったと考えられます。
コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更箇所は以下のファイルに集中しています。
-
src/pkg/runtime/Makefile
:Makefile.auto
への依存が削除され、自動生成ファイルの生成ロジックがこのファイルに直接追加されました。version.go
,version_$(GOOS).go
,version_$(GOARCH).go
の生成ルールが追加されました。asm_$(GOARCH).h
の生成ルールが追加され、mkasmh.sh
スクリプトが使用されるようになりました。runtime_defs.go
の生成ルールが追加され、mkgodefs.sh
スクリプトが使用されるようになりました。CLEANFILES
に自動生成ファイルが追加されました。OFILES
リストからzgoarch_$(GOARCH).go
、zgoos_$(GOOS).go
、zruntime_defs_$(GOOS)_$(GOARCH).go
などの古い自動生成ファイルが削除され、新しいファイル名が追加されました。CFLAGS
とAFLAGS
から-DGOOS_$(GOOS) -DGOARCH_$(GOARCH)
の定義が削除されました。
-
src/pkg/runtime/Makefile.auto
:- ファイル全体が削除されました。
-
src/pkg/runtime/asm_386.s
,src/pkg/runtime/asm_amd64.s
,src/pkg/runtime/asm_arm.s
:- インクルードパスが
#include "zasm_GOOS_GOARCH.h"
から#include "asm_$(GOARCH).h"
(例:#include "asm_386.h"
) に変更されました。
- インクルードパスが
-
src/pkg/runtime/defs*.go
(複数ファイル):- ファイルの先頭にあった
// +build ignore
タグが削除されました。
- ファイルの先頭にあった
-
src/pkg/runtime/goc2c.c
:// +build ignore
タグが削除されました。- 自動生成を示すコメント
printf("// AUTO-GENERATED; run make\\n\\n");
が削除されました。
-
src/pkg/runtime/mkasmh.sh
:- 引数からOS/ARCH情報を取得する代わりに、環境変数
GOOS
とGOARCH
を直接使用するように変更されました。 - 一時ファイルのコピーと削除のロジックが簡素化されました。
runtime.acid.$GOARCH
からアセンブリ定数を抽出するようになりました。- 自動生成を示すコメントが
// AUTO-GENERATED; run make -f Makefile.auto
から// AUTOMATICALLY GENERATED BY mkasmh.sh DURING BUILD
に変更されました。
- 引数からOS/ARCH情報を取得する代わりに、環境変数
-
src/pkg/runtime/mkgodefs.sh
:- 引数からOS/ARCH情報を取得する代わりに、環境変数
GOOS
とGOARCH
を直接使用するように変更されました。 - 自動生成を示すコメントが
// AUTO-GENERATED; run make -f Makefile.auto
から// AUTOMATICALLY GENERATED BY THE FOLLOWING COMMAND. DO NOT EDIT.
に変更されました。
- 引数からOS/ARCH情報を取得する代わりに、環境変数
-
src/pkg/runtime/mkversion.c
:// +build ignore
タグが削除されました。- 自動生成を示すコメントが
// AUTO-GENERATED; run make -f Makefile.auto
から// generated by mkversion.c; do not edit.
に変更されました。
-
src/Make.pkg
:- アセンブリファイルのコンパイルコマンドから
$(AFLAGS)
が削除されました。
- アセンブリファイルのコンパイルコマンドから
-
src/cmd/Makefile
:DIRS
リストから5c
,6c
,8c
が削除され、$(O)c
が追加されました。gc.install 5c.install 6c.install 8c.install: cc.install
がgc.install $(O)c.install: cc.install
に変更されました。
-
src/make.bash
:pkg/runtime
の自動生成ファイルをMakefile.auto
でビルドするステップが削除されました。for i in lib9 libbio libmach cmd
がfor i in lib9 libbio libmach cmd pkg
に変更され、pkg
ディレクトリ全体のビルドが統合されました。
コアとなるコードの解説
このコミットの核心は、Goランタイムのビルドプロセスにおける自動生成ファイルの管理方法の根本的な見直しと簡素化です。
-
Makefile.auto
の廃止: 以前は、src/pkg/runtime/Makefile.auto
がOSやアーキテクチャに特化した多数のファイルを自動生成する役割を担っていました。このコミットでは、Makefile.auto
を完全に削除し、その機能をsrc/pkg/runtime/Makefile
に直接統合しました。これにより、ビルド設定が単一のMakefile
に集約され、ビルドプロセスの透明性と保守性が向上します。開発者は、自動生成ファイルのルールを一つの場所で確認できるようになります。 -
自動生成ファイルの命名規則とインクルードパスの簡素化:
zgoarch_*.go
やzgoos_*.go
といった冗長なプレフィックスを持つファイル名が、より直感的なversion_*.go
に変更されました。これは、これらのファイルがGoのバージョン情報やOS/アーキテクチャ情報をランタイムに提供する役割を明確に示しています。- アセンブリファイルにおけるヘッダファイルのインクルードパスも、
zasm_GOOS_GOARCH.h
からasm_$(GOARCH).h
へと簡素化されました。これにより、アセンブリコードの可読性が向上し、特定のOS情報が不要な場合にインクルードが不要になります。
-
// +build ignore
タグの削除の意図: 多くのdefs*.go
ファイルやgoc2c.c
などから// +build ignore
タグが削除されたことは、これらのファイルがGoコンパイラによって直接ビルドされるようになったことを示唆しています。以前は、これらのファイルは特定のツール(例:cgo -cdefs
)の入力としてのみ扱われ、Goのビルドシステムからは無視されていました。タグの削除は、ビルドシステムがこれらのファイルをより統合的に管理するようになったことを意味し、ビルドプロセスの効率化に貢献します。 -
mkasmh.sh
とmkgodefs.sh
の改善: これらのスクリプトは、OSやアーキテクチャの情報を環境変数から直接取得するように変更され、より汎用性が高まりました。特にmkasmh.sh
がruntime.acid.$GOARCH
から情報を抽出するようになった点は注目に値します。これは、Cコンパイラのデバッグ出力からGoランタイムの内部構造に関する情報を動的に取得し、アセンブリコードに反映させるという、より高度な自動化が導入されたことを示しています。これにより、Goの内部データ構造が変更されても、アセンブリコードを手動で更新する必要が減り、開発の効率が向上します。
これらの変更は、Go言語の初期段階におけるビルドシステムの試行錯誤と成熟の過程を示しています。複雑な自動生成プロセスをよりシンプルで一元化された方法に移行することで、ビルドの信頼性と開発者の生産性を向上させることを目指しています。
関連リンク
- https://github.com/golang/go/commit/86dcc431e9282013eb8ce6cce22c882f37a05147
- https://golang.org/cl/5492063 (Go Code Review)