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

[インデックス 157] ファイルの概要

コミット

コミットハッシュ: 69b74c3953eac1a28febb893d1e8e383ffbe5209 作者: Rob Pike r@golang.org 日付: Thu Jun 12 13:26:16 2008 -0700

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/69b74c3953eac1a28febb893d1e8e383ffbe5209

元コミット内容

    import the plan 9 libraries libc (lib9) and libbio into the tree.
    remove the dependency on /home/r.
    
    SVN=122482

変更の背景

このコミットは、Go言語の初期開発段階における重要なマイルストーンを示しています。変更の主な背景は、Goプロジェクトが外部の依存関係、特にRob Pike個人の開発環境(/home/r)に依存している状態から脱却し、自己完結性を高めることにありました。

Go言語は、ベル研究所のPlan 9オペレーティングシステムの影響を強く受けています。初期のGoコンパイラやツールチェインは、Plan 9のCコンパイラやリンカ、そしてPlan 9の標準ライブラリ(libclibbioなど)に大きく依存していました。しかし、Goが独立したプロジェクトとして成長するためには、これらの依存関係をGo自身のソースツリー内に取り込み、外部環境への依存をなくす必要がありました。

具体的には、/home/r/plan9/include/home/r/plan9/lib といったパスへの参照がMakefile内に存在しており、これはRob Pikeのローカル環境に強く結びついていました。この依存関係は、他の開発者がGoのソースコードをビルドしたり、開発に参加したりする上で大きな障壁となります。このコミットは、これらのPlan 9由来のライブラリをGoのリポジトリ内に直接インポートすることで、ビルドプロセスを標準化し、Goプロジェクトのポータビリティと独立性を向上させることを目的としています。

前提知識の解説

Plan 9 from Bell Labs

Plan 9 from Bell Labsは、ベル研究所で開発された分散オペレーティングシステムです。Unixの設計思想をさらに推し進め、すべてのリソース(ファイル、デバイス、ネットワーク接続など)をファイルシステムとして表現するという「すべてはファイルである」という原則を徹底しています。Go言語の設計者であるRob Pike、Ken Thompson、Robert Griesemerは、いずれもPlan 9の開発に深く関わっていました。そのため、Go言語の設計にはPlan 9の哲学や概念が色濃く反映されています。

libc (Plan 9版)

Plan 9におけるlibcは、標準Cライブラリの実装です。一般的なUnix系システムのlibcと同様に、ファイルI/O、メモリ管理、文字列操作、プロセス制御などの基本的なシステムコールやユーティリティ関数を提供します。しかし、Plan 9のlibcは、そのOSの設計思想に合わせて、Unixのそれとは異なるAPIやセマンティクスを持つ部分があります。例えば、Plan 9のファイルシステムプロトコルである9P(またはPlan 9 File System Protocol)に特化した関数などが含まれます。

libbio (Plan 9版)

libbioは、Plan 9におけるバッファリングI/Oライブラリです。Unixにおけるstdio(Standard I/O)ライブラリに相当しますが、Plan 9のI/Oモデルに合わせて設計されています。効率的なファイル読み書きのために内部バッファを使用し、BgetcBputcBreadBwriteなどの関数を提供します。Go言語の初期のI/O処理は、このlibbioの概念や実装から影響を受けていると考えられます。

Rob Pike (r@golang.org)

Rob Pikeは、Go言語の共同設計者の一人であり、ベル研究所でUnix、Plan 9、Infernoなどの開発に携わった著名なコンピュータ科学者です。彼のメールアドレスであるr@golang.orgは、Goプロジェクトにおける彼の初期の貢献と、彼がGoの初期開発環境のセットアップに深く関わっていたことを示しています。このコミットで/home/rへの依存が削除されたことは、Goプロジェクトが個人の環境から独立し、より広範な開発コミュニティに開かれるための重要なステップでした。

技術的詳細

