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

[インデックス 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内に直接記述されており、以下のような問題を引き起こしていました。

  1. Makefileの複雑化: 自動生成ロジックと通常のビルドロジックが混在し、Makefileが肥大化し、理解や保守が困難になっていました。
  2. 依存関係の不明瞭さ: どのファイルが自動生成され、どのファイルが手書きなのかが曖昧になり、ビルドの依存関係を追跡しにくくなっていました。
  3. クリーンアップの課題: 自動生成されたファイルを適切にクリーンアップするためのルールが散在し、ビルド環境を完全にクリーンな状態に戻すのが難しい場合がありました。
  4. ビルド順序の管理: 自動生成されたファイルが、それらを使用する他のファイルよりも先に生成されることを保証するためのビルド順序の管理が複雑でした。

このコミットは、これらの問題を解決するために、自動生成ファイルの生成プロセスを専用のMakefile.autoに分離し、ビルドシステム全体の構造を改善することを目的としています。

前提知識の解説

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

  1. Go言語のランタイム (Runtime): Goプログラムが実行される際に、メモリ管理(ガベージコレクション)、スケジューリング(ゴルーチン)、システムコール、ネットワークI/Oなどを担当する低レベルな部分です。Goランタイムは、Go言語自体で書かれている部分と、C言語やアセンブリ言語で書かれている部分が混在しています。
  2. Makefile: makeユーティリティが使用するビルド自動化スクリプトです。ソースコードのコンパイル、リンク、テストなどのタスクを定義し、ファイルの依存関係に基づいて必要なタスクのみを実行します。
  3. 自動生成ファイル: ソースコードから別のソースコードや設定ファイルを自動的に生成するプロセスです。Go言語のビルドでは、OSやアーキテクチャ固有の定数、構造体のオフセット、バージョン情報などが自動生成されることがあります。
  4. goc2c: Go言語のC言語との連携機能(cgo)の一部として、.gocファイルをC言語のソースファイルに変換するツールです。.gocファイルは、GoとCのコードを混在させて記述できる特殊なファイル形式です。
  5. mkasmh.sh: アセンブリコードで使用するヘッダーファイルを生成するシェルスクリプトです。Goランタイムのアセンブリコードは、C言語の構造体のオフセットなどの情報に依存することがあり、これらのオフセットはビルド時に決定されるため、自動生成されます。
  6. mkgodefs.sh: C言語の構造体定義からGo言語の構造体定義を生成するシェルスクリプトです。これにより、C言語で定義されたデータ構造をGo言語から安全に利用できるようになります。
  7. mkversion: Goのバージョン情報を埋め込んだGoソースファイルを生成するツールです。
  8. +build ディレクティブ: Goのソースファイルに記述されるビルドタグです。特定のOS、アーキテクチャ、またはカスタムタグに基づいて、ファイルのコンパイルを制御します。+build ignoreは、そのファイルをGoツールチェーンが直接コンパイルしないように指示します。これは、そのファイルが別のツールによって処理される入力ファイルであることを示唆します。
  9. z プレフィックス: このコミットで導入された、自動生成されたファイルに付けられる新しい命名規則です。これにより、手書きのファイルと自動生成されたファイルを視覚的に区別しやすくなります。

技術的詳細

このコミットの技術的な核心は、Goランタイムのビルドプロセスにおける自動生成ファイルの管理方法の再構築にあります。

  1. 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ターゲットも定義されており、自動生成されたファイルを一括で削除できるようになりました。
  2. メインMakefileからのロジック分離:

    • src/pkg/runtime/Makefileから、自動生成ファイルに関するすべてのルール(version.goの生成、runtime_defs.goの生成、goc2cmkversionのビルドなど)が削除されました。
    • これにより、メインのMakefileは、手書きのソースファイルのコンパイルとリンクに集中できるようになり、大幅に簡素化されました。
    • CLEANFILESからも自動生成ファイルが削除され、clean-localターゲットがMakefile.autocleanターゲットを呼び出すように変更されました。
  3. ビルドスクリプトの変更:

    • 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)が明示的にビルドされるようになりました。
  4. ファイル命名規則とビルドタグの変更:

    • 自動生成される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")を指すように変更されました。
  5. スクリプトの汎用化:

    • mkasmh.shmkgodefs.shスクリプトは、引数としてOSとアーキテクチャの組み合わせ(例: linux_amd64)を受け取るように変更されました。これにより、これらのスクリプトは特定のOS/アーキテクチャに依存しない汎用的なツールとして機能し、Makefile.autoから様々な組み合わせのファイルを生成できるようになりました。

