[インデックス 12447] ファイルの概要
このコミットは、Go言語プロジェクトのmisc/cgo
ディレクトリ内のテストを再有効化し、関連するビルドシステムとCGOの有効化ロジックを更新するものです。主に、Goのビルドシステムがgomake
から標準のgo
コマンドラインツールへと移行する過程で、CGO関連のテストが適切に動作するように調整が行われています。
コミット
commit c3f4319a241d646668f81de5e7109ce8938f79f2
Author: Russ Cox <rsc@golang.org>
Date: Tue Mar 6 23:27:30 2012 -0500
misc/cgo: re-enable some tests
The testso directory still needs to be enabled.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5731048
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/c3f4319a241d646668f81de5e7109ce8938f79f2
元コミット内容
misc/cgo: re-enable some tests
The testso directory still needs to be enabled.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5731048
変更の背景
このコミットが行われた2012年3月は、Go言語がまだ比較的新しく、その開発プロセスが活発に行われていた時期です。特に、ビルドシステムに関しては、初期のgomake
というカスタムのMakeベースのシステムから、現在の標準的なgo
コマンドラインツール(go build
, go test
など)への移行が進められていました。
このような移行期においては、既存のテストスイートが新しいビルドシステムに適合するように更新される必要がありました。CGO(GoとC言語の相互運用機能)は、Goの機能の中でも特に複雑な部分であり、異なるOSやアーキテクチャでの動作保証が重要です。そのため、CGO関連のテストは、ビルドシステムの変更によって一時的に無効化されたり、調整が必要になったりすることがありました。
このコミットの主な背景は以下の点に集約されます。
- ビルドシステムの移行:
gomake
からgo
コマンドへの移行に伴い、misc/cgo
ディレクトリ内のテストのビルド方法を更新する必要があった。 - CGOテストの安定化と再有効化: CGOのテストは、GoとCの連携、外部ライブラリのリンクなど、複雑な要素が絡むため、安定した動作を保証することが重要でした。一時的に無効化されていた、あるいは適切に動作していなかったCGOテストを再有効化し、GoのCI/CDパイプラインに組み込む必要があったと考えられます。
- CGO有効化ロジックの改善: Goのビルドツールが、どのOS/アーキテクチャの組み合わせでCGOを有効にするべきかを正確に判断するためのロジックを、より堅牢にする必要があった。これは、クロスコンパイルや異なる環境でのビルドの信頼性を高める上で不可欠です。
- テストインフラの整備:
src/run.bash
のようなトップレベルのテストスクリプトが、新しいビルドシステムに対応し、CGOテストを適切に実行できるように更新する必要があった。
コミットメッセージにある「The testso directory still needs to be enabled.」という記述は、おそらく共有ライブラリ(.so
ファイルなど)を扱うCGOテストが、まだ完全に統合されていないか、特別な対応が必要であることを示唆しています。このコミットは、その一環として、一部のCGOテストを再有効化するステップであったと考えられます。
前提知識の解説
このコミットの変更内容を深く理解するためには、以下の技術的な概念について把握しておく必要があります。
CGO (Go and C interoperability)
CGOは、Go言語のプログラムからC言語のコードを呼び出したり、その逆を行ったりするためのGoの機能です。これにより、既存のCライブラリをGoプロジェクトで再利用したり、パフォーマンスが重要な部分をCで記述したりすることが可能になります。
- GoからCの呼び出し: Goのコード内で
import "C"
と記述し、Cの関数や変数にアクセスします。CのコードはGoのソースファイル内に直接埋め込むか、外部のCファイルとして提供します。 - CからGoの呼び出し: CのコードからGoの関数を呼び出すことも可能です。これは通常、Goの関数をCのコールバックとして登録する形で行われます。
- ビルドプロセス: CGOを使用するGoプログラムをビルドする際には、Goコンパイラだけでなく、Cコンパイラ(通常はGCCやClang)も必要になります。GoツールチェーンがCGOのコードを検出し、Cコンパイラを呼び出してCコードをコンパイルし、Goのオブジェクトファイルとリンクします。
go build
コマンドとgomake
go build
: 現在のGo言語の標準的なビルドコマンドです。ソースファイルをコンパイルし、実行可能バイナリを生成します。Goモジュールシステムと密接に連携し、依存関係の解決、パッケージのビルド、テストの実行など、Goプロジェクトのライフサイクル全体を管理します。gomake
: Go言語の初期段階で使用されていたカスタムのビルドシステムです。Goのソースコードをビルドするために設計されたMakeファイルベースのシステムで、Goの標準ツールが成熟するまでの過渡期に利用されていました。このシステムは、Goのソースツリー内の特定のディレクトリに配置されたMakefile
を介して動作しました。このコミットが行われた時期には、gomake
からgo build
への移行が積極的に進められていました。
// +build ignore
ビルドタグ
Goのソースファイルには、特定の条件に基づいてファイルをビルドに含めるか除外するかを制御するための「ビルドタグ」を記述できます。// +build ignore
は特別なビルドタグで、このタグが記述されたファイルは、go build
やgo install
などの通常のビルドプロセスでは無視されます。
このタグは、主に以下の目的で使用されます。
- 実行可能な例 (Executable Examples): ドキュメントの一部として提供されるが、通常のビルドには含めたくない実行可能なコード例。
- テストヘルパー: テストスイート内で特定の目的のために使用されるが、直接実行されるべきではない補助的なコード。
- 一時的なコード: 開発中に一時的に作成されたコードや、特定のツールによってのみビルドされるべきコード。
このコミットでは、misc/cgo
内の多くのGoファイルにこのタグが追加されています。これは、これらのファイルが通常のGoパッケージとしてビルドされるのではなく、対応するtest.bash
スクリプトによって明示的にgo build
コマンドでコンパイル・実行されることを意図していると考えられます。
syscall.ENOENT
ENOENT
は、"Error NO ENTry" の略で、ファイルやディレクトリが見つからないことを示す標準的なエラーコードです。Unix系システムでは、errno
変数を通じてシステムコールが失敗した理由を伝えます。Go言語では、syscall
パッケージがOSのシステムコールやエラーコードへの低レベルなアクセスを提供します。
このコミットでos.ENOENT
からsyscall.ENOENT
への変更が見られるのは、Goの標準ライブラリにおけるエラーハンドリングの進化、あるいはより低レベルでOS固有のエラーコードを直接扱う必要があったためと考えられます。os
パッケージはより高レベルな抽象化を提供しますが、syscall
パッケージはOSのプリミティブに直接対応します。
Goのビルドコンテキスト (GOOS/GOARCH)
Goのビルドプロセスは、ターゲットのオペレーティングシステム(GOOS
、例: linux
, windows
, darwin
)とアーキテクチャ(GOARCH
、例: amd64
, 386
, arm
)の組み合わせに強く依存します。これらの環境変数は、Goコンパイラが生成するバイナリのターゲット環境を決定します。CGOはOSやアーキテクチャに強く依存するため、CGOが有効になるGOOS/GOARCHの組み合わせはGoのツールチェーンによって明示的に管理されます。
技術的詳細
このコミットは、Go言語のCGOテストインフラストラクチャとビルドシステムに複数の重要な変更を加えています。
1. Makefile
の削除とgo build
への移行
- 変更箇所:
misc/cgo/gmp/Makefile
,misc/cgo/life/Makefile
,misc/cgo/stdio/Makefile
が削除されました。 - 影響: これらのディレクトリ内のCGOテストは、もはや
gomake
によってビルドされなくなりました。代わりに、対応するtest.bash
スクリプト内で直接go build
コマンドが使用されるようになります。これは、Goのビルドシステムがgomake
からgo
コマンドラインツールへと完全に移行する過程の一部です。gomake
はGoの初期のビルドシステムであり、より汎用的なgo
コマンドに置き換えられていきました。
2. // +build ignore
タグの追加
- 変更箇所:
misc/cgo/gmp/fib.go
,misc/cgo/gmp/pi.go
,misc/cgo/life/main.go
,misc/cgo/stdio/chain.go
,misc/cgo/stdio/fib.go
,misc/cgo/stdio/hello.go
に// +build ignore
タグが追加されました。 - 影響: このタグにより、これらのGoファイルは通常の
go build
やgo install
コマンドの対象から外されます。つまり、これらのファイルはGoの標準パッケージとしてビルドされるのではなく、それぞれのtest.bash
スクリプト内で明示的にgo build -o <output_name> <source_file.go>
のように指定されてコンパイルされることを意図しています。これは、これらのファイルが独立した実行可能ファイルとしてテストされるべきであり、ライブラリとしてインポートされるべきではない、という設計思想を反映しています。
3. インポートパスの変更
- 変更箇所:
misc/cgo/gmp/fib.go
,misc/cgo/gmp/pi.go
でimport "gmp"
がimport "."
に変更され、misc/cgo/life/main.go
でimport "life"
がimport "."
に変更され、misc/cgo/stdio/chain.go
,misc/cgo/stdio/fib.go
,misc/cgo/stdio/hello.go
でimport "stdio"
がimport "../stdio"
に変更されました。 - 影響: これは、Goのパッケージ管理とインポートのセマンティクスに関する変更です。
import "."
は、現在のディレクトリをパッケージとしてインポートすることを意味します。これは、// +build ignore
で通常のビルドから除外されたファイルが、そのディレクトリ内で独立したプログラムとしてビルドされる際に、そのディレクトリ内の他のGoファイル(CGOのCコードを含む)を参照するために使用されます。import "../stdio"
のような相対パスは、Goモジュールが導入される前のGoのパッケージ管理において、親ディレクトリのパッケージを参照する一般的な方法でした。これは、stdio
パッケージがmisc/cgo
のサブディレクトリとして存在し、その中のファイルが互いに参照し合うために必要でした。
4. エラーコードの変更 (os.ENOENT
-> syscall.ENOENT
)
- 変更箇所:
misc/cgo/test/basic.go
でos.ENOENT
がsyscall.ENOENT
に変更されました。 - 影響: これは、Goのエラーハンドリングのより正確な表現への移行を示唆しています。
os
パッケージは高レベルなOS操作を提供しますが、syscall
パッケージはより低レベルでOS固有のシステムコールやエラーコードに直接アクセスします。この変更は、CGOを介したCライブラリの操作において、より正確なシステムエラーコードの比較が必要とされたためと考えられます。
5. CGOコールバックメカニズムの改善
- 変更箇所:
misc/cgo/test/callback.go
とmisc/cgo/test/callback_c.c
で、CからGoへのコールバックに関する変更が行われました。特に、callGoFoo
関数の宣言がCのヘッダ部分に移動し、lockedOSThread
がbackdoor
パッケージからインポートされるようになりました。また、callback_c.c
にcallGoFoo
,IntoC
,twoSleep
のC関数定義が追加されました。 - 影響: これらの変更は、CGOにおけるGoとCの間のコールバックの信頼性と柔軟性を向上させることを目的としています。特に、GoのランタイムがCのコードから呼び出される際の挙動(例えば、GoのgoroutineがCのコールバック内でどのように動作するか)をより細かく制御し、テストするためのものです。
backdoor
パッケージからのインポートは、Goの内部ランタイム機能へのアクセスを示唆しており、CGOの低レベルな動作をテストするために必要だったと考えられます。
6. CGO有効化ロジックの更新
- 変更箇所:
src/cmd/dist/build.c
とsrc/pkg/go/build/build.go
が更新されました。src/cmd/dist/build.c
には、CGOが有効なGOOS/GOARCH
の組み合わせのリスト(okcgo
)が追加され、ビルド時にCGO_ENABLED
環境変数を設定するロジックが導入されました。src/pkg/go/build/build.go
にも同様のcgoEnabled
マップが追加され、cmd/dist/build.c
と同期していることがコメントで示されています。
- 影響: これは、Goのビルドツールが、どのターゲット環境でCGOを有効にするべきかをより正確に判断するための重要な変更です。
CGO_ENABLED=1
が設定されることで、GoコンパイラはCGOのコードを処理し、Cコンパイラを呼び出すようになります。このリストは、Goが公式にサポートし、CGOが安定して動作すると保証されているプラットフォームを明示しています。これにより、クロスコンパイルの際にもCGOの挙動が予測可能になります。
7. src/run.bash
におけるテストの再有効化
- 変更箇所:
src/run.bash
スクリプトから、$BROKEN ||
という条件が削除され、gomake clean
が削除され、gotest
がgo test
に置き換えられました。 - 影響:
$BROKEN ||
の削除は、以前は「壊れている」とマークされていたCGOテストが、このコミットによって修正され、Goのメインテストスイートの一部として再び実行されるようになったことを意味します。gomake clean
の削除は、Makefile
が削除されたことと一貫しており、ビルド成果物のクリーンアップもgo
コマンドベースのスクリプトに委ねられるようになったことを示します。gotest
からgo test
への変更は、Goのテスト実行も標準のgo test
コマンドに統一されたことを示しています。
これらの変更は全体として、Go言語のCGO機能の成熟と、ビルドシステムがより現代的で統一されたgo
コマンドラインツールへと移行する過程における重要なステップを示しています。
コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更箇所は以下の通りです。
-
misc/cgo/gmp/Makefile
、misc/cgo/life/Makefile
、misc/cgo/stdio/Makefile
の削除:- これらのファイルは、Goの初期のビルドシステムである
gomake
を使用するためのMakefileでした。これらが削除されたことで、各CGOテストのビルドは、対応するtest.bash
スクリプト内で直接go build
コマンドによって行われるようになります。
- これらのファイルは、Goの初期のビルドシステムである
-
misc/cgo/gmp/fib.go
、misc/cgo/gmp/pi.go
、misc/cgo/life/main.go
、misc/cgo/stdio/chain.go
、misc/cgo/stdio/fib.go
、misc/cgo/stdio/hello.go
への// +build ignore
タグの追加:- これらのGoファイルの先頭に
// +build ignore
というビルドタグが追加されました。これにより、これらのファイルは通常のgo build
やgo install
コマンドの対象から外され、特定のテストスクリプトによってのみビルドされるようになります。
- これらのGoファイルの先頭に
-
misc/cgo/life/test.bash
とmisc/cgo/stdio/test.bash
におけるビルドコマンドの変更:gomake life
がgo build -o life main.go
に、gomake hello fib chain
がgo build hello.go
、go build fib.go
、go build chain.go
にそれぞれ変更されました。- また、
gomake clean
の呼び出しが削除され、rm -f
コマンドによる直接的なクリーンアップに置き換えられました。
-
misc/cgo/test/basic.go
におけるエラーコードの変更:if err != os.ENOENT {
がif err != syscall.ENOENT {
に変更されました。これにより、ファイルが見つからないエラーの比較がos
パッケージからsyscall
パッケージの定数に切り替わりました。
-
src/cmd/dist/build.c
におけるCGO有効化ロジックの追加:static char *okcgo[]
という配列が追加され、CGOが有効なGOOS/GOARCH
の組み合わせが定義されました。cmdenv
関数内で、現在のGOOS/GOARCH
がokcgo
リストに含まれる場合にCGO_ENABLED=1
環境変数を設定し、それ以外の場合はCGO_ENABLED=0
を設定するロジックが追加されました。
-
src/pkg/go/build/build.go
におけるCGO有効化マップの追加:var cgoEnabled = map[string]bool{...}
というマップが追加され、src/cmd/dist/build.c
と同様のCGO有効化情報がGoのコードベースにも反映されました。
-
src/run.bash
におけるテスト実行条件の変更:$BROKEN ||
という条件が、misc/cgo/stdio
、misc/cgo/life
、misc/cgo/test
の各テストブロックから削除されました。misc/cgo/test
のテストブロックでgotest
がgo test
に置き換えられました。
コアとなるコードの解説
1. Makefile
の削除とgo build
への移行
misc/cgo/gmp/Makefile
などの削除は、Goのビルドシステムがgomake
から標準のgo
コマンドラインツールへと完全に移行したことを明確に示しています。以前は、これらのMakefileがCGOプログラムのコンパイルとリンクを管理していましたが、Goツールチェーン自体がCGOのビルドをネイティブにサポートするようになったため、カスタムのMakefileは不要になりました。これにより、ビルドプロセスが簡素化され、Goの標準ツールによる一貫したビルド体験が提供されます。
2. // +build ignore
タグの追加
このタグの追加は、これらのGoファイルが通常のGoパッケージとしてではなく、独立した実行可能プログラムとして扱われるべきであることを示しています。例えば、misc/cgo/gmp/fib.go
は、gmp
パッケージのフィボナッチ数計算の例ですが、これはgo build fib.go
のように直接ビルドされ、実行されることを想定しています。通常のGoパッケージとしてビルドされると、他のパッケージから誤ってインポートされたり、不必要な依存関係が生じたりする可能性があります。// +build ignore
は、このような「スタンドアロン」な例やテストコードを、Goのモジュールシステムやパッケージ管理から切り離すための効果的なメカニズムです。
3. test.bash
スクリプトにおけるビルドコマンドの変更
gomake
からgo build
への変更は、前述のMakefile削除と直接関連しています。test.bash
スクリプトは、各CGOテストのビルドと実行をオーケストレーションする役割を担っています。この変更により、テストスクリプト自体がGoの標準ビルドツールを使用するようになり、Goプロジェクト全体のビルドプロセスの一貫性が保たれます。また、rm -f
による直接的なクリーンアップは、gomake clean
が提供していた機能の代替であり、スクリプト内で完結するようになりました。
4. misc/cgo/test/basic.go
におけるエラーコードの変更
os.ENOENT
からsyscall.ENOENT
への変更は、より低レベルでOSに依存しないエラーハンドリングへの移行を示唆しています。os
パッケージはGoの標準ライブラリの一部として高レベルな抽象化を提供しますが、syscall
パッケージはOSのシステムコールに直接対応する定数や関数を提供します。CGOはC言語のライブラリと直接やり取りするため、OS固有のエラーコードを正確に扱うことが重要になる場合があります。この変更は、CGOテストの堅牢性を高めるための細かな調整と考えられます。
5. src/cmd/dist/build.c
とsrc/pkg/go/build/build.go
におけるCGO有効化ロジックの追加
これは、GoのビルドシステムがCGOを有効にするかどうかを決定する中心的なロジックです。okcgo
リスト(またはcgoEnabled
マップ)は、GoがCGOをサポートする公式なプラットフォームの組み合わせを定義しています。ビルド時に、現在のターゲット環境(GOOS/GOARCH
)がこのリストに含まれている場合のみ、CGO_ENABLED=1
という環境変数が設定されます。この環境変数は、GoコンパイラにCGOコードを処理するよう指示し、Cコンパイラを呼び出すトリガーとなります。このメカニズムにより、Goのビルドシステムは、CGOがサポートされていない環境でのビルド時に不必要なエラーや依存関係の問題を回避し、クロスコンパイルの信頼性を向上させます。
6. src/run.bash
におけるテスト実行条件の変更
$BROKEN ||
の削除は、以前は不安定であったり、特定の理由で無効化されていたCGOテストが、このコミットによって修正され、Goの自動テストスイートに再統合されたことを意味します。これは、CGO機能の安定性が向上し、そのテストカバレッジが強化されたことを示しています。また、gotest
からgo test
への変更は、Goのテスト実行も標準のgo test
コマンドに統一されたことを示しており、Goプロジェクト全体のテストインフラストラクチャの一貫性を高めています。
これらの変更は、Go言語が初期段階から成熟期へと移行する中で、CGOのような複雑な機能のサポートを強化し、ビルドおよびテストプロセスをより効率的かつ堅牢にするための継続的な努力の一環です。
関連リンク
- Go Gerrit Change: https://golang.org/cl/5731048
参考にした情報源リンク
- Go言語公式ドキュメント (CGO): https://go.dev/blog/c-go-cgo (CGOの基本的な概念を理解するために参照)
- Go言語ビルドタグに関するドキュメント: https://go.dev/cmd/go/#hdr-Build_constraints (
// +build ignore
の挙動を理解するために参照) - Go言語の歴史とビルドシステムに関する情報 (一般的な知識として): https://go.dev/doc/go1 (Go 1のリリースノートなど、当時のGoの状況を把握するために参照)
syscall
パッケージのドキュメント: https://pkg.go.dev/syscall (syscall.ENOENT
の理解のために参照)os
パッケージのドキュメント: https://pkg.go.dev/os (os.ENOENT
の理解のために参照)- Goのビルドプロセスに関する一般的な情報 (
GOOS
,GOARCH
,CGO_ENABLED
): https://go.dev/doc/install/source (Goのビルド環境変数の理解のために参照) make
コマンドとMakefile
の一般的な概念 (gomake
の背景を理解するために参照)- シェルスクリプトの基本的な構文 (テストスクリプトの理解のために参照)
- Gitの基本的なコマンドと概念 (コミット内容の理解のために参照)
- GitHubのコミットページ (提供されたURL)