このコミットの技術的な核心は、Go言語のビルドシステムとランタイムが、外部のPlan 9環境に依存することなく、自己完結的に動作できるようにすることです。

  1. ソースコードのインポート:

    • include/bio.h, include/fmt.h, include/libc.h, include/u.h といったヘッダーファイルがGoのリポジトリのinclude/ディレクトリに新しく追加されています。これらはPlan 9の標準ヘッダーであり、GoのCコード(特に初期のランタイムやツールチェインの一部)がこれらの定義に依存していたことを示しています。
    • src/lib9/src/libbio/ ディレクトリが新設され、それぞれPlan 9のlibclibbioの実装ファイル(.cファイル)が大量にインポートされています。これには、文字列操作、I/O、プロセス管理、フォーマット(fmtディレクトリ内のファイル)など、多岐にわたる機能が含まれています。特にsrc/lib9/utf/にはUTF-8関連のユーティリティが含まれており、Goが最初からUnicodeを重視していたことが伺えます。
  2. Makefileの変更:

    • src/cmd/6a/Makefile, src/cmd/6c/Makefile, src/cmd/6g/Makefile, src/cmd/6l/Makefile, src/cmd/cc/Makefile, src/cmd/gc/Makefile など、Goの各種ツール(アセンブラ、Cコンパイラ、Goコンパイラ、リンカなど)のMakefileが変更されています。
    • 変更内容は、CFLAGSから-I/home/r/plan9/includeのパスを削除し、代わりに-I$(GOROOT)/includeを使用するように修正している点です。これにより、Goのビルドシステムは、Go自身のソースツリー内のincludeディレクトリを参照するようになります。
    • 同様に、リンカのオプションも-L/home/r/plan9/libから-L$(GOROOT)/libに変更され、Go自身のライブラリパスを参照するようになります。
    • src/lib9/Makefilesrc/libbio/Makefileが新しく追加され、これらのライブラリがGoのビルドシステム内でどのようにコンパイルされ、アーカイブ(.aファイル)として生成されるかが定義されています。
  3. ビルドプロセスの独立性:

    • これらの変更により、Goのビルドは外部のPlan 9環境に依存せず、Goのソースツリー自体に含まれるPlan 9由来のライブラリを使用して完結するようになります。これは、Goのクロスプラットフォーム対応や、より広範な開発者による貢献を可能にする上で不可欠なステップでした。
    • src/clean.bashスクリプトも更新され、新しくインポートされたlib9libbioのクリーンアップ処理が追加されています。

このコミットは、Go言語がPlan 9の思想を受け継ぎつつも、独立したモダンなプログラミング言語としての基盤を確立していく過程の一部を示しています。Plan 9の堅牢なCライブラリをGoの初期ランタイムに組み込むことで、Goは安定した低レベル機能を手に入れ、その後の発展の土台を築きました。

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

このコミットでは、主に以下のファイルが新規追加または変更されています。

  • 新規追加されたヘッダーファイル:
    • include/bio.h
    • include/fmt.h
    • include/libc.h
    • include/u.h
  • 新規追加されたライブラリソースディレクトリとファイル:
    • src/lib9/ ディレクトリとその配下の多数の .c ファイル (例: _exits.c, _p9dir.c, atoi.c, await.c, cleanname.c, create.c, errstr.c, exec.c, getenv.c, getfields.c, notify.c, open.c, pipe.c, readn.c, rfork.c, seek.c, sysfatal.c, tokenize.c など)
    • src/lib9/fmt/ ディレクトリとその配下の多数の .c ファイル (例: dofmt.c, fltfmt.c, fmt.c, fmtprint.c, fmtquote.c, print.c, sprint.c など)
    • src/lib9/utf/ ディレクトリとその配下の多数の .c ファイル (例: rune.c, utflen.c, runetype.c など)
    • src/libbio/ ディレクトリとその配下の多数の .c ファイル (例: bbuffered.c, bflush.c, bgetc.c, binit.c, bprint.c, bread.c, bwrite.c など)
  • 新規追加されたMakefile:
    • src/lib9/Makefile
    • src/libbio/Makefile
  • 変更されたMakefile (既存のGoツールチェイン関連):
    • src/cmd/6a/Makefile
    • src/cmd/6c/Makefile
    • src/cmd/6g/Makefile
    • src/cmd/6l/Makefile
    • src/cmd/cc/Makefile
    • src/cmd/gc/Makefile
  • 変更されたスクリプト:
    • src/clean.bash

コアとなるコードの解説

include/bio.h

このヘッダーファイルは、Plan 9のバッファリングI/Oライブラリであるlibbioのインターフェースを定義しています。Biobuf構造体はバッファリングI/Oの状態を保持し、BsizeBungetsizeなどの定数がバッファサイズやアンゲットバッファのサイズを定義しています。Bgetc, Bputc, Bread, Bwriteなどの関数プロトタイプが宣言されており、これらはファイルからの読み書きをバッファリングして効率化するためのものです。Go言語の初期のI/Oシステムは、このlibbioの設計に強く影響を受けています。

include/fmt.h

このヘッダーファイルは、Plan 9のフォーマットライブラリであるlibfmtのインターフェースを定義しています。C言語におけるprintfのような機能を提供しますが、より柔軟で拡張性のある設計になっています。Fmt構造体はフォーマット処理の状態を保持し、dofmt, fmtprint, fprint, printなどの関数プロトタイプが宣言されています。これらは、様々なデータ型を文字列にフォーマットしたり、ファイルディスクリプタや文字列バッファに出力したりするために使用されます。Go言語のfmtパッケージのルーツはここにあります。

include/libc.h

このヘッダーファイルは、Plan 9の標準Cライブラリlib9の主要なインターフェースを定義しています。一般的なUnixのlibcに似ていますが、Plan 9特有の機能やGo言語の初期のニーズに合わせて調整されています。strecpy, tokenize, cleanname, exits, getenv, getfields, sysfatal, rfork, create, open, pipe, readn, seek, waitなど、多岐にわたるシステムコールやユーティリティ関数のプロトタイプが含まれています。特に、rforkはPlan 9のプロセス生成メカニズムであり、Goのgoroutineやスケジューラの実装に影響を与えた可能性があります。

include/u.h

このヘッダーファイルは、Plan 9のユーザー空間プログラムで共通して使用される基本的な型定義やマクロを含んでいます。uchar, ushort, uint, ulong, uvlong, vlongなどの符号なし/符号付き整数型や、p9jmp_bufのようなジャンプバッファの型が定義されています。また、様々なOS(Linux, SunOS, FreeBSD, macOSなど)に対応するための条件付きコンパイルディレクティブが含まれており、Plan 9 Portプロジェクト(Plan 9のツールやライブラリをUnix系システムに移植したもの)の遺産であることが伺えます。Go言語の初期のクロスプラットフォーム対応において、これらの型定義やOS固有の調整が役立ったと考えられます。

src/lib9/Makefile および src/libbio/Makefile

これらのMakefileは、Goのビルドシステム内でlib9libbioをどのようにコンパイルし、アーカイブライブラリ(.aファイル)として生成するかを定義しています。各ライブラリを構成するオブジェクトファイル(.oファイル)のリストが指定され、Cコンパイラ($(CC))とリンカ(ar)を使用してライブラリがビルドされます。これにより、Goのツールチェインがこれらのライブラリを内部的に利用できるようになります。

src/cmd/*/Makefile の変更

Goの各種コマンド(6a, 6c, 6g, 6l, cc, gc)のMakefileでは、コンパイルフラグ(CFLAGS)とリンカフラグ(-L)から、Rob Pikeのローカル環境への絶対パス(/home/r/plan9/include/home/r/plan9/lib)が削除され、代わりにGoのインストールルート($(GOROOT))内の相対パスが使用されるようになっています。これは、Goのビルドシステムが自己完結的になり、外部環境に依存しなくなるための重要な変更です。

関連リンク

参考にした情報源リンク