コアとなるコードの変更箇所

このコミットのコアとなる変更は、以下のファイルに集中しています。

  1. src/pkg/runtime/Makefile.auto (新規作成):

    • このファイルは、Goランタイムの自動生成ファイルのビルドロジックをすべてカプセル化しています。
    • AUTO変数に、生成されるすべてのzプレフィックス付きファイルがリストされています。
    • goc2c, mkversion, mkgodefs.sh, mkasmh.shといったツールを呼び出すための具体的なルールが定義されています。
  2. src/pkg/runtime/Makefile (変更):

    • 自動生成ファイルに関する古いルールがすべて削除されました。
    • GOFILESおよびOFILESリストが更新され、新しいzプレフィックス付きの自動生成ファイルが参照されるようになりました。
    • clean-localターゲットがMakefile.autocleanターゲットを呼び出すように変更されました。
  3. src/make.bash (変更):

    • ビルドシーケンスが変更され、pkg/runtimeの通常のビルドの前にMakefile.autoが実行されるようになりました。
  4. src/pkg/runtime/defs*.go ファイル群 (変更):

    • これらのファイルの先頭に// +build ignoreディレクティブが追加されました。
  5. 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変数には、これらの組み合わせに基づいて生成されるすべてのファイル名がリストされています。%はワイルドカードとして機能し、GOARCHESGOOSARCHESの各要素に展開されます。
  • all: autoauto: $(AUTO)は、make autoを実行すると、AUTOリスト内のすべてのファイルが生成されることを意味します。
  • 続くルール(z%_386.c: %.goc goc2cなど)は、それぞれの自動生成ファイルをどのように作成するかを定義しています。例えば、zmalloc_386.cmalloc.gocgoc2cツールから生成されます。
  • zruntime_defs_%.gozasm_%.hのルールでは、mkgodefs.shmkasmh.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内に直接記述されており、以下のような問題を引き起こしていました。

  1. Makefileの複雑化: 自動生成ロジックと通常のビルドロジックが混在し、Makefileが肥大化し、理解や保守が困難になっていました。
  2. 依存関係の不明瞭さ: どのファイルが自動生成され、どのファイルが手書きなのかが曖昧になり、ビルドの依存関係を追跡しにくくなっていました。
  3. クリーンアップの課題: 自動生成されたファイルを適切にクリーンアップするためのルールが散在し、ビルド環境を完全にクリーンな状態に戻すのが難しい場合がありました。
  4. ビルド順序の管理: 自動生成されたファイルが、それらを使用する他のファイルよりも先に生成されることを保証するためのビルド順序の管理が複雑でした。

このコミットは、これらの問題を解決するために、自動生成ファイルの生成プロセスを専用のMakefile.autoに分離し、ビルドシステム全体の構造を改善することを目的としています。

前提知識の解説

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

  1. Go言語のランタイム (Runtime): Goプログラムが実行される際に、メモリ管理(ガベージコレクション)、スケジューリング(ゴルーチン)、システムコール、ネットワークI/Oなどを担当する低レベルな部分です。Goランタイムは、Go言語自体で書かれている部分と、C言語やアセンブリ言語で書かれている部分が混在しています。
  2. Makefile: makeユーティリティが使用するビルド自動化スクリプトです。ソースコードのコンパイル、リンク、テストなどのタスクを定義し、ファイルの依存関係に基づいて必要なタスクのみを実行します。
  3. 自動生成ファイル: ソースコードから別のソースコードや設定ファイルを自動的に生成するプロセスです。Go言語のビルドでは、OSやアーキテクチャ固有の定数、構造体のオフセット、バージョン情報などが自動生成されることがあります。
  4. goc2c: Go言語のC言語との連携機能(cgo)の一部として、.gocファイルをC言語のソースファイルに変換するツールです。.gocファイルは、GoとCのコードを混在させて記述できる特殊なファイル形式です。
  5. mkasmh.sh: アセンブリコードで使用するヘッダーファイルを生成するシェルスクリプトです。Goランタイムのアセンブリコードは、C言語の構造体のオフセットなどの情報に依存することがあり、これらのオフセットはビルド時に決定されるため、自動生成されます。
  6. mkgodefs.sh: C言語の構造体定義からGo言語の構造体定義を生成するシェルスクリプトです。これにより、C言語で定義されたデータ構造をGo言語から安全に利用できるようになります。
  7. mkversion: Goのバージョン情報を埋め込んだGoソースファイルを生成するツールです。
  8. +build ディレクティブ: Goのソースファイルに記述されるビルドタグです。特定のOS、アーキテクチャ、またはカスタムタグに基づいて、ファイルのコンパイルを制御します。+build ignoreは、そのファイルをGoツールチェーンが直接コンパイルしないように指示します。これは、そのファイルが別のツールによって処理される入力ファイルであることを示唆します。
  9. z プレフィックス: このコミットで導入された、自動生成されたファイルに付けられる新しい命名規則です。これにより、手書きのファイルと自動生成されたファイルを視覚的に区別しやすくなります。

