[インデックス 11551] ファイルの概要
このコミットは、Go言語プロジェクトのlib9
ライブラリに対する重要な変更を導入しています。主な目的は、lib9
を「自動ビルドに対して安全にする」こと、すなわち、異なるオペレーティングシステム(特にWindowsと非Windowsシステム)上でのビルドの堅牢性と移植性を向上させることです。具体的には、Unix固有の機能の削除または条件付きコンパイル、およびファイル名の命名規則の統一が行われています。
コミット
commit b53ce1e66221be41a0b869869ceba73b795c8c3e
Author: Russ Cox <rsc@golang.org>
Date: Wed Feb 1 18:25:40 2012 -0500
lib9: make safe for automatic builds
R=golang-dev, adg, bradfitz
CC=golang-dev
https://golang.org/cl/5615046
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/b53ce1e66221be41a0b869869ceba73b795c8c3e
元コミット内容
lib9: make safe for automatic builds
R=golang-dev, adg, bradfitz
CC=golang-dev
https://golang.org/cl/5615046
変更の背景
このコミットの背景には、Go言語がクロスプラットフォーム対応を強化し、様々な環境での自動ビルドプロセスをよりスムーズにするという目標があります。lib9
は、Plan 9オペレーティングシステムのCライブラリをUnix系システムに移植したものであり、Goの初期段階では低レベルのシステム操作や互換性レイヤーのために利用されていました。しかし、lib9
にはUnix固有の機能が多く含まれており、これがWindowsなどの非Unix環境でのビルドの障壁となっていました。
「自動ビルドに対して安全にする」という目的は、CI/CD(継続的インテグレーション/継続的デリバリー)システムや、開発者が異なるOS上でGoプロジェクトをビルドする際に、予期せぬコンパイルエラーやランタイムエラーが発生しないようにすることを示唆しています。特に、fork()
システムコールやerrno
に基づくエラー処理など、POSIX準拠のシステムに特化した機能は、Windowsでは利用できないか、異なる動作をするため、これらを適切に扱う必要がありました。
前提知識の解説
lib9
: Plan 9オペレーティングシステムの標準Cライブラリ(libc
)のサブセットを、Unix系システム(Linux, macOSなど)に移植したものです。Plan 9はベル研究所で開発された実験的なOSで、その設計思想やAPIはGo言語にも大きな影響を与えています。lib9
は、Goの初期のランタイムや標準ライブラリの一部で、Plan 9の哲学に基づいた低レベルの操作を提供するために使用されていました。- Goビルドタグ (
// +build
): Goのソースファイルに記述される特殊なコメントで、そのファイルがどの環境でコンパイルされるべきかを制御します。例えば、// +build windows
はWindowsでのみコンパイルされることを意味し、// +build !windows
はWindows以外のシステムでのみコンパイルされることを意味します。これにより、OS固有のコードを分離し、クロスプラットフォーム対応を容易にします。 fork()
システムコール: Unix系OSにおけるプロセス生成のためのシステムコールです。親プロセスを複製して新しい子プロセスを作成します。Windowsには直接的なfork()
に相当するAPIは存在せず、プロセス生成にはCreateProcess
などの異なるAPIを使用します。strerror(errno)
: C言語の標準ライブラリ関数で、グローバル変数errno
に格納されたエラーコードに対応するエラーメッセージ文字列を返します。errno
はPOSIX標準の一部であり、Unix系システムで広く使われるエラー報告メカニズムです。Windowsではエラー処理のメカニズムが異なります(例:GetLastError()
とFormatMessage()
)。
技術的詳細
このコミットは、lib9
のクロスプラットフォーム互換性を向上させるために、以下の主要な技術的変更を加えています。
-
Unix固有機能の削除:
src/lib9/fmt/errfmt.c
の削除: このファイルには__errfmt
関数が含まれており、内部でstrerror(errno)
を使用していました。errno
とstrerror
はUnix固有のエラー処理メカニズムであるため、これを削除することで、Goのエラー処理をよりポータブルな方法に統一するか、あるいはこの機能がもはやlib9
のスコープ外になったことを示しています。Go自体は独自の強力なエラー処理メカニズム(error
インターフェース)を持っているため、Cライブラリのerrno
に依存する部分は不要になったと考えられます。src/lib9/fork.c
の削除: このファイルにはp9fork
関数が含まれており、これはUnixのfork()
システムコールをラップしていました。fork()
はWindowsでは利用できないため、このファイルの削除は、lib9
が直接的なプロセスフォークに依存するのをやめ、Goのランタイムが提供するより抽象化されたプロセス管理機能(例:os/exec
パッケージ)に移行したことを意味します。これにより、Windows上でのビルド時のリンカーエラーやランタイムエラーが回避されます。
-
条件付きコンパイルの導入:
src/lib9/await.c
,src/lib9/getuser.c
,src/lib9/jmp.c
,src/lib9/notify.c
,src/lib9/rfork.c
の各ファイルの先頭に// +build !windows
ディレクティブが追加されました。これは、これらのファイルがWindows以外のシステムでのみコンパイルされるべきであることをGoのビルドシステムに指示します。これらのファイルは、それぞれawait
(子プロセスの終了待機)、getuser
(ユーザー情報の取得)、jmp
(setjmp
/longjmp
のような非ローカルジャンプ)、notify
(シグナル通知)、rfork
(Plan 9スタイルのリソースフォーク)といった、Unix系OSに特有の機能や概念に関連しています。これにより、Windowsビルドからこれらの非互換なコードが自動的に除外され、ビルドエラーを防ぎます。
-
ファイル名の命名規則の統一:
src/lib9/win32.c
がsrc/lib9/windows.c
にリネームされました。これは、Goの標準的な命名規則(OS名を小文字で統一する)に合わせるための変更です。Goのビルドタグもwindows
と小文字で記述されるため、ファイル名もそれに合わせることで、一貫性と可読性が向上します。Makefile
もこの変更に合わせてwin32.$O
からwindows.$O
に修正されています。
これらの変更は、lib9
がGoのクロスプラットフォーム戦略に適合し、より広範な環境で安定して動作するための基盤を固めるものです。
コアとなるコードの変更箇所
このコミットにおける主要なコード変更は以下の通りです。
-
src/lib9/Makefile
:--- a/src/lib9/Makefile +++ b/src/lib9/Makefile @@ -85,7 +85,7 @@ LIB9OFILES=\ ifeq ($(GOHOSTOS),windows) LIB9OFILES+=\ - win32.$O\ + windows.$O\ else LIB9OFILES+=\
win32.$O
というオブジェクトファイル名がwindows.$O
に変更されています。 -
src/lib9/await.c
,src/lib9/getuser.c
,src/lib9/jmp.c
,src/lib9/notify.c
,src/lib9/rfork.c
: これらの各ファイルの先頭に以下の行が追加されています。// +build !windows
-
src/lib9/fmt/errfmt.c
: ファイル全体が削除されました。--- a/src/lib9/fmt/errfmt.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * The authors of this software are Rob Pike and Ken Thompson, - * with contributions from Mike Burrows and Sean Dorward. - * ... (省略) ... - */ - -#include <u.h> -#include <libc.h> -#include "fmtdef.h" - -int -__errfmt(Fmt *f) -{ - char *s; - - s = strerror(errno); - return fmtstrcpy(f, s); -}
-
src/lib9/fork.c
: ファイル全体が削除されました。--- a/src/lib9/fork.c +++ /dev/null @@ -1,46 +0,0 @@ -/* -Plan 9 from User Space src/lib9/fork.c -... (省略) ... -*/ -#include <u.h> -#include <signal.h> -#include <libc.h> -#include "9proc.h" -#undef fork - -int -p9fork(void) -{ - int pid; - sigset_t all, old; - - sigfillset(&all); - sigprocmask(SIG_SETMASK, &all, &old); - pid = fork(); - if(pid == 0){ - _clearuproc(); - _p9uproc(0); - } - sigprocmask(SIG_SETMASK, &old, nil); - return pid; -}
-
src/lib9/win32.c
: ファイル名がsrc/lib9/windows.c
にリネームされました。内容に変更はありません。
コアとなるコードの解説
-
Makefile
の変更: この変更は、ビルドシステムがWindows固有のオブジェクトファイルをリンクする際に、新しい命名規則windows.$O
を使用するように指示しています。これは、ファイル名のリネームと同期した変更であり、ビルドプロセスの一貫性を保つために不可欠です。 -
// +build !windows
ディレクティブの追加: これはGoのビルドタグの典型的な使用例です。await.c
、getuser.c
、jmp.c
、notify.c
、rfork.c
といったファイルは、Unix系システムに深く根ざした機能を提供しています。例えば、await.c
は子プロセスの終了を待つ機能、jmp.c
はC言語のsetjmp
/longjmp
に似た非ローカルジャンプ機能を提供している可能性があります。これらの機能はWindowsでは異なるAPIで実装されるか、Goのランタイムが提供する抽象化された機能で代替されるため、Windowsビルドから除外することで、コンパイルエラーや互換性の問題を回避します。 -
errfmt.c
の削除:errfmt.c
はstrerror(errno)
を使用してエラーメッセージをフォーマットしていました。Goは独自の強力なエラー処理メカニズム(error
インターフェース)を持っているため、C言語のerrno
に依存するこの種のユーティリティは、Goの標準ライブラリやランタイムの進化に伴い不要になったか、よりGoらしい方法で再実装されたと考えられます。これにより、lib9
の依存関係が簡素化され、クロスプラットフォームでのエラー処理の統一が図られます。 -
fork.c
の削除:fork.c
はUnixのfork()
システムコールをラップしていました。Goは軽量な並行処理の単位であるゴルーチン(goroutine)と、それらを管理するランタイムを持っています。プロセス生成に関しても、os/exec
パッケージなどを通じてOSに依存しない抽象化されたインターフェースを提供しています。fork.c
の削除は、lib9
が直接的なfork()
の使用から脱却し、Goのネイティブな並行処理およびプロセス管理モデルに完全に移行したことを示しています。これは、特にWindowsのようなfork()
が存在しない環境でのGoの移植性を大幅に向上させるための重要なステップです。 -
win32.c
からwindows.c
へのリネーム: これは主に命名規則の統一とコードベースの整理を目的とした変更です。Goコミュニティでは、OS固有のファイルやビルドタグに小文字のOS名を使用する慣習があります(例:linux
,windows
,darwin
)。このリネームにより、lib9
内のファイル名がGoの一般的な慣習に沿うようになり、コードベース全体の整合性が向上します。
これらの変更は全体として、lib9
をよりモジュール化し、Goのクロスプラットフォーム戦略に適合させることを目指しています。Unix固有の依存関係を減らし、Goのビルドタグを活用することで、異なるOS上でのGoアプリケーションのビルドと実行の信頼性を高めています。
関連リンク
- Go言語のビルドタグに関する公式ドキュメント: https://pkg.go.dev/cmd/go#hdr-Build_constraints
- Plan 9 from User Space (plan9port): http://plan9.bell-labs.com/plan9port/
- Go言語の
os/exec
パッケージ: https://pkg.go.dev/os/exec
参考にした情報源リンク
- Go言語の公式ドキュメント
- Plan 9 from User Spaceのソースコードとドキュメント
- C言語の標準ライブラリ関数に関する一般的な知識
- UnixおよびWindowsのシステムプログラミングに関する一般的な知識
- Go言語のコミット履歴と関連するコードレビュー(CL: Change List)