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

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

このコミットは、Go言語のビルドシステムにおいて、Plan 9オペレーティングシステム向けのlibc.hヘッダーファイルに不足していた関数宣言を追加するものです。具体的には、Goの実行環境に関する情報を取得する関数(getgoarm, getgo386)と、コマンドライン引数解析に関連するflagパッケージの内部関数群の宣言が追加されています。これにより、Plan 9環境でのGoのビルドと実行の整合性が向上します。

コミット

commit 39ffa83fdbbb21d59ecc07afb201b3839968587b
Author: Lucio De Re <lucio.dere@gmail.com>
Date:   Fri Jan 11 16:58:46 2013 -0800

    build: add missing function declarations for Plan 9
    
    R=golang-dev, minux.ma, rsc, ality, seed
    CC=golang-dev
    https://golang.org/cl/7034052
---
 include/plan9/libc.h | 12 ++++++++++++\n 1 file changed, 12 insertions(+)\n

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

https://github.com/golang/go/commit/39ffa83fdbbb21d59ecc07afb201b3839968587b

元コミット内容

build: add missing function declarations for Plan 9

このコミットは、Go言語のビルドプロセスにおいて、Plan 9オペレーティングシステム向けに不足していた関数宣言をinclude/plan9/libc.hに追加するものです。

変更の背景

Go言語は、その設計思想の一つとして、様々なオペレーティングシステムやアーキテクチャへの対応を重視しています。Goのビルドシステムは、GOOS(ターゲットOS)とGOARCH(ターゲットアーキテクチャ)という環境変数を用いて、異なるプラットフォーム向けのバイナリを生成するクロスコンパイル機能を強力にサポートしています。

Plan 9は、ベル研究所で開発された分散オペレーティングシステムであり、Go言語の開発者の一部がその設計に深く関わっていたこともあり、Go言語は初期からPlan 9をサポート対象としていました。

このコミットが行われた2013年当時、Go言語のビルドツールやランタイムは進化の途上にあり、特定のプラットフォーム(この場合はPlan 9)において、必要なC言語の関数宣言が不足しているケースがありました。Goのランタイムや標準ライブラリの一部は、C言語で書かれた低レベルなシステムコールやユーティリティ関数に依存しています。これらのC関数がGoのコードから呼び出される際、適切なヘッダーファイルにその宣言が存在しないと、コンパイルエラーやリンクエラーが発生し、Goプログラムが正しくビルドまたは実行できない問題が生じます。

具体的には、Goの環境変数(GOARM, GO386など)を取得する内部関数や、Goの標準ライブラリであるflagパッケージがコマンドライン引数を解析するために内部的に使用する関数群の宣言が、Plan 9向けのlibc.hに欠けていました。これらの宣言を追加することで、Plan 9環境でのGoのビルドが正常に完了し、Goプログラムが期待通りに動作するようになります。これは、Go言語のマルチプラットフォーム対応を強化し、Plan 9ユーザーがGoをより円滑に利用できるようにするための、ビルドシステムのメンテナンスの一環です。

前提知識の解説

Plan 9 from Bell Labs

Plan 9 from Bell Labsは、ベル研究所で開発された分散オペレーティングシステムです。Unixの後継として設計され、"Everything is a file"(すべてはファイルである)という哲学に基づいています。ネットワーク透過性、リソースの仮想化、UTF-8の採用など、多くの革新的な概念を導入しました。Go言語の開発者であるRob PikeやKen ThompsonもPlan 9の開発に深く関わっており、Go言語の設計思想にもPlan 9の影響が見られます。Go言語は、初期からPlan 9を公式にサポートするOSの一つとしていました。

Go言語のビルドシステムとクロスコンパイル

Go言語のビルドシステムは非常に強力で、異なるオペレーティングシステム(GOOS)とCPUアーキテクチャ(GOARCH)の組み合わせに対して、単一のコマンドでバイナリを生成する「クロスコンパイル」を容易に行うことができます。例えば、Linux上でWindows向けの実行ファイルをビルドしたり、ARMプロセッサ向けのバイナリを生成したりすることが可能です。