技術的詳細

このコミットの技術的な核心は、Goランタイムのビルドプロセスにおける自動生成ファイルの管理方法の再構築にあります。

  1. 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ターゲットも定義されており、自動生成されたファイルを一括で削除できるようになりました。
  2. メインMakefileからのロジック分離:

    • src/pkg/runtime/Makefileから、自動生成ファイルに関するすべてのルール(version.goの生成、runtime_defs.goの生成、goc2cmkversionのビルドなど)が削除されました。
    • これにより、メインのMakefileは、手書きのソースファイルのコンパイルとリンクに集中できるようになり、大幅に簡素化されました。
    • CLEANFILESからも自動生成ファイルが削除され、clean-localターゲットがMakefile.autocleanターゲットを呼び出すように変更されました。
  3. ビルドスクリプトの変更:

    • 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)が明示的にビルドされるようになりました。
  4. ファイル命名規則とビルドタグの変更:

    • 自動生成される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")を指すように変更されました。
  5. スクリプトの汎用化:

    • mkasmh.shmkgodefs.shスクリプトは、引数としてOSとアーキテクチャの組み合わせ(例: linux_amd64)を受け取るように変更されました。これにより、これらのスクリプトは特定のOS/アーキテクチャに依存しない汎用的なツールとして機能し、Makefile.autoから様々な組み合わせのファイルを生成できるようになりました。

コアとなるコードの変更箇所

このコミットのコアとなる変更は、以下のファイルに集中しています。

  1. src/pkg/runtime/Makefile.auto (新規作成):

    • このファイルは、Goランタイムの自動生成ファイルのビルドロジックをすべてカプセル化しています。
    • AUTO変数に、生成されるすべてのzプレフィックス付きファイルがリストされています。
    • goc2c, mkversion, mkgodefs.sh, mkasmh.shといったツールを呼び出すための具体的なルールが定義されています。
  2. src/pkg/runtime/Makefile (変更):

    • 自動生成ファイルに関する古いルールがすべて削除されました。
    • GOFILESおよびOFILESリストが更新され、新しいzプレフィックス付きの自動生成ファイルが参照されるようになりました。
    • clean-localターゲットがMakefile.autocleanターゲットを呼び出すように変更されました。
  3. src/make.bash (変更):

    • ビルドシーケンスが変更され、pkg/runtimeの通常のビルドの前にMakefile.autoが実行されるようになりました。
  4. src/pkg/runtime/defs*.go ファイル群 (変更):

    • これらのファイルの先頭に// +build ignoreディレクティブが追加されました。
  5. 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変数には、これらの組み合わせに基づいて生成されるすべてのファイル名がリストされています。%はワイルドカードとして機能し、GOARCHESGOOSARCHESの各要素に展開されます。
  • all: autoauto: $(AUTO)は、make autoを実行すると、AUTOリスト内のすべてのファイルが生成されることを意味します。
  • 続くルール(z%_386.c: %.goc goc2cなど)は、それぞれの自動生成ファイルをどのように作成するかを定義しています。例えば、zmalloc_386.cmalloc.gocgoc2cツールから生成されます。
  • zruntime_defs_%.gozasm_%.hのルールでは、mkgodefs.shmkasmh.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氏のブログなど)