[インデックス 10849] ファイルの概要
このコミットは、Go言語のランタイム(src/pkg/runtime
)における自動生成ファイルのビルドプロセスを大幅に整理し、分離することを目的としています。これまでsrc/pkg/runtime/Makefile
内に散在していた自動生成ロジックを、新しく導入されたsrc/pkg/runtime/Makefile.auto
に集約し、ビルドシステム全体の整合性と保守性を向上させています。
コミット
commit bd9243da220935ea2a6985777683c0e587563283
Author: Russ Cox <rsc@golang.org>
Date: Fri Dec 16 17:04:32 2011 -0500
runtime: separate out auto-generated files
R=golang-dev, r, r
CC=golang-dev
https://golang.org/cl/5493063
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/bd9243da220935ea2a6985777683c0e587563283
元コミット内容
このコミットの元のメッセージは「runtime: separate out auto-generated files」であり、Goランタイムにおける自動生成ファイルを分離するという明確な意図を示しています。これは、ビルドプロセスのモジュール化と、生成されるファイルの明確な識別を目的としています。
変更の背景
Go言語の初期のビルドシステムは、C言語のmake
ユーティリティを多用しており、特にランタイムのような低レベルな部分では、OSやアーキテクチャに依存する多くのファイルがビルド時に自動生成されていました。これらの自動生成ファイルの生成ロジックは、メインのsrc/pkg/runtime/Makefile
内に直接記述されており、以下のような問題を引き起こしていました。
- Makefileの複雑化: 自動生成ロジックと通常のビルドロジックが混在し、
Makefile
が肥大化し、理解や保守が困難になっていました。 - 依存関係の不明瞭さ: どのファイルが自動生成され、どのファイルが手書きなのかが曖昧になり、ビルドの依存関係を追跡しにくくなっていました。
- クリーンアップの課題: 自動生成されたファイルを適切にクリーンアップするためのルールが散在し、ビルド環境を完全にクリーンな状態に戻すのが難しい場合がありました。
- ビルド順序の管理: 自動生成されたファイルが、それらを使用する他のファイルよりも先に生成されることを保証するためのビルド順序の管理が複雑でした。
このコミットは、これらの問題を解決するために、自動生成ファイルの生成プロセスを専用のMakefile.auto
に分離し、ビルドシステム全体の構造を改善することを目的としています。
前提知識の解説
このコミットを理解するためには、以下の前提知識が必要です。
- Go言語のランタイム (Runtime): Goプログラムが実行される際に、メモリ管理(ガベージコレクション)、スケジューリング(ゴルーチン)、システムコール、ネットワークI/Oなどを担当する低レベルな部分です。Goランタイムは、Go言語自体で書かれている部分と、C言語やアセンブリ言語で書かれている部分が混在しています。
- Makefile:
make
ユーティリティが使用するビルド自動化スクリプトです。ソースコードのコンパイル、リンク、テストなどのタスクを定義し、ファイルの依存関係に基づいて必要なタスクのみを実行します。 - 自動生成ファイル: ソースコードから別のソースコードや設定ファイルを自動的に生成するプロセスです。Go言語のビルドでは、OSやアーキテクチャ固有の定数、構造体のオフセット、バージョン情報などが自動生成されることがあります。
goc2c
: Go言語のC言語との連携機能(cgo)の一部として、.goc
ファイルをC言語のソースファイルに変換するツールです。.goc
ファイルは、GoとCのコードを混在させて記述できる特殊なファイル形式です。mkasmh.sh
: アセンブリコードで使用するヘッダーファイルを生成するシェルスクリプトです。Goランタイムのアセンブリコードは、C言語の構造体のオフセットなどの情報に依存することがあり、これらのオフセットはビルド時に決定されるため、自動生成されます。mkgodefs.sh
: C言語の構造体定義からGo言語の構造体定義を生成するシェルスクリプトです。これにより、C言語で定義されたデータ構造をGo言語から安全に利用できるようになります。mkversion
: Goのバージョン情報を埋め込んだGoソースファイルを生成するツールです。+build
ディレクティブ: Goのソースファイルに記述されるビルドタグです。特定のOS、アーキテクチャ、またはカスタムタグに基づいて、ファイルのコンパイルを制御します。+build ignore
は、そのファイルをGoツールチェーンが直接コンパイルしないように指示します。これは、そのファイルが別のツールによって処理される入力ファイルであることを示唆します。z
プレフィックス: このコミットで導入された、自動生成されたファイルに付けられる新しい命名規則です。これにより、手書きのファイルと自動生成されたファイルを視覚的に区別しやすくなります。
技術的詳細
このコミットの技術的な核心は、Goランタイムのビルドプロセスにおける自動生成ファイルの管理方法の再構築にあります。
-
Makefile.auto
の導入:src/pkg/runtime/Makefile.auto
という新しいMakefile
が作成されました。このファイルは、Goランタイムで自動生成されるすべてのファイル(zversion.go
,zgoos_*.go
,zgoarch_*.go
,zruntime_defs_*.go
,zasm_*.h
,zsyscall_windows_*.c
,zmalloc_*.c
など)の生成ルールを定義しています。GOARCHES
,GOOSES
,GOOSARCHES
といった変数を定義し、サポートするすべてのアーキテクチャとOSの組み合わせに対して自動生成ファイルを効率的に作成できるようにしています。goc2c
,mkversion
,mkgodefs.sh
,mkasmh.sh
といったツールを呼び出して、それぞれの自動生成ファイルを作成するルールが含まれています。clean
ターゲットも定義されており、自動生成されたファイルを一括で削除できるようになりました。
-
メイン
Makefile
からのロジック分離:src/pkg/runtime/Makefile
から、自動生成ファイルに関するすべてのルール(version.go
の生成、runtime_defs.go
の生成、goc2c
やmkversion
のビルドなど)が削除されました。- これにより、メインの
Makefile
は、手書きのソースファイルのコンパイルとリンクに集中できるようになり、大幅に簡素化されました。 CLEANFILES
からも自動生成ファイルが削除され、clean-local
ターゲットがMakefile.auto
のclean
ターゲットを呼び出すように変更されました。
-
ビルドスクリプトの変更:
src/make.bash
(Goの全体ビルドスクリプト)が変更され、pkg/runtime
の通常のインストール(gomake -C pkg install
)の前に、pkg/runtime
ディレクトリ内でMakefile.auto
を明示的に呼び出す(gomake -C pkg/runtime -f Makefile.auto
)ステップが追加されました。これにより、自動生成ファイルが、それらを使用する他のGoパッケージがビルドされる前に確実に存在することが保証されます。src/cmd/Makefile
も更新され、ランタイムの自動生成ファイルのリビルドに必要なCコンパイラ(5c
,6c
,8c
)が明示的にビルドされるようになりました。
-
ファイル命名規則とビルドタグの変更:
- 自動生成されるGoソースファイルやCソースファイル、ヘッダーファイルには、
z
プレフィックスが付けられるようになりました(例:version.go
->zversion.go
,runtime_defs.go
->zruntime_defs_linux_amd64.go
,asm_386.h
->zasm_linux_386.h
)。これにより、ファイルシステム上で自動生成ファイルと手書きファイルを容易に区別できます。 src/pkg/runtime/defs*.go
のような、自動生成の「元」となるGoファイルには、// +build ignore
ディレクティブが追加されました。これは、Goツールチェーンがこれらのファイルを直接コンパイルせず、自動生成プロセスへの入力としてのみ扱うべきであることを示します。- アセンブリファイル(
.s
)内のインクルードパスも、より具体的な自動生成ヘッダーファイル(例:#include "zasm_GOOS_GOARCH.h"
)を指すように変更されました。
- 自動生成されるGoソースファイルやCソースファイル、ヘッダーファイルには、
-
スクリプトの汎用化:
mkasmh.sh
とmkgodefs.sh
スクリプトは、引数としてOSとアーキテクチャの組み合わせ(例:linux_amd64
)を受け取るように変更されました。これにより、これらのスクリプトは特定のOS/アーキテクチャに依存しない汎用的なツールとして機能し、Makefile.auto
から様々な組み合わせのファイルを生成できるようになりました。
コアとなるコードの変更箇所
このコミットのコアとなる変更は、以下のファイルに集中しています。
-
src/pkg/runtime/Makefile.auto
(新規作成):- このファイルは、Goランタイムの自動生成ファイルのビルドロジックをすべてカプセル化しています。
AUTO
変数に、生成されるすべてのz
プレフィックス付きファイルがリストされています。goc2c
,mkversion
,mkgodefs.sh
,mkasmh.sh
といったツールを呼び出すための具体的なルールが定義されています。
-
src/pkg/runtime/Makefile
(変更):- 自動生成ファイルに関する古いルールがすべて削除されました。
GOFILES
およびOFILES
リストが更新され、新しいz
プレフィックス付きの自動生成ファイルが参照されるようになりました。clean-local
ターゲットがMakefile.auto
のclean
ターゲットを呼び出すように変更されました。
-
src/make.bash
(変更):- ビルドシーケンスが変更され、
pkg/runtime
の通常のビルドの前にMakefile.auto
が実行されるようになりました。
- ビルドシーケンスが変更され、
-
src/pkg/runtime/defs*.go
ファイル群 (変更):- これらのファイルの先頭に
// +build ignore
ディレクティブが追加されました。
- これらのファイルの先頭に
-
src/pkg/runtime/asm_*.s
およびsrc/pkg/runtime/sys_*.s
ファイル群 (変更):- アセンブリヘッダーのインクルードパスが、
asm_GOARCH.h
からzasm_GOOS_GOARCH.h
に変更されました。
- アセンブリヘッダーのインクルードパスが、
コアとなるコードの解説
src/pkg/runtime/Makefile.auto
(抜粋)
# Copyright 2011 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.
GOARCHES=\
386\\\
amd64\\\
arm\\\
GOOSES=\
darwin\\\
freebsd\\\
linux\\\
netbsd\\\
openbsd\\\
plan9\\\
windows\\\
GOOSARCHES=\
darwin_386\\\
darwin_amd64\\\
freebsd_386\\\
freebsd_amd64\\\
linux_386\\\
linux_amd64\\\
linux_arm\\\
netbsd_386\\\
netbsd_amd64\\\
openbsd_386\\\
openbsd_amd64\\\
plan9_386\\\
windows_386\\\
windows_amd64\\\
AUTO=\
$(GOARCHES:%=zmalloc_%.c)\\\
$(GOARCHES:%=zmprof_%.c)\\\
$(GOARCHES:%=zruntime1_%.c)\\\
$(GOARCHES:%=zsema_%.c)\\\
$(GOARCHES:%=zsigqueue_%.c)\\\
$(GOARCHES:%=zstring_%.c)\\\
$(GOARCHES:%=ztime_%.c)\\\
$(GOARCHES:%=zgoarch_%.go)\\\
$(GOOSES:%=zgoos_%.go)\\\
$(GOOSARCHES:%=zruntime_defs_%.go)\\\
$(GOOSARCHES:%=zasm_%.h)\\\
zsyscall_windows_386.c\\\
zsyscall_windows_amd64.c\\\
zversion.go\\\
all: auto
auto: $(AUTO)
# .goc -> .c (specific to os/arch combination)
goc2c: goc2c.c
quietgcc -o $@ -I "$(GOROOT)/include" $< "$(GOROOT)/lib/lib9.a"
z%_386.c: %.goc goc2c
GOARCH=386 ./goc2c "`pwd`/$<" >$@.tmp
mv -f $@.tmp $@
# ... (amd64, arm の同様のルール)
# version files
mkversion: mkversion.c ../../../lib/lib9.a
quietgcc -o $@ -I "$(GOROOT)/include" $< "$(GOROOT)/lib/lib9.a"
zversion.go: mkversion
GOROOT="$(GOROOT_FINAL)" ./mkversion >$@
zgoos_%.go:
(echo '// AUTO-GENERATED; run make -f Makefile.auto'; echo; echo 'package runtime'; echo; echo 'const theGoos = "$*"') >$@
zgoarch_%.go:
(echo '// AUTO-GENERATED; run make -f Makefile.auto'; echo; echo 'package runtime'; echo; echo 'const theGoarch = "$*"') >$@
# definitions of runtime structs, translated from C to Go
zruntime_defs_%.go: proc.c iface.c hashmap.c chan.c $(HFILES) mkgodefs.sh
./mkgodefs.sh $* proc.c iface.c hashmap.c chan.c >$@.tmp
mv -f $@.tmp $@
# struct field offsets #defined for assembly
zasm_%.h: mkasmh.sh proc.c defs.h
./mkasmh.sh $* >$@.tmp
mv -f $@.tmp $@
clean:
rm -f goc2c mkversion $(AUTO)
このMakefile.auto
は、Goランタイムのビルドにおける自動生成のハブとなります。
GOARCHES
,GOOSES
,GOOSARCHES
は、GoがサポートするアーキテクチャとOSの組み合わせを定義しています。AUTO
変数には、これらの組み合わせに基づいて生成されるすべてのファイル名がリストされています。%
はワイルドカードとして機能し、GOARCHES
やGOOSARCHES
の各要素に展開されます。all: auto
とauto: $(AUTO)
は、make auto
を実行すると、AUTO
リスト内のすべてのファイルが生成されることを意味します。- 続くルール(
z%_386.c: %.goc goc2c
など)は、それぞれの自動生成ファイルをどのように作成するかを定義しています。例えば、zmalloc_386.c
はmalloc.goc
とgoc2c
ツールから生成されます。 zruntime_defs_%.go
やzasm_%.h
のルールでは、mkgodefs.sh
やmkasmh.sh
といったシェルスクリプトが、OSとアーキテクチャの情報を引数として受け取り、適切なファイルを生成していることがわかります。clean
ターゲットは、生成されたすべてのファイルを削除し、クリーンな状態に戻すための便利な方法を提供します。
src/pkg/runtime/Makefile
(変更点抜粋)
--- a/src/pkg/runtime/Makefile
+++ b/src/pkg/runtime/Makefile
@@ -14,15 +11,13 @@ GOFILES=\
error.go\\\
extern.go\\\
mem.go\\\
- runtime_defs.go\\\
sig.go\\\
softfloat64.go\\\
type.go\\\
- version.go\\\
- version_$(GOOS).go\\\
- version_$(GOARCH).go\\\
-\
-CLEANFILES+=version.go version_*.go
+\ zgoarch_$(GOARCH).go\\\
+\ zgoos_$(GOOS).go\\\
+\ zruntime_defs_$(GOOS)_$(GOARCH).go\\\
+\ zversion.go\\\
この変更は、GOFILES
リストから古い自動生成ファイル(runtime_defs.go
, version.go
など)を削除し、代わりに新しいz
プレフィックス付きの自動生成ファイル(zgoarch_$(GOARCH).go
, zgoos_$(GOOS).go
, zruntime_defs_$(GOOS)_$(GOARCH).go
, zversion.go
)を追加していることを示しています。これにより、メインのMakefile
は、これらのファイルがMakefile.auto
によって生成されることを前提としています。
src/make.bash
(変更点抜粋)
--- a/src/make.bash
+++ b/src/make.bash
@@ -78,12 +78,18 @@ done
bash "$GOROOT"/src/clean.bash
# pkg builds libcgo and the Go programs in cmd.
-for i in lib9 libbio libmach cmd pkg
+for i in lib9 libbio libmach cmd
do
echo; echo; echo %%%% making $i %%%%; echo
gomake -C $i install
done
+echo; echo; echo %%%% making runtime generated files %%%%; echo
+gomake -C pkg/runtime -f Makefile.auto
+
+echo; echo; echo %%%% making pkg%%%%; echo
+gomake -C pkg install
+
# Print post-install messages.
# Implemented as a function so that all.bash can repeat the output
# after run.bash finishes running all the tests.
このシェルスクリプトの変更は非常に重要です。以前はpkg
ディレクトリ全体がfor
ループ内でビルドされていましたが、この変更により、pkg/runtime
の自動生成ファイルがMakefile.auto
を使って明示的に、かつ他のpkg
のビルドの前に生成されるようになりました。これは、依存関係を正しく解決し、自動生成ファイルが他のコンポーネントによって利用可能であることを保証するために不可欠です。
関連リンク
- Go Change List (CL) 5493063: https://golang.org/cl/5493063
- このCLページには、コミットの詳細な説明、レビューコメント、および関連する議論が含まれており、コミットの背景と意図を深く理解するのに役立ちます。
参考にした情報源リンク
- Go言語の公式ドキュメント (特にビルドシステムやランタイムに関するセクション)
- Go言語のソースコード (特に
src/make.bash
,src/pkg/runtime/Makefile
,src/pkg/runtime/Makefile.auto
の歴史) make
ユーティリティのドキュメント- Go言語の
+build
ディレクティブに関するドキュメント - Go言語のcgoに関するドキュメント
- Go言語の初期のビルドシステムに関するブログ記事や議論 (Russ Cox氏のブログなど) [WebFetchTool] Full response for prompt "Summarize https://golang.org/cl/5493063...": { "candidates": [ { "content": { "role": "model", "parts": [ { "text": "I am unable to access the content of the provided URL. It might be behind a paywall, require a login, or contain sensitive information. Therefore, I cannot summarize it." } ] }, "finishReason": "STOP", "groundingMetadata": {}, "urlContextMetadata": { "urlMetadata": [ { "retrievedUrl": "https://golang.org/cl/5493063", "urlRetrievalStatus": "URL_RETRIEVAL_STATUS_ERROR" } ] } } ], "usageMetadata": { "promptTokenCount": 4213, "candidatesTokenCount": 36, "totalTokenCount": 4303, "trafficType": "PROVISIONED_THROUGHPUT", "promptTokensDetails": [ { "modality": "TEXT", "tokenCount": 4213 } ], "candidatesTokensDetails": [ { "modality": "TEXT", "tokenCount": 36 } ], "toolUsePromptTokenCount": 52, "thoughtsTokenCount": 54 } }
[インデックス 10849] ファイルの概要
このコミットは、Go言語のランタイム(src/pkg/runtime
)における自動生成ファイルのビルドプロセスを大幅に整理し、分離することを目的としています。これまでsrc/pkg/runtime/Makefile
内に散在していた自動生成ロジックを、新しく導入されたsrc/pkg/runtime/Makefile.auto
に集約し、ビルドシステム全体の整合性と保守性を向上させています。
コミット
commit bd9243da220935ea2a6985777683c0e587563283
Author: Russ Cox <rsc@golang.org>
Date: Fri Dec 16 17:04:32 2011 -0500
runtime: separate out auto-generated files
R=golang-dev, r, r
CC=golang-dev
https://golang.org/cl/5493063
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/bd9243da220935ea2a6985777683c0e587563283
元コミット内容
このコミットの元のメッセージは「runtime: separate out auto-generated files」であり、Goランタイムにおける自動生成ファイルを分離するという明確な意図を示しています。これは、ビルドプロセスのモジュール化と、生成されるファイルの明確な識別を目的としています。
変更の背景
Go言語の初期のビルドシステムは、C言語のmake
ユーティリティを多用しており、特にランタイムのような低レベルな部分では、OSやアーキテクチャに依存する多くのファイルがビルド時に自動生成されていました。これらの自動生成ファイルの生成ロジックは、メインのsrc/pkg/runtime/Makefile
内に直接記述されており、以下のような問題を引き起こしていました。
- Makefileの複雑化: 自動生成ロジックと通常のビルドロジックが混在し、
Makefile
が肥大化し、理解や保守が困難になっていました。 - 依存関係の不明瞭さ: どのファイルが自動生成され、どのファイルが手書きなのかが曖昧になり、ビルドの依存関係を追跡しにくくなっていました。
- クリーンアップの課題: 自動生成されたファイルを適切にクリーンアップするためのルールが散在し、ビルド環境を完全にクリーンな状態に戻すのが難しい場合がありました。
- ビルド順序の管理: 自動生成されたファイルが、それらを使用する他のファイルよりも先に生成されることを保証するためのビルド順序の管理が複雑でした。
このコミットは、これらの問題を解決するために、自動生成ファイルの生成プロセスを専用のMakefile.auto
に分離し、ビルドシステム全体の構造を改善することを目的としています。
前提知識の解説
このコミットを理解するためには、以下の前提知識が必要です。
- Go言語のランタイム (Runtime): Goプログラムが実行される際に、メモリ管理(ガベージコレクション)、スケジューリング(ゴルーチン)、システムコール、ネットワークI/Oなどを担当する低レベルな部分です。Goランタイムは、Go言語自体で書かれている部分と、C言語やアセンブリ言語で書かれている部分が混在しています。
- Makefile:
make
ユーティリティが使用するビルド自動化スクリプトです。ソースコードのコンパイル、リンク、テストなどのタスクを定義し、ファイルの依存関係に基づいて必要なタスクのみを実行します。 - 自動生成ファイル: ソースコードから別のソースコードや設定ファイルを自動的に生成するプロセスです。Go言語のビルドでは、OSやアーキテクチャ固有の定数、構造体のオフセット、バージョン情報などが自動生成されることがあります。
goc2c
: Go言語のC言語との連携機能(cgo)の一部として、.goc
ファイルをC言語のソースファイルに変換するツールです。.goc
ファイルは、GoとCのコードを混在させて記述できる特殊なファイル形式です。mkasmh.sh
: アセンブリコードで使用するヘッダーファイルを生成するシェルスクリプトです。Goランタイムのアセンブリコードは、C言語の構造体のオフセットなどの情報に依存することがあり、これらのオフセットはビルド時に決定されるため、自動生成されます。mkgodefs.sh
: C言語の構造体定義からGo言語の構造体定義を生成するシェルスクリプトです。これにより、C言語で定義されたデータ構造をGo言語から安全に利用できるようになります。mkversion
: Goのバージョン情報を埋め込んだGoソースファイルを生成するツールです。+build
ディレクティブ: Goのソースファイルに記述されるビルドタグです。特定のOS、アーキテクチャ、またはカスタムタグに基づいて、ファイルのコンパイルを制御します。+build ignore
は、そのファイルをGoツールチェーンが直接コンパイルしないように指示します。これは、そのファイルが別のツールによって処理される入力ファイルであることを示唆します。z
プレフィックス: このコミットで導入された、自動生成されたファイルに付けられる新しい命名規則です。これにより、手書きのファイルと自動生成されたファイルを視覚的に区別しやすくなります。
技術的詳細
このコミットの技術的な核心は、Goランタイムのビルドプロセスにおける自動生成ファイルの管理方法の再構築にあります。
-
Makefile.auto
の導入:src/pkg/runtime/Makefile.auto
という新しいMakefile
が作成されました。このファイルは、Goランタイムで自動生成されるすべてのファイル(zversion.go
,zgoos_*.go
,zgoarch_*.go
,zruntime_defs_*.go
,zasm_*.h
,zsyscall_windows_*.c
,zmalloc_*.c
など)の生成ルールを定義しています。GOARCHES
,GOOSES
,GOOSARCHES
といった変数を定義し、サポートするすべてのアーキテクチャとOSの組み合わせに対して自動生成ファイルを効率的に作成できるようにしています。goc2c
,mkversion
,mkgodefs.sh
,mkasmh.sh
といったツールを呼び出して、それぞれの自動生成ファイルを作成するルールが含まれています。clean
ターゲットも定義されており、自動生成されたファイルを一括で削除できるようになりました。
-
メイン
Makefile
からのロジック分離:src/pkg/runtime/Makefile
から、自動生成ファイルに関するすべてのルール(version.go
の生成、runtime_defs.go
の生成、goc2c
やmkversion
のビルドなど)が削除されました。- これにより、メインの
Makefile
は、手書きのソースファイルのコンパイルとリンクに集中できるようになり、大幅に簡素化されました。 CLEANFILES
からも自動生成ファイルが削除され、clean-local
ターゲットがMakefile.auto
のclean
ターゲットを呼び出すように変更されました。
-
ビルドスクリプトの変更:
src/make.bash
(Goの全体ビルドスクリプト)が変更され、pkg/runtime
の通常のインストール(gomake -C pkg install
)の前に、pkg/runtime
ディレクトリ内でMakefile.auto
を明示的に呼び出す(gomake -C pkg/runtime -f Makefile.auto
)ステップが追加されました。これにより、自動生成ファイルが、それらを使用する他のGoパッケージがビルドされる前に確実に存在することが保証されます。src/cmd/Makefile
も更新され、ランタイムの自動生成ファイルのリビルドに必要なCコンパイラ(5c
,6c
,8c
)が明示的にビルドされるようになりました。
-
ファイル命名規則とビルドタグの変更:
- 自動生成されるGoソースファイルやCソースファイル、ヘッダーファイルには、
z
プレフィックスが付けられるようになりました(例:version.go
->zversion.go
,runtime_defs.go
->zruntime_defs_linux_amd64.go
,asm_386.h
->zasm_linux_386.h
)。これにより、ファイルシステム上で自動生成ファイルと手書きファイルを容易に区別できます。 src/pkg/runtime/defs*.go
のような、自動生成の「元」となるGoファイルには、// +build ignore
ディレクティブが追加されました。これは、Goツールチェーンがこれらのファイルを直接コンパイルせず、自動生成プロセスへの入力としてのみ扱うべきであることを示します。- アセンブリファイル(
.s
)内のインクルードパスも、より具体的な自動生成ヘッダーファイル(例:#include "zasm_GOOS_GOARCH.h"
)を指すように変更されました。
- 自動生成されるGoソースファイルやCソースファイル、ヘッダーファイルには、
-
スクリプトの汎用化:
mkasmh.sh
とmkgodefs.sh
スクリプトは、引数としてOSとアーキテクチャの組み合わせ(例:linux_amd64
)を受け取るように変更されました。これにより、これらのスクリプトは特定のOS/アーキテクチャに依存しない汎用的なツールとして機能し、Makefile.auto
から様々な組み合わせのファイルを生成できるようになりました。
コアとなるコードの変更箇所
このコミットのコアとなる変更は、以下のファイルに集中しています。
-
src/pkg/runtime/Makefile.auto
(新規作成):- このファイルは、Goランタイムの自動生成ファイルのビルドロジックをすべてカプセル化しています。
AUTO
変数に、生成されるすべてのz
プレフィックス付きファイルがリストされています。goc2c
,mkversion
,mkgodefs.sh
,mkasmh.sh
といったツールを呼び出すための具体的なルールが定義されています。
-
src/pkg/runtime/Makefile
(変更):- 自動生成ファイルに関する古いルールがすべて削除されました。
GOFILES
およびOFILES
リストが更新され、新しいz
プレフィックス付きの自動生成ファイルが参照されるようになりました。clean-local
ターゲットがMakefile.auto
のclean
ターゲットを呼び出すように変更されました。
-
src/make.bash
(変更):- ビルドシーケンスが変更され、
pkg/runtime
の通常のビルドの前にMakefile.auto
が実行されるようになりました。
- ビルドシーケンスが変更され、
-
src/pkg/runtime/defs*.go
ファイル群 (変更):- これらのファイルの先頭に
// +build ignore
ディレクティブが追加されました。
- これらのファイルの先頭に
-
src/pkg/runtime/asm_*.s
およびsrc/pkg/runtime/sys_*.s
ファイル群 (変更):- アセンブリヘッダーのインクルードパスが、
asm_GOARCH.h
からzasm_GOOS_GOARCH.h
に変更されました。
- アセンブリヘッダーのインクルードパスが、
コアとなるコードの解説
src/pkg/runtime/Makefile.auto
(抜粋)
# Copyright 2011 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.
GOARCHES=\
386\\\
amd64\\\
arm\\\
GOOSES=\
darwin\\\
freebsd\\\
linux\\\
netbsd\\\
openbsd\\\
plan9\\\
windows\\\
GOOSARCHES=\
darwin_386\\\
darwin_amd64\\\
freebsd_386\\\
freebsd_amd64\\\
linux_386\\\
linux_amd64\\\
linux_arm\\\
netbsd_386\\\
netbsd_amd64\\\
openbsd_386\\\
openbsd_amd64\\\
plan9_386\\\
windows_386\\\
windows_amd64\\\
AUTO=\
$(GOARCHES:%=zmalloc_%.c)\\\
$(GOARCHES:%=zmprof_%.c)\\\
$(GOARCHES:%=zruntime1_%.c)\\\
$(GOARCHES:%=zsema_%.c)\\\
$(GOARCHES:%=zsigqueue_%.c)\\\
$(GOARCHES:%=zstring_%.c)\\\
$(GOARCHES:%=ztime_%.c)\\\
$(GOARCHES:%=zgoarch_%.go)\\\
$(GOOSES:%=zgoos_%.go)\\\
$(GOOSARCHES:%=zruntime_defs_%.go)\\\
$(GOOSARCHES:%=zasm_%.h)\\\
zsyscall_windows_386.c\\\
zsyscall_windows_amd64.c\\\
zversion.go\\\
all: auto
auto: $(AUTO)
# .goc -> .c (specific to os/arch combination)
goc2c: goc2c.c
quietgcc -o $@ -I "$(GOROOT)/include" $< "$(GOROOT)/lib/lib9.a"
z%_386.c: %.goc goc2c
GOARCH=386 ./goc2c "`pwd`/$<" >$@.tmp
mv -f $@.tmp $@
# ... (amd64, arm の同様のルール)
# version files
mkversion: mkversion.c ../../../lib/lib9.a
quietgcc -o $@ -I "$(GOROOT)/include" $< "$(GOROOT)/lib/lib9.a"
zversion.go: mkversion
GOROOT="$(GOROOT_FINAL)" ./mkversion >$@
zgoos_%.go:
(echo '// AUTO-GENERATED; run make -f Makefile.auto'; echo; echo 'package runtime'; echo; echo 'const theGoos = "$*"') >$@
zgoarch_%.go:
(echo '// AUTO-GENERATED; run make -f Makefile.auto'; echo; echo 'package runtime'; echo; echo 'const theGoarch = "$*"') >$@
# definitions of runtime structs, translated from C to Go
zruntime_defs_%.go: proc.c iface.c hashmap.c chan.c $(HFILES) mkgodefs.sh
./mkgodefs.sh $* proc.c iface.c hashmap.c chan.c >$@.tmp
mv -f $@.tmp $@
# struct field offsets #defined for assembly
zasm_%.h: mkasmh.sh proc.c defs.h
./mkasmh.sh $* >$@.tmp
mv -f $@.tmp $@
clean:
rm -f goc2c mkversion $(AUTO)
このMakefile.auto
は、Goランタイムのビルドにおける自動生成のハブとなります。
GOARCHES
,GOOSES
,GOOSARCHES
は、GoがサポートするアーキテクチャとOSの組み合わせを定義しています。AUTO
変数には、これらの組み合わせに基づいて生成されるすべてのファイル名がリストされています。%
はワイルドカードとして機能し、GOARCHES
やGOOSARCHES
の各要素に展開されます。all: auto
とauto: $(AUTO)
は、make auto
を実行すると、AUTO
リスト内のすべてのファイルが生成されることを意味します。- 続くルール(
z%_386.c: %.goc goc2c
など)は、それぞれの自動生成ファイルをどのように作成するかを定義しています。例えば、zmalloc_386.c
はmalloc.goc
とgoc2c
ツールから生成されます。 zruntime_defs_%.go
やzasm_%.h
のルールでは、mkgodefs.sh
やmkasmh.sh
といったシェルスクリプトが、OSとアーキテクチャの情報を引数として受け取り、適切なファイルを生成していることがわかります。clean
ターゲットは、生成されたすべてのファイルを削除し、クリーンな状態に戻すための便利な方法を提供します。
src/pkg/runtime/Makefile
(変更点抜粋)
--- a/src/pkg/runtime/Makefile
+++ b/src/pkg/runtime/Makefile
@@ -14,15 +11,13 @@ GOFILES=\
error.go\\\
extern.go\\\
mem.go\\\
- runtime_defs.go\\\
sig.go\\\
softfloat64.go\\\
type.go\\\
- version.go\\\
- version_$(GOOS).go\\\
- version_$(GOARCH).go\\\
-\
-CLEANFILES+=version.go version_*.go
+\ zgoarch_$(GOARCH).go\\\
+\ zgoos_$(GOOS).go\\\
+\ zruntime_defs_$(GOOS)_$(GOARCH).go\\\
+\ zversion.go\\\
この変更は、GOFILES
リストから古い自動生成ファイル(runtime_defs.go
, version.go
など)を削除し、代わりに新しいz
プレフィックス付きの自動生成ファイル(zgoarch_$(GOARCH).go
, zgoos_$(GOOS).go
, zruntime_defs_$(GOOS)_$(GOARCH).go
, zversion.go
)を追加していることを示しています。これにより、メインのMakefile
は、これらのファイルがMakefile.auto
によって生成されることを前提としています。
src/make.bash
(変更点抜粋)
--- a/src/make.bash
+++ b/src/make.bash
@@ -78,12 +78,18 @@ done
bash "$GOROOT"/src/clean.bash
# pkg builds libcgo and the Go programs in cmd.
-for i in lib9 libbio libmach cmd pkg
+for i in lib9 libbio libmach cmd
do
echo; echo; echo %%%% making $i %%%%; echo
gomake -C $i install
done
+echo; echo; echo %%%% making runtime generated files %%%%; echo
+gomake -C pkg/runtime -f Makefile.auto
+
+echo; echo; echo %%%% making pkg%%%%; echo
+gomake -C pkg install
+
# Print post-install messages.
# Implemented as a function so that all.bash can repeat the output
# after run.bash finishes running all the tests.
このシェルスクリプトの変更は非常に重要です。以前はpkg
ディレクトリ全体がfor
ループ内でビルドされていましたが、この変更により、pkg/runtime
の自動生成ファイルがMakefile.auto
を使って明示的に、かつ他のpkg
のビルドの前に生成されるようになりました。これは、依存関係を正しく解決し、自動生成ファイルが他のコンポーネントによって利用可能であることを保証するために不可欠です。
関連リンク
- Go Change List (CL) 5493063: https://golang.org/cl/5493063
- このCLページには、コミットの詳細な説明、レビューコメント、および関連する議論が含まれており、コミットの背景と意図を深く理解するのに役立ちます。
参考にした情報源リンク
- Go言語の公式ドキュメント (特にビルドシステムやランタイムに関するセクション)
- Go言語のソースコード (特に
src/make.bash
,src/pkg/runtime/Makefile
,src/pkg/runtime/Makefile.auto
の歴史) make
ユーティリティのドキュメント- Go言語の
+build
ディレクティブに関するドキュメント - Go言語のcgoに関するドキュメント
- Go言語の初期のビルドシステムに関するブログ記事や議論 (Russ Cox氏のブログなど)