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

[インデックス 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関連のテストは、ビルドシステムの変更によって一時的に無効化されたり、調整が必要になったりすることがありました。

このコミットの主な背景は以下の点に集約されます。

  1. ビルドシステムの移行: gomakeからgoコマンドへの移行に伴い、misc/cgoディレクトリ内のテストのビルド方法を更新する必要があった。
  2. CGOテストの安定化と再有効化: CGOのテストは、GoとCの連携、外部ライブラリのリンクなど、複雑な要素が絡むため、安定した動作を保証することが重要でした。一時的に無効化されていた、あるいは適切に動作していなかったCGOテストを再有効化し、GoのCI/CDパイプラインに組み込む必要があったと考えられます。
  3. CGO有効化ロジックの改善: Goのビルドツールが、どのOS/アーキテクチャの組み合わせでCGOを有効にするべきかを正確に判断するためのロジックを、より堅牢にする必要があった。これは、クロスコンパイルや異なる環境でのビルドの信頼性を高める上で不可欠です。
  4. テストインフラの整備: 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 buildgo 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 buildgo installコマンドの対象から外されます。つまり、これらのファイルはGoの標準パッケージとしてビルドされるのではなく、それぞれのtest.bashスクリプト内で明示的にgo build -o <output_name> <source_file.go>のように指定されてコンパイルされることを意図しています。これは、これらのファイルが独立した実行可能ファイルとしてテストされるべきであり、ライブラリとしてインポートされるべきではない、という設計思想を反映しています。

3. インポートパスの変更

  • 変更箇所: misc/cgo/gmp/fib.go, misc/cgo/gmp/pi.goimport "gmp"import "."に変更され、misc/cgo/life/main.goimport "life"import "."に変更され、misc/cgo/stdio/chain.go, misc/cgo/stdio/fib.go, misc/cgo/stdio/hello.goimport "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.goos.ENOENTsyscall.ENOENTに変更されました。
  • 影響: これは、Goのエラーハンドリングのより正確な表現への移行を示唆しています。osパッケージは高レベルなOS操作を提供しますが、syscallパッケージはより低レベルでOS固有のシステムコールやエラーコードに直接アクセスします。この変更は、CGOを介したCライブラリの操作において、より正確なシステムエラーコードの比較が必要とされたためと考えられます。

5. CGOコールバックメカニズムの改善

  • 変更箇所: misc/cgo/test/callback.gomisc/cgo/test/callback_c.cで、CからGoへのコールバックに関する変更が行われました。特に、callGoFoo関数の宣言がCのヘッダ部分に移動し、lockedOSThreadbackdoorパッケージからインポートされるようになりました。また、callback_c.ccallGoFoo, IntoC, twoSleepのC関数定義が追加されました。
  • 影響: これらの変更は、CGOにおけるGoとCの間のコールバックの信頼性と柔軟性を向上させることを目的としています。特に、GoのランタイムがCのコードから呼び出される際の挙動(例えば、GoのgoroutineがCのコールバック内でどのように動作するか)をより細かく制御し、テストするためのものです。backdoorパッケージからのインポートは、Goの内部ランタイム機能へのアクセスを示唆しており、CGOの低レベルな動作をテストするために必要だったと考えられます。

6. CGO有効化ロジックの更新

  • 変更箇所: src/cmd/dist/build.csrc/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が削除され、gotestgo testに置き換えられました。
  • 影響:
    • $BROKEN ||の削除は、以前は「壊れている」とマークされていたCGOテストが、このコミットによって修正され、Goのメインテストスイートの一部として再び実行されるようになったことを意味します。
    • gomake cleanの削除は、Makefileが削除されたことと一貫しており、ビルド成果物のクリーンアップもgoコマンドベースのスクリプトに委ねられるようになったことを示します。
    • gotestからgo testへの変更は、Goのテスト実行も標準のgo testコマンドに統一されたことを示しています。

これらの変更は全体として、Go言語のCGO機能の成熟と、ビルドシステムがより現代的で統一されたgoコマンドラインツールへと移行する過程における重要なステップを示しています。

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

このコミットにおけるコアとなるコードの変更箇所は以下の通りです。

  1. misc/cgo/gmp/Makefilemisc/cgo/life/Makefilemisc/cgo/stdio/Makefileの削除:

    • これらのファイルは、Goの初期のビルドシステムであるgomakeを使用するためのMakefileでした。これらが削除されたことで、各CGOテストのビルドは、対応するtest.bashスクリプト内で直接go buildコマンドによって行われるようになります。
  2. misc/cgo/gmp/fib.gomisc/cgo/gmp/pi.gomisc/cgo/life/main.gomisc/cgo/stdio/chain.gomisc/cgo/stdio/fib.gomisc/cgo/stdio/hello.goへの// +build ignoreタグの追加:

    • これらのGoファイルの先頭に// +build ignoreというビルドタグが追加されました。これにより、これらのファイルは通常のgo buildgo installコマンドの対象から外され、特定のテストスクリプトによってのみビルドされるようになります。
  3. misc/cgo/life/test.bashmisc/cgo/stdio/test.bashにおけるビルドコマンドの変更:

    • gomake lifego build -o life main.goに、gomake hello fib chaingo build hello.gogo build fib.gogo build chain.goにそれぞれ変更されました。
    • また、gomake cleanの呼び出しが削除され、rm -fコマンドによる直接的なクリーンアップに置き換えられました。
  4. misc/cgo/test/basic.goにおけるエラーコードの変更:

    • if err != os.ENOENT {if err != syscall.ENOENT {に変更されました。これにより、ファイルが見つからないエラーの比較がosパッケージからsyscallパッケージの定数に切り替わりました。
  5. src/cmd/dist/build.cにおけるCGO有効化ロジックの追加:

    • static char *okcgo[]という配列が追加され、CGOが有効なGOOS/GOARCHの組み合わせが定義されました。
    • cmdenv関数内で、現在のGOOS/GOARCHokcgoリストに含まれる場合にCGO_ENABLED=1環境変数を設定し、それ以外の場合はCGO_ENABLED=0を設定するロジックが追加されました。
  6. src/pkg/go/build/build.goにおけるCGO有効化マップの追加:

    • var cgoEnabled = map[string]bool{...}というマップが追加され、src/cmd/dist/build.cと同様のCGO有効化情報がGoのコードベースにも反映されました。
  7. src/run.bashにおけるテスト実行条件の変更:

    • $BROKEN ||という条件が、misc/cgo/stdiomisc/cgo/lifemisc/cgo/testの各テストブロックから削除されました。
    • misc/cgo/testのテストブロックでgotestgo 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.csrc/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言語公式ドキュメント (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)