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

[インデックス 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.pkgsrc/cmd/Makefilesrc/pkg/runtime/Makefileなど、複数のMakefileが存在し、それぞれが特定のパッケージやコンポーネントのビルドを担当していました。
  • Makefile.auto: このコミットで削除されたsrc/pkg/runtime/Makefile.autoは、Goランタイムのビルドプロセスにおいて、OSやアーキテクチャに依存する自動生成ファイルを管理するための特別なMakefileでした。これには、zmalloc_%.czruntime1_%.czgoarch_%.gozasm_%.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ランタイムのビルドプロセスにおける自動生成ファイルの管理方法の変更に集約されます。

  1. Makefile.autoの削除と機能統合: 最も大きな変更は、src/pkg/runtime/Makefile.autoが完全に削除されたことです。このファイルは、Goランタイムのビルドにおいて、様々なOS/アーキテクチャ固有の自動生成ファイル(zmalloc_%.c, zruntime1_%.c, zgoarch_%.go, zasm_%.hなど)の生成を担っていました。これらの生成ロジックは、src/pkg/runtime/Makefileに直接統合されました。これにより、ビルド設定が一元化され、管理が簡素化されることが期待されます。

  2. 自動生成ファイルの命名規則の変更と直接的な生成:

    • 以前はzgoarch_$(GOARCH).gozgoos_$(GOOS).goといったファイルがMakefile.autoによって生成されていましたが、これらはそれぞれversion_$(GOARCH).goversion_$(GOOS).goに名称が変更され、src/pkg/runtime/Makefile内で直接生成されるようになりました。
    • zversion.goversion.goに名称変更され、mkversionツールによって生成されます。
    • アセンブリファイルでインクルードされていたzasm_GOOS_GOARCH.hは、asm_$(GOARCH).hというより簡潔な名前に変更され、mkasmh.shスクリプトによって生成されるようになりました。これにより、アセンブリファイル内のインクルードパスも簡素化されています。
  3. // +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タグが付与されていました。タグの削除は、ビルドシステムがこれらのファイルをより直接的に扱うようになったことを意味します。

  4. mkasmh.shmkgodefs.shの変更: これらのスクリプトは、OSやアーキテクチャの情報を引数として受け取るのではなく、環境変数GOOSGOARCHを直接利用するように変更されました。また、一時ファイルのコピーや削除のロジックが簡素化され、よりクリーンなスクリプトになりました。特にmkasmh.shは、runtime.acid.$GOARCHというファイルからアセンブリ定数を抽出するようになりました。これは、Cコンパイラが生成するデバッグ情報から構造体オフセットなどを取得する新しいメカニズムを示唆しています。

  5. src/Make.pkgsrc/cmd/Makefilesrc/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にロジックを集約することで、保守性を向上させる狙いがあったと考えられます。

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

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

  1. 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).gozgoos_$(GOOS).gozruntime_defs_$(GOOS)_$(GOARCH).goなどの古い自動生成ファイルが削除され、新しいファイル名が追加されました。
    • CFLAGSAFLAGSから-DGOOS_$(GOOS) -DGOARCH_$(GOARCH)の定義が削除されました。
  2. src/pkg/runtime/Makefile.auto:

    • ファイル全体が削除されました。
  3. 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") に変更されました。
  4. src/pkg/runtime/defs*.go (複数ファイル):

    • ファイルの先頭にあった// +build ignoreタグが削除されました。
  5. src/pkg/runtime/goc2c.c:

    • // +build ignoreタグが削除されました。
    • 自動生成を示すコメントprintf("// AUTO-GENERATED; run make\\n\\n");が削除されました。
  6. src/pkg/runtime/mkasmh.sh:

    • 引数からOS/ARCH情報を取得する代わりに、環境変数GOOSGOARCHを直接使用するように変更されました。
    • 一時ファイルのコピーと削除のロジックが簡素化されました。
    • runtime.acid.$GOARCHからアセンブリ定数を抽出するようになりました。
    • 自動生成を示すコメントが// AUTO-GENERATED; run make -f Makefile.autoから// AUTOMATICALLY GENERATED BY mkasmh.sh DURING BUILDに変更されました。
  7. src/pkg/runtime/mkgodefs.sh:

    • 引数からOS/ARCH情報を取得する代わりに、環境変数GOOSGOARCHを直接使用するように変更されました。
    • 自動生成を示すコメントが// AUTO-GENERATED; run make -f Makefile.autoから// AUTOMATICALLY GENERATED BY THE FOLLOWING COMMAND. DO NOT EDIT.に変更されました。
  8. src/pkg/runtime/mkversion.c:

    • // +build ignoreタグが削除されました。
    • 自動生成を示すコメントが// AUTO-GENERATED; run make -f Makefile.autoから// generated by mkversion.c; do not edit.に変更されました。
  9. src/Make.pkg:

    • アセンブリファイルのコンパイルコマンドから$(AFLAGS)が削除されました。
  10. src/cmd/Makefile:

    • DIRSリストから5c, 6c, 8cが削除され、$(O)cが追加されました。
    • gc.install 5c.install 6c.install 8c.install: cc.installgc.install $(O)c.install: cc.installに変更されました。
  11. src/make.bash:

    • pkg/runtimeの自動生成ファイルをMakefile.autoでビルドするステップが削除されました。
    • for i in lib9 libbio libmach cmdfor 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_*.gozgoos_*.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.shmkgodefs.shの改善: これらのスクリプトは、OSやアーキテクチャの情報を環境変数から直接取得するように変更され、より汎用性が高まりました。特にmkasmh.shruntime.acid.$GOARCHから情報を抽出するようになった点は注目に値します。これは、Cコンパイラのデバッグ出力からGoランタイムの内部構造に関する情報を動的に取得し、アセンブリコードに反映させるという、より高度な自動化が導入されたことを示しています。これにより、Goの内部データ構造が変更されても、アセンブリコードを手動で更新する必要が減り、開発の効率が向上します。

これらの変更は、Go言語の初期段階におけるビルドシステムの試行錯誤と成熟の過程を示しています。複雑な自動生成プロセスをよりシンプルで一元化された方法に移行することで、ビルドの信頼性と開発者の生産性を向上させることを目指しています。

関連リンク

参考にした情報源リンク