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

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

このコミットは、Go言語のビルドシステムの一部である cmd/dist ツールにおける変更を扱っています。具体的には、Plan 9オペレーティングシステム上でのフラグ解析の挙動を更新するために、src/cmd/dist/build.c ファイルが修正されました。

コミット

commit 0c026c45b4f26ffe88340a86e748d2ed8b1705f9
Author: Anthony Martin <ality@pbrane.org>
Date:   Fri Jan 18 15:19:51 2013 -0500

    cmd/dist: update for new flag parsing on Plan 9
    
    R=golang-dev, seed, rsc
    CC=golang-dev
    https://golang.org/cl/7069053
---
 src/cmd/dist/build.c | 6 +++++-\n 1 file changed, 5 insertions(+), 1 deletion(-)\n

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

https://github.com/golang/go/commit/0c026c45b4f26ffe88340a86e748d2ed8b1705f9

元コミット内容

このコミットは、src/cmd/dist/build.c ファイル内の shouldbuild 関数を変更しています。この関数は、特定のファイルがビルドプロセスに含まれるべきかどうかを決定します。変更は、gohostos が "plan9" である場合の条件分岐内にあります。

変更前は、dir が "lib9" であり、かつ file が "lib9/goos.c" でない場合、ビルドしない (return 0) となっていました。

変更後は、dir が "lib9" の場合、ファイル名 (lastelem(file)) が "goos.c" または "flag.c" であればビルドする (return 1) ように変更されました。それ以外の場合はビルドしない (return 0) となっています。

変更の背景

このコミットの背景には、Plan 9オペレーティングシステムにおけるGo言語のフラグ解析メカニズムの変更があります。Goのツールチェーンは、様々なオペレーティングシステムやアーキテクチャをサポートしており、それぞれの環境に特化したビルドロジックを持つことがあります。

cmd/dist はGoのソースコードからツールチェーンをビルドするためのプログラムであり、どのファイルをコンパイルに含めるかを決定する役割を担っています。Plan 9環境で新しいフラグ解析の仕組みが導入されたため、その新しい仕組みに関連するソースファイル(具体的には flag.c)がビルドプロセスに適切に含まれるように、cmd/dist のビルドロジックを更新する必要がありました。

これにより、Plan 9上でのGoツールチェーンが、新しいフラグ解析機能を正しく利用できるようになります。

前提知識の解説

Plan 9 from Bell Labs

Plan 9 from Bell Labsは、ベル研究所で開発された分散オペレーティングシステムです。Unixの設計思想をさらに推し進め、すべてのリソースをファイルとして表現し、ネットワーク透過性を重視しています。Go言語の開発者の一部(特にRob PikeやKen Thompson)はPlan 9の開発にも深く関わっており、Go言語の設計思想にもPlan 9の影響が見られます。Go言語が初期からPlan 9をサポートしていたのは、このような背景があるためです。

Go言語のビルドシステム (cmd/dist)

Go言語のソースコードからコンパイラ、リンカ、標準ライブラリなどのツールチェーンをビルドするプロセスは、cmd/dist というツールによって管理されています。cmd/dist は、Goのソースツリー内の様々なディレクトリやファイルを走査し、ターゲットとなるOSやアーキテクチャに応じて、どのファイルをコンパイルし、どのライブラリをリンクするかを決定します。これは、クロスコンパイルや異なる環境への対応を容易にするために非常に重要です。

フラグ解析 (Flag Parsing)

コマンドラインツールでは、ユーザーがオプションや引数を指定するために「フラグ」(またはオプション)を使用します。例えば、go build -o myapp main.go-o myapp の部分がフラグです。Go言語には標準ライブラリとして flag パッケージがあり、コマンドライン引数を解析するための機能を提供しています。このコミットで言及されている「新しいフラグ解析」は、Plan 9環境における flag パッケージの実装、またはその基盤となるC言語のコードに変更があったことを示唆しています。

lib9goos.c

Go言語のツールチェーンには、様々なOS固有のコードが含まれています。lib9 は、Plan 9環境に特化した低レベルのライブラリやユーティリティを含むディレクトリであると推測されます。goos.c は、GoのランタイムがOS固有の機能(例: システムコール、スレッド管理)とやり取りするためのC言語のコードを含むファイルであることが一般的です。各OSごとに goos.c のようなファイルが存在し、GoのランタイムとOSカーネル間のインターフェースを提供します。

技術的詳細

このコミットは、src/cmd/dist/build.c 内の shouldbuild 関数を変更しています。この関数は、Goのビルドプロセスにおいて、特定のソースファイルが現在のターゲットOS/アーキテクチャに対してビルドされるべきかどうかを判断します。

変更の核心は、Plan 9 (gohostos == "plan9") 環境における lib9 ディレクトリ内のファイルの扱い方です。

変更前:

if(streq(gohostos, "plan9")) {
    if(streq(dir, "lib9") && !hassuffix(file, "lib9/goos.c"))
        return 0; // lib9/goos.c 以外の lib9 内のファイルはビルドしない
    // ...
}

このロジックでは、lib9 ディレクトリ内のファイルのうち、goos.c 以外のすべてのファイルはビルド対象から除外されていました。これは、lib9 が主にPlan 9固有の低レベルなC言語のコードを含んでおり、その多くはGoのビルドプロセスには不要、あるいはGoのランタイムが直接利用する goos.c のみが特別に扱われるべき、という設計思想に基づいていたと考えられます。

変更後:

if(streq(gohostos, "plan9")) {
    if(streq(dir, "lib9")) {
        name = lastelem(file); // ファイル名を取得
        if(streq(name, "goos.c") || streq(name, "flag.c"))
            return 1; // goos.c または flag.c はビルドする
        return 0; // それ以外の lib9 内のファイルはビルドしない
    }
    // ...
}

この変更により、lib9 ディレクトリ内のファイルのうち、goos.c に加えて flag.c もビルド対象に含まれるようになりました。lastelem(file) はファイルパスの最後の要素(ファイル名)を取得する関数です。

これは、Plan 9環境でGoのフラグ解析機能が更新され、その新しい実装が flag.c というファイルに記述されていることを示唆しています。この flag.c がGoのツールチェーンの一部としてコンパイルされ、リンクされることで、Plan 9上でのGoプログラムが新しいフラグ解析ロジックを利用できるようになります。

この修正は、Goのビルドシステムが特定のOSの特性や、そのOS向けに導入された新しい機能に柔軟に対応していることを示しています。

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

src/cmd/dist/build.c ファイルの shouldbuild 関数内、約1053行目からの変更です。

--- a/src/cmd/dist/build.c
+++ b/src/cmd/dist/build.c
@@ -1053,8 +1053,12 @@ shouldbuild(char *file, char *dir)
 	// The main exception is libmach which has been modified
 	// in various places to support Go object files.
 	if(streq(gohostos, "plan9")) {
-		if(streq(dir, "lib9") && !hassuffix(file, "lib9/goos.c"))
+		if(streq(dir, "lib9")) {
+			name = lastelem(file);
+			if(streq(name, "goos.c") || streq(name, "flag.c"))
+				return 1;
 		return 0;
+		}
 	if(streq(dir, "libbio"))
 		return 0;
 	}

コアとなるコードの解説

変更されたコードブロックは、GoのビルドプロセスがPlan 9オペレーティングシステム上で実行されている場合に適用されます。

  1. if(streq(gohostos, "plan9")): 現在のホストOSがPlan 9であるかをチェックします。
  2. if(streq(dir, "lib9")): 現在処理しているファイルが lib9 ディレクトリ内にあるかをチェックします。
  3. name = lastelem(file);: ファイルパスからファイル名(例: goos.cflag.c)を抽出します。lastelem は、パスの最後のスラッシュ以降の部分を返すユーティリティ関数です。
  4. if(streq(name, "goos.c") || streq(name, "flag.c")): 抽出されたファイル名が "goos.c" または "flag.c" のいずれかであるかをチェックします。
  5. return 1;: 上記の条件が真であれば、そのファイルはビルド対象として含められます。
  6. return 0;: 上記の条件が偽であれば、そのファイルはビルド対象から除外されます。

この変更により、Plan 9環境において lib9/flag.c がGoツールチェーンのビルドプロセスに明示的に含まれるようになり、新しいフラグ解析機能が正しくコンパイル・リンクされることが保証されます。

関連リンク

参考にした情報源リンク