Goのビルドプロセスでは、Goのソースコードだけでなく、C言語で書かれた部分(特にランタイムや一部のシステムコール)もコンパイルされます。この際、ターゲットとなるOSやアーキテクチャに応じたCヘッダーファイルが必要となります。

libc.h

libc.hは、C言語の標準ライブラリ(libc)の関数宣言を含むヘッダーファイルです。Unix系システムでは、stdio.h, stdlib.h, string.hなど、様々な標準ライブラリのヘッダーファイルが存在しますが、libc.hはこれらの一部または全体をまとめた、あるいは特定のシステムコールや低レベル関数に特化した宣言を含む場合があります。Go言語の内部では、C言語で書かれたランタイムコードが、OS固有の機能にアクセスするためにこれらのC関数を呼び出すことがあります。そのため、Goのビルドシステムは、ターゲットOSごとに適切なlibc.hのようなヘッダーファイルを提供する必要があります。

flagパッケージ

Go言語の標準ライブラリであるflagパッケージは、コマンドライン引数を解析するための機能を提供します。プログラムが起動される際に渡されるオプション(例: -port 8080, -debug)を簡単に定義し、その値をGoの変数にバインドすることができます。このパッケージは、Goプログラムがユーザーからの入力を受け取るための基本的なインターフェースの一つです。内部的には、引数の解析やエラーハンドリングのために、いくつかのヘルパー関数を使用しています。

技術的詳細

このコミットは、Go言語のソースツリー内のinclude/plan9/libc.hファイルに、以下の関数宣言を追加しています。

  1. char* getgoarm(void);

  2. char* getgo386(void);

    これらは、Goのビルド環境変数であるGOARMおよびGO386の値をGoランタイムから取得するための内部関数です。

    • GOARMは、ARMアーキテクチャ向けのGoバイナリをビルドする際に、特定のARMバージョン(例: GOARM=5, GOARM=7)を指定するために使用されます。これにより、生成されるバイナリが特定のARMプロセッサの機能セット(例: 浮動小数点演算ユニットの有無)に最適化されます。
    • GO386は、386(i386)アーキテクチャ向けのGoバイナリをビルドする際に、特定の最適化レベルや機能セットを指定するために使用されることがあります。 これらの関数がlibc.hに宣言されていないと、Goのランタイムがこれらの環境変数の値にアクセスしようとした際に、Cコンパイラが関数の存在を知らず、コンパイルエラーやリンクエラーが発生します。
  3. void flagcount(char*, char*, int*);

  4. void flagint32(char*, char*, int32*);

  5. void flagint64(char*, char*, int64*);

  6. void flagstr(char*, char*, char**);

  7. void flagparse(int*, char***, void (*usage)(void));

  8. void flagfn0(char*, char*, void(*fn)(void));

  9. void flagfn1(char*, char*, void(*fn)(char*));

  10. void flagfn2(char*, char*, void(*fn)(char*, char*));

  11. void flagprint(int);

    これらは、Goのflagパッケージが内部的に使用するC言語のヘルパー関数群の宣言です。flagパッケージは、Goのコードからコマンドライン引数を解析するために利用されますが、その実装の一部はC言語で書かれた低レベルな関数に依存しています。

    • flagcount, flagint32, flagint64, flagstr: それぞれ、フラグの出現回数、32ビット整数、64ビット整数、文字列型のフラグを処理するための関数です。
    • flagparse: コマンドライン引数の解析を実行する主要な関数です。usage関数へのポインタを受け取り、解析エラー時にヘルプメッセージを表示するために使用されます。
    • flagfn0, flagfn1, flagfn2: 特定のフラグが指定されたときに呼び出されるコールバック関数を登録するための関数です。引数の数に応じて異なるバージョンがあります。
    • flagprint: フラグのヘルプメッセージなどを表示するための関数です。

これらのflag関連の関数宣言が不足していると、flagパッケージを使用するGoプログラムをPlan 9向けにビルドしようとした際に、Cコンパイラがこれらの内部関数のプロトタイプを知らないため、コンパイルエラーが発生します。

このコミットは、これらの不足していた宣言をlibc.hに追加することで、Plan 9環境におけるGoのビルドプロセスを完全なものにし、Goプログラムが正しくコンパイル・リンクされることを保証します。これは、Go言語のクロスプラットフォーム対応の堅牢性を高める上で重要な修正です。

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

diff --git a/include/plan9/libc.h b/include/plan9/libc.h
index d13ddbcb7f..0870a5b4af 100644
--- a/include/plan9/libc.h
+++ b/include/plan9/libc.h
@@ -14,3 +14,15 @@ char*	getgoos(void);\n char*	getgoarch(void);\n char*	getgoroot(void);\n char*	getgoversion(void);\n+char*\tgetgoarm(void);\n+char*\tgetgo386(void);\n+\n+void\tflagcount(char*, char*, int*);\n+void\tflagint32(char*, char*, int32*);\n+void\tflagint64(char*, char*, int64*);\n+void\tflagstr(char*, char*, char**);\n+void\tflagparse(int*, char***, void (*usage)(void));\n+void\tflagfn0(char*, char*, void(*fn)(void));\n+void\tflagfn1(char*, char*, void(*fn)(char*));\n+void\tflagfn2(char*, char*, void(*fn)(char*, char*));\n+void\tflagprint(int);\n

コアとなるコードの解説

変更はinclude/plan9/libc.hファイルに対して行われています。これは、Plan 9オペレーティングシステム向けのC言語ヘッダーファイルであり、Goのランタイムや標準ライブラリが内部的に使用するC関数の宣言を含んでいます。

追加された行は以下の通りです。

  • char* getgoarm(void);
    • Goのビルド環境変数GOARMの値を取得する関数の宣言。
  • char* getgo386(void);
    • Goのビルド環境変数GO386の値を取得する関数の宣言。
  • void flagcount(char*, char*, int*);
    • flagパッケージが内部で利用する、フラグの出現回数を処理する関数の宣言。
  • void flagint32(char*, char*, int32*);
    • flagパッケージが内部で利用する、32ビット整数型フラグを処理する関数の宣言。
  • void flagint64(char*, char*, int64*);
    • flagパッケージが内部で利用する、64ビット整数型フラグを処理する関数の宣言。
  • void flagstr(char*, char*, char**);
    • flagパッケージが内部で利用する、文字列型フラグを処理する関数の宣言。
  • void flagparse(int*, char***, void (*usage)(void));
    • flagパッケージが内部で利用する、コマンドライン引数解析のメイン関数の宣言。
  • void flagfn0(char*, char*, void(*fn)(void));
    • flagパッケージが内部で利用する、引数なしのコールバック関数を登録する関数の宣言。
  • void flagfn1(char*, char*, void(*fn)(char*));
    • flagパッケージが内部で利用する、引数1つのコールバック関数を登録する関数の宣言。
  • void flagfn2(char*, char*, void(*fn)(char*, char*));
    • flagパッケージが内部で利用する、引数2つのコールバック関数を登録する関数の宣言。
  • void flagprint(int);
    • flagパッケージが内部で利用する、フラグ関連の情報を出力する関数の宣言。

これらの宣言が追加されることで、Goのコンパイラとリンカは、Plan 9環境でGoプログラムをビルドする際に、これらのC関数が利用可能であることを認識できるようになります。これにより、以前は宣言不足によって発生していたコンパイルエラーやリンクエラーが解消され、Plan 9上でのGoのビルドと実行がスムーズに行われるようになります。これは、Go言語のクロスプラットフォーム対応の完全性を高めるための、基盤的な修正です。

関連リンク

参考にした情報源リンク

  • Go言語のソースコード(GitHubリポジトリ): https://github.com/golang/go
  • Go言語のコードレビューシステム (Gerrit): https://go.dev/cl/ (コミットメッセージに記載されているhttps://golang.org/cl/7034052は、このGerritの変更リストへのリンクです。)
  • Plan 9に関する一般的な情報源(Wikipediaなど)
  • Go言語のビルドプロセスに関する技術記事やドキュメントI have generated the commit explanation as requested. I will now output it to standard output.
# [インデックス 14873] ファイルの概要

このコミットは、Go言語のビルドシステムにおいて、Plan 9オペレーティングシステム向けの`libc.h`ヘッダーファイルに不足していた関数宣言を追加するものです。具体的には、Goの実行環境に関する情報を取得する関数(`getgoarm`, `getgo386`)と、コマンドライン引数解析に関連する`flag`パッケージの内部関数群の宣言が追加されています。これにより、Plan 9環境でのGoのビルドと実行の整合性が向上します。

## コミット

commit 39ffa83fdbbb21d59ecc07afb201b3839968587b Author: Lucio De Re lucio.dere@gmail.com Date: Fri Jan 11 16:58:46 2013 -0800

build: add missing function declarations for Plan 9

R=golang-dev, minux.ma, rsc, ality, seed
CC=golang-dev
https://golang.org/cl/7034052

include/plan9/libc.h | 12 ++++++++++++\n 1 file changed, 12 insertions(+)\n


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

[https://github.com/golang/go/commit/39ffa83fdbbb21d59ecc07afb201b3839968587b](https://github.com/golang/go/commit/39ffa83fdbbb21d59ecc07afb201b3839968587b)

## 元コミット内容

`build: add missing function declarations for Plan 9`

このコミットは、Go言語のビルドプロセスにおいて、Plan 9オペレーティングシステム向けに不足していた関数宣言を`include/plan9/libc.h`に追加するものです。

## 変更の背景

Go言語は、その設計思想の一つとして、様々なオペレーティングシステムやアーキテクチャへの対応を重視しています。Goのビルドシステムは、`GOOS`(ターゲットOS)と`GOARCH`(ターゲットアーキテクチャ)という環境変数を用いて、異なるプラットフォーム向けのバイナリを生成するクロスコンパイル機能を強力にサポートしています。

Plan 9は、ベル研究所で開発された分散オペレーティングシステムであり、Go言語の開発者の一部がその設計に深く関わっていたこともあり、Go言語は初期からPlan 9をサポート対象としていました。

このコミットが行われた2013年当時、Go言語のビルドツールやランタイムは進化の途上にあり、特定のプラットフォーム(この場合はPlan 9)において、必要なC言語の関数宣言が不足しているケースがありました。Goのランタイムや標準ライブラリの一部は、C言語で書かれた低レベルなシステムコールやユーティリティ関数に依存しています。これらのC関数がGoのコードから呼び出される際、適切なヘッダーファイルにその宣言が存在しないと、コンパイルエラーやリンクエラーが発生し、Goプログラムが正しくビルドまたは実行できない問題が生じます。

具体的には、Goの環境変数(`GOARM`, `GO386`など)を取得する内部関数や、Goの標準ライブラリである`flag`パッケージがコマンドライン引数を解析するために内部的に使用する関数群の宣言が、Plan 9向けの`libc.h`に欠けていました。これらの宣言を追加することで、Plan 9環境でのGoのビルドが正常に完了し、Goプログラムが期待通りに動作するようになります。これは、Go言語のマルチプラットフォーム対応を強化し、Plan 9ユーザーがGoをより円滑に利用できるようにするための、ビルドシステムのメンテナンスの一環です。

## 前提知識の解説

### Plan 9 from Bell Labs

Plan 9 from Bell Labsは、ベル研究所で開発された分散オペレーティングシステムです。Unixの後継として設計され、"Everything is a file"(すべてはファイルである)という哲学に基づいています。ネットワーク透過性、リソースの仮想化、UTF-8の採用など、多くの革新的な概念を導入しました。Go言語の開発者であるRob PikeやKen ThompsonもPlan 9の開発に深く関わっており、Go言語の設計思想にもPlan 9の影響が見られます。Go言語は、初期からPlan 9を公式にサポートするOSの一つとしていました。

### Go言語のビルドシステムとクロスコンパイル

Go言語のビルドシステムは非常に強力で、異なるオペレーティングシステム(`GOOS`)とCPUアーキテクチャ(`GOARCH`)の組み合わせに対して、単一のコマンドでバイナリを生成する「クロスコンパイル」を容易に行うことができます。例えば、Linux上でWindows向けの実行ファイルをビルドしたり、ARMプロセッサ向けのバイナリを生成したりすることが可能です。

Goのビルドプロセスでは、Goのソースコードだけでなく、C言語で書かれた部分(特にランタイムや一部のシステムコール)もコンパイルされます。この際、ターゲットとなるOSやアーキテクチャに応じたCヘッダーファイルが必要となります。

### `libc.h`

`libc.h`は、C言語の標準ライブラリ(libc)の関数宣言を含むヘッダーファイルです。Unix系システムでは、`stdio.h`, `stdlib.h`, `string.h`など、様々な標準ライブラリのヘッダーファイルが存在しますが、`libc.h`はこれらの一部または全体をまとめた、あるいは特定のシステムコールや低レベル関数に特化した宣言を含む場合があります。Go言語の内部では、C言語で書かれたランタイムコードが、OS固有の機能にアクセスするためにこれらのC関数を呼び出すことがあります。そのため、Goのビルドシステムは、ターゲットOSごとに適切な`libc.h`のようなヘッダーファイルを提供する必要があります。

### `flag`パッケージ

Go言語の標準ライブラリである`flag`パッケージは、コマンドライン引数を解析するための機能を提供します。プログラムが起動される際に渡されるオプション(例: `-port 8080`, `-debug`)を簡単に定義し、その値をGoの変数にバインドすることができます。このパッケージは、Goプログラムがユーザーからの入力を受け取るための基本的なインターフェースの一つです。内部的には、引数の解析やエラーハンドリングのために、いくつかのヘルパー関数を使用しています。

## 技術的詳細

このコミットは、Go言語のソースツリー内の`include/plan9/libc.h`ファイルに、以下の関数宣言を追加しています。

1.  **`char* getgoarm(void);`**
2.  **`char* getgo386(void);`**

    これらは、Goのビルド環境変数である`GOARM`および`GO386`の値をGoランタイムから取得するための内部関数です。
    *   `GOARM`は、ARMアーキテクチャ向けのGoバイナリをビルドする際に、特定のARMバージョン(例: `GOARM=5`, `GOARM=7`)を指定するために使用されます。これにより、生成されるバイナリが特定のARMプロセッサの機能セット(例: 浮動小数点演算ユニットの有無)に最適化されます。
    *   `GO386`は、386(i386)アーキテクチャ向けのGoバイナリをビルドする際に、特定の最適化レベルや機能セットを指定するために使用されることがあります。
    これらの関数が`libc.h`に宣言されていないと、Goのランタイムがこれらの環境変数の値にアクセスしようとした際に、Cコンパイラが関数の存在を知らず、コンパイルエラーやリンクエラーが発生します。

3.  **`void flagcount(char*, char*, int*);`**
4.  **`void flagint32(char*, char*, int32*);`**
5.  **`void flagint64(char*, char*, int64*);`**
6.  **`void flagstr(char*, char*, char**);`**
7.  **`void flagparse(int*, char***, void (*usage)(void));`**
8.  **`void flagfn0(char*, char*, void(*fn)(void));`**
9.  **`void flagfn1(char*, char*, void(*fn)(char*));`**
10. **`void flagfn2(char*, char*, void(*fn)(char*, char*));`**
11. **`void flagprint(int);`**

    これらは、Goの`flag`パッケージが内部的に使用するC言語のヘルパー関数群の宣言です。`flag`パッケージは、Goのコードからコマンドライン引数を解析するために利用されますが、その実装の一部はC言語で書かれた低レベルな関数に依存しています。
    *   `flagcount`, `flagint32`, `flagint64`, `flagstr`: それぞれ、フラグの出現回数、32ビット整数、64ビット整数、文字列型のフラグを処理するための関数です。
    *   `flagparse`: コマンドライン引数の解析を実行する主要な関数です。`usage`関数へのポインタを受け取り、解析エラー時にヘルプメッセージを表示するために使用されます。
    *   `flagfn0`, `flagfn1`, `flagfn2`: 特定のフラグが指定されたときに呼び出されるコールバック関数を登録するための関数です。引数の数に応じて異なるバージョンがあります。
    *   `flagprint`: フラグのヘルプメッセージなどを表示するための関数です。

これらの`flag`関連の関数宣言が不足していると、`flag`パッケージを使用するGoプログラムをPlan 9向けにビルドしようとした際に、Cコンパイラがこれらの内部関数のプロトタイプを知らないため、コンパイルエラーが発生します。

このコミットは、これらの不足していた宣言を`libc.h`に追加することで、Plan 9環境におけるGoのビルドプロセスを完全なものにし、Goプログラムが正しくコンパイル・リンクされることを保証します。これは、Go言語のクロスプラットフォーム対応の堅牢性を高める上で重要な修正です。

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

```diff
diff --git a/include/plan9/libc.h b/include/plan9/libc.h
index d13ddbcb7f..0870a5b4af 100644
--- a/include/plan9/libc.h
+++ b/include/plan9/libc.h
@@ -14,3 +14,15 @@ char*	getgoos(void);\n char*	getgoarch(void);\n char*	getgoroot(void);\n char*	getgoversion(void);\n+char*\tgetgoarm(void);\n+char*\tgetgo386(void);\n+\n+void\tflagcount(char*, char*, int*);\n+void\tflagint32(char*, char*, int32*);\n+void\tflagint64(char*, char*, int64*);\n+void\tflagstr(char*, char*, char**);\n+void\tflagparse(int*, char***, void (*usage)(void));\n+void\tflagfn0(char*, char*, void(*fn)(void));\n+void\tflagfn1(char*, char*, void(*fn)(char*));\n+void\tflagfn2(char*, char*, void(*fn)(char*, char*));\n+void\tflagprint(int);\n

コアとなるコードの解説

変更はinclude/plan9/libc.hファイルに対して行われています。これは、Plan 9オペレーティングシステム向けのC言語ヘッダーファイルであり、Goのランタイムや標準ライブラリが内部的に使用するC関数の宣言を含んでいます。

追加された行は以下の通りです。

  • char* getgoarm(void);
    • Goのビルド環境変数GOARMの値を取得する関数の宣言。
  • char* getgo386(void);
    • Goのビルド環境変数GO386の値を取得する関数の宣言。
  • void flagcount(char*, char*, int*);
    • flagパッケージが内部で利用する、フラグの出現回数を処理する関数の宣言。
  • void flagint32(char*, char*, int32*);
    • flagパッケージが内部で利用する、32ビット整数型フラグを処理する関数の宣言。
  • void flagint64(char*, char*, int64*);
    • flagパッケージが内部で利用する、64ビット整数型フラグを処理する関数の宣言。
  • void flagstr(char*, char*, char**);
    • flagパッケージが内部で利用する、文字列型フラグを処理する関数の宣言。
  • void flagparse(int*, char***, void (*usage)(void));
    • flagパッケージが内部で利用する、コマンドライン引数解析のメイン関数の宣言。
  • void flagfn0(char*, char*, void(*fn)(void));
    • flagパッケージが内部で利用する、引数なしのコールバック関数を登録する関数の宣言。
  • void flagfn1(char*, char*, void(*fn)(char*));
    • flagパッケージが内部で利用する、引数1つのコールバック関数を登録する関数の宣言。
  • void flagfn2(char*, char*, void(*fn)(char*, char*));
    • flagパッケージが内部で利用する、引数2つのコールバック関数を登録する関数の宣言。
  • void flagprint(int);
    • flagパッケージが内部で利用する、フラグ関連の情報を出力する関数の宣言。

これらの宣言が追加されることで、Goのコンパイラとリンカは、Plan 9環境でGoプログラムをビルドする際に、これらのC関数が利用可能であることを認識できるようになります。これにより、以前は宣言不足によって発生していたコンパイルエラーやリンクエラーが解消され、Plan 9上でのGoのビルドと実行がスムーズに行われるようになります。これは、Go言語のクロスプラットフォーム対応の完全性を高めるための、基盤的な修正です。

関連リンク

参考にした情報源リンク

  • Go言語のソースコード(GitHubリポジトリ): https://github.com/golang/go
  • Go言語のコードレビューシステム (Gerrit): https://go.dev/cl/ (コミットメッセージに記載されているhttps://golang.org/cl/7034052は、このGerritの変更リストへのリンクです。)
  • Plan 9に関する一般的な情報源(Wikipediaなど)
  • Go言語のビルドプロセスに関する技術記事やドキュメント