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

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

このコミットは、Go言語のビルドシステムがGoogle Native Client (NaCl) 環境で適切に動作するようにするための変更を導入しています。具体的には、NaCl環境でのテスト実行に必要な入力ファイルを埋め込んだsyscallパッケージのバリアントをビルドするための新しいスクリプトnacl.bashを追加し、NaCl環境と互換性のない一部のテスト(主にos/execを使用するもの)を無効にしています。

コミット

  • コミットハッシュ: 0c2a727477908dc0adbfcb05baac34b4ba4fa309
  • Author: Russ Cox rsc@golang.org
  • Date: Tue May 20 12:10:19 2014 -0400

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

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

元コミット内容

build: make nacl pass

Add nacl.bash, the NaCl version of all.bash.
It's a separate script because it builds a variant of package syscall
with a large zip file embedded in it, containing all the input files
needed for tests.

Disable various tests new since the last round, mostly the ones using os/exec.

Fixes #7945.

LGTM=dave
R=golang-codereviews, remyoudompheng, dave, bradfitz
CC=golang-codereviews
https://golang.org/cl/100590044

変更の背景

この変更の主な背景は、Go言語がGoogle Native Client (NaCl) 環境で動作し、そのテストスイートがNaCl上でパスするようにすることです。

Google Native Client (NaCl) とは? Google Native Client (NaCl) は、ウェブブラウザ内でネイティブコード(C/C++など)を安全かつポータブルに実行するためのサンドボックス技術です。これにより、ウェブアプリケーションはネイティブのパフォーマンスを活用しつつ、セキュリティ上のリスクを最小限に抑えることができます。NaClは、特定のCPUアーキテクチャ(x86-32, x86-64, ARM)とオペレーティングシステム(Windows, macOS, Linux, Chrome OS)に依存しないバイナリ形式(Portable Native Client, PNaCl)を提供し、一度コンパイルすればどこでも実行できることを目指していました。

Go言語は、その設計思想としてクロスプラットフォーム対応を重視しており、様々な環境での動作をサポートしています。NaClもその一つであり、Goプログラムをウェブブラウザ内で実行可能にすることは、Goの適用範囲を広げる上で重要な目標でした。

しかし、NaCl環境は通常のオペレーティングシステム環境とは異なる制約を持っています。例えば、ファイルシステムへのアクセスやプロセス間通信、外部プログラムの実行など、一部のシステムコールが制限されるか、異なる方法で提供されます。Goの標準ライブラリ、特にテストスイートは、これらのシステム機能に依存している部分が多く、そのままではNaCl上で動作しませんでした。

このコミットは、GoのテストスイートをNaCl環境で実行可能にするための具体的なステップとして、以下の課題に対処しています。

  1. テストデータの管理: 多くのテストは、外部ファイルからデータを読み込んだり、一時ファイルを作成したりします。NaClのサンドボックス環境では、通常のファイルシステムアクセスが制限されるため、これらのテストデータをどのように提供するかが課題でした。
  2. システムコールと互換性: os/execパッケージのように、外部プロセスを起動する機能はNaCl環境では直接サポートされません。このような機能に依存するテストは、NaClでは実行できないため、適切に処理する必要がありました。
  3. ビルドプロセスの適応: NaCl向けのGoバイナリをビルドするためには、通常のビルドプロセスとは異なる手順や設定が必要になります。

このコミットは、これらの課題に対する解決策を提供し、GoのNaClサポートを強化することを目的としています。

前提知識の解説

このコミットを理解するためには、以下の概念について基本的な知識があると役立ちます。

  1. Go言語のビルドシステム:

    • all.bash: Goプロジェクトのルートディレクトリにあるシェルスクリプトで、Goの標準ライブラリ、ツール、およびテストをビルド・実行するための主要なスクリプトです。これはGoのCI/CDパイプラインや開発者がローカルでGo環境をセットアップする際に広く使用されます。
    • クロスコンパイル: Goは、あるプラットフォーム(例: Linux x86-64)で別のプラットフォーム(例: Windows ARM)向けのバイナリを生成するクロスコンパイルを強力にサポートしています。これは、GOOS(ターゲットOS)やGOARCH(ターゲットアーキテクチャ)といった環境変数を設定することで実現されます。
    • パッケージ: Goのコードはパッケージに分割されており、各パッケージは特定の機能を提供します。syscallパッケージは、オペレーティングシステムのシステムコールへの低レベルなインターフェースを提供します。os/execパッケージは、外部コマンドの実行を可能にします。
  2. Google Native Client (NaCl):

    • サンドボックス: NaClは、実行されるコードを厳しく制限された環境(サンドボックス)内で動作させます。これにより、悪意のあるコードがシステムに損害を与えたり、機密情報にアクセスしたりするのを防ぎます。
    • PNaCl (Portable Native Client): NaClの進化版で、特定のCPUアーキテクチャに依存しない中間表現(LLVM IRベース)を使用します。これにより、開発者は一度PNaClバイナリをコンパイルすれば、Chromeブラウザが実行時にターゲットアーキテクチャに最適化されたネイティブコードに変換して実行します。
    • 制限されたI/O: NaClサンドボックス内では、通常のファイルシステムアクセスやネットワークアクセスが制限されます。ファイルアクセスは、通常、事前にパッケージ化されたリソース(例えば、アプリケーションの.nmfマニフェストファイルに記述されたリソース)や、ブラウザのAPIを介して行われます。
  3. テストとテストデータ:

    • Goのテストは、通常、_test.goファイルに記述され、go testコマンドで実行されます。
    • テストの中には、外部ファイル(設定ファイル、入力データ、期待される出力など)を必要とするものがあります。これらのファイルは「テストデータ」と呼ばれます。
  4. 埋め込みリソース:

    • Goのバイナリに任意のファイルを埋め込む一般的な方法は、Goのコードとしてバイト配列に変換し、それをプログラム内で読み込むことです。これにより、外部ファイルへの依存をなくし、単一のバイナリとして配布できるようになります。このコミットでは、特にテストデータをzipファイルとして埋め込むアプローチが取られています。

これらの知識を前提として、コミットの技術的詳細を掘り下げていきます。

技術的詳細

このコミットは、GoのNaClビルドとテスト実行を可能にするために、いくつかの重要な技術的変更を導入しています。

  1. nacl.bashの導入:

    • src/all.bashのNaCl版としてsrc/nacltest.bashが追加されました。これは、NaCl環境に特化したビルドとテストのロジックを含んでいます。
    • 通常のall.bashがGoの標準的なビルドとテストを行うのに対し、nacltest.bashはNaClの制約と要件に合わせて調整されています。
  2. テストデータの埋め込みとmkzip.go:

    • NaCl環境では、テストが外部ファイルにアクセスすることが困難です。この問題を解決するため、テストに必要なすべての入力ファイルを一つの大きなzipファイルにまとめ、それをGoのバイナリに埋め込むというアプローチが取られました。
    • misc/nacl/mkzip.goという新しいGoプログラムが追加されました。このツールは、特定のプロトコルファイル(testzip.proto)で記述されたファイルツリー構造に基づいて、zipファイルを作成します。
    • mkzip.goは、src.protoという入力ファイルとout.zipという出力ファイルを引数にとります。src.protoは、どのファイルをzipに含めるか、そしてそれらのファイルがzip内でどのようなパスを持つかを定義します。
    • さらに、mkzip.go-pフラグを使用することで、生成されたzipファイルの内容をGoのソースコード(バイト配列として)として出力する機能を持っています。これにより、zipファイルがGoのバイナリに直接埋め込まれることが可能になります。
  3. testzip.protoの役割:

    • misc/nacl/testzip.protoは、mkzip.goがzipファイルを作成する際に参照する「プロトタイプ」ファイルです。これは、Plan 9のmkfsプロトタイプファイル形式にインスパイアされています。
    • このファイルは、タブによるインデントでディレクトリ構造を表現し、各行にはファイル名とオプションの属性(例: src=fooで元のファイルのパスを指定)が記述されます。
    • このプロトファイルには、etc/mime.typesusr/bin、Goの標準ライブラリのテストデータなど、Goのテストスイートが依存する様々なファイルが含まれています。特にmime.typesは非常に大きなファイルであり、これが埋め込まれることで、syscallパッケージのサイズが大きくなることが示唆されています。
  4. syscallパッケージのバリアント:

    • nacltest.bashは、mkzip.goを使用して生成されたzipファイルをsyscallパッケージに埋め込みます。これにより、NaCl環境で実行されるGoプログラムは、外部ファイルシステムにアクセスすることなく、必要なテストデータにアクセスできるようになります。
    • この埋め込みは、syscallパッケージの特定のビルドタグ(おそらくNaCl固有のタグ)が有効な場合にのみ行われるように設計されていると考えられます。
  5. os/execを使用するテストの無効化:

    • NaClのサンドボックスモデルでは、外部プロセスの実行(os/execパッケージが提供する機能)はセキュリティ上の理由から厳しく制限されるか、完全に禁止されます。
    • このコミットでは、os/execに依存するテストがNaCl環境で実行されないように、それらのテストを無効化する変更が含まれています。これは、テストファイルの変更(例: src/pkg/os/exec/exec_test.go)や、nacltest.bashスクリプト内での条件付き実行によって実現されています。

これらの変更により、GoのビルドシステムはNaClの特殊な環境に対応し、テストがサンドボックス内で必要なリソースにアクセスできるようになり、同時にNaClの制約に違反するテストはスキップされるようになります。

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

このコミットにおける主要なコード変更は以下のファイルに集中しています。

  1. misc/nacl/mkzip.go:

    • 新規追加されたファイル。
    • testzip.protoで定義されたファイル構造に基づいてzipファイルを作成するGoプログラム。
    • -pフラグを使用すると、zipの内容をGoのバイト配列として出力し、Goのソースコードに埋め込める形式にする機能を持つ。
  2. misc/nacl/testzip.proto:

    • 新規追加されたファイル。
    • mkzip.goがzipファイルを作成する際に参照するプロトタイプファイル。
    • Goのテストに必要な様々なファイル(例: mime.types, group, hostsなど)のパスと、それらをzip内でどのように配置するかを定義。
  3. src/nacltest.bash:

    • 新規追加されたファイル。
    • all.bashのNaCl版であり、NaCl環境でのGoのビルドとテスト実行をオーケストレーションするシェルスクリプト。
    • mkzip.goを呼び出してテストデータを埋め込んだsyscallパッケージをビルドするロジックが含まれる。
  4. src/all.bash:

    • 既存のファイルへの変更。
    • nacltest.bashの呼び出しや、NaCl関連のビルド設定が追加された可能性がある。
  5. 各種テストファイル (src/cmd/..._test.go, src/pkg/..._test.go, test/...go):

    • 多数の既存テストファイルに修正が加えられています。
    • 主に、os/execパッケージを使用するテストや、NaCl環境で問題を引き起こす可能性のあるテストが、NaClビルドタグが有効な場合にスキップされるように変更されています。これは、if runtime.GOOS == "nacl"のような条件分岐や、ビルドタグ(例: // +build !nacl)の追加によって実現されます。
    • 例: src/pkg/os/exec/exec_test.gosrc/pkg/net/http/cgi/matryoshka_test.goなど。
  6. misc/nacl/testdata/以下のファイル:

    • mime.types, group, hosts, empty, bin/placeholderなどが新規追加されています。
    • これらはtestzip.protoで参照され、最終的に埋め込まれるテストデータの一部となります。特にmime.typesは非常に大きなファイルです。

コアとなるコードの解説

このコミットの核心は、NaCl環境の制約を克服し、GoのテストスイートをNaCl上で実行可能にするための巧妙なデータ埋め込みとビルドプロセスの調整にあります。

mkzip.gotestzip.protoによるテストデータの埋め込み

mkzip.goは、Goのテストが実行時に必要とする外部ファイルを、単一のGoバイナリに埋め込むための重要なツールです。

  1. testzip.protoの解析: mkzip.goは、testzip.protoファイルを読み込み、その内容を解析します。testzip.protoは、以下のような形式でファイルツリーを記述します。

    etc     src=/etc
        mime.types  src=../misc/nacl/testdata/mime.types
        resolv.conf src=../misc/nacl/testdata/empty
    usr     src=../misc/nacl/testdata
        bin
    
    • 行頭のタブの数でディレクトリの階層構造を示します。
    • 最初のフィールドは、zipファイル内のパス名です。
    • src=...属性は、実際のファイルデータがどこから取得されるかを指定します。これが指定されない場合、同名のファイルが現在のソースディレクトリからコピーされます。
    • *+は、ディレクトリ内のすべてのファイルや、サブディレクトリを含めたすべてのファイルを再帰的に追加することを示します。
  2. Zipファイルの生成: mkzip.goは、解析した情報に基づいてarchive/zipパッケージを使用してzipファイルを作成します。各エントリは、testzip.protoで指定されたパスとソースからデータを取得して追加されます。

  3. Goソースコードへの変換(-pフラグ): 最も重要な機能の一つは、-pフラグが指定された場合です。この場合、mkzip.goはzipファイルの内容を直接ファイルに書き込むのではなく、Goのソースコードとして標準出力に出力します。具体的には、zipファイルのバイナリデータを16進数エスケープシーケンス(\xNN)の文字列リテラルに変換し、それをinit()関数内でunzip関数に渡す形式で出力します。

    package somepackage
    
    func init() {
        unzip("\x50\x4b\x03\x04\x14\x00\x00\x00...") // zipファイルのバイナリデータ
    }
    

    この生成されたGoコードは、Goのビルドプロセス中にsyscallパッケージ(または関連するパッケージ)にコンパイルされ、結果としてzipファイルの内容がGoのバイナリに埋め込まれます。

nacltest.bashによるビルドオーケストレーション

nacltest.bashは、NaCl環境向けのGoのビルドとテストを調整するスクリプトです。

  1. mkzip.goの実行: このスクリプトは、mkzip.goを呼び出し、testzip.protoを読み込ませて、テストデータを埋め込んだGoソースファイルを生成させます。この生成されたソースファイルは、Goのビルドシステムによってsyscallパッケージの一部としてコンパイルされます。

  2. syscallパッケージの特殊なビルド: NaCl環境では、syscallパッケージが通常のシステムコールではなく、NaClのnewlibglibcインターフェースを介して動作する必要があります。また、このコミットでは、前述の埋め込まれたテストデータにアクセスするためのロジックもsyscallパッケージ内に含まれるようになります。これにより、テストは実行時に外部ファイルシステムに依存することなく、必要なデータにアクセスできます。

  3. テストの選択的無効化: nacltest.bashは、NaCl環境で実行できないテスト(特にos/execを使用するもの)を特定し、それらをスキップするようにGoのテストコマンドを調整します。これは、テストファイル内のビルドタグ(例: // +build !nacl)や、テスト実行時の環境変数設定によって制御されます。

テストファイルの変更

多くのテストファイルでは、以下のような変更が加えられています。

// Some test code
if runtime.GOOS == "nacl" {
    t.Skip("skipping test on nacl")
}
// Original test logic

または、ファイルの先頭にビルドタグが追加されます。

// +build !nacl

package somepackage_test
// ...

これにより、naclビルドタグが有効な場合(つまりNaCl向けにビルドされる場合)、特定のテストファイル全体またはテスト関数がコンパイルから除外されるか、実行時にスキップされるようになります。これは、NaClのサンドボックスモデルではサポートされない機能(例: 外部プロセスの起動、特定のネットワーク操作、ファイルシステム操作)に依存するテストを適切に処理するために不可欠です。

これらの変更の組み合わせにより、GoはNaCl環境で動作し、そのテストスイートもNaClの制約内で実行可能になります。特に、テストデータの埋め込みは、NaClの制限されたファイルシステムアクセスに対する実用的な解決策を提供しています。

関連リンク

  • Go Issue #7945: https://github.com/golang/go/issues/7945

    • このコミットが修正したGoのIssueです。通常、Issueには問題の詳細な説明や議論が含まれています。
  • Go Code Review (CL) 100590044: https://golang.org/cl/100590044

    • このコミットに対応するGoのコードレビューページです。ここには、コミットがマージされるまでの議論、レビューコメント、変更の差分などが詳細に記録されています。

参考にした情報源リンク

  • Google Native Client (NaCl) 公式ドキュメント:
  • Go言語の公式ドキュメント:
    • Goのビルドシステム、パッケージ、テストに関する一般的な情報。
  • Go言語のソースコード:
    • src/all.bashsrc/make.bashなど、Goのビルドプロセスに関連するスクリプト。
    • os/execパッケージのドキュメント。
  • Plan 9 mkfs:

(注: 上記の参考情報源リンクは、当時の技術背景を理解するための一般的な情報源であり、このコミットが直接参照したものではない可能性があります。特にNaClは現在では非推奨の技術ですが、コミット当時の状況を説明するために言及しています。)# [インデックス 19410] ファイルの概要

このコミットは、Go言語のビルドシステムがGoogle Native Client (NaCl) 環境で適切に動作するようにするための変更を導入しています。具体的には、NaCl環境でのテスト実行に必要な入力ファイルを埋め込んだsyscallパッケージのバリアントをビルドするための新しいスクリプトnacl.bashを追加し、NaCl環境と互換性のない一部のテスト(主にos/execを使用するもの)を無効にしています。

コミット

  • コミットハッシュ: 0c2a727477908dc0adbfcb05baac34b4ba4fa309
  • Author: Russ Cox rsc@golang.org
  • Date: Tue May 20 12:10:19 2014 -0400

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

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

元コミット内容

build: make nacl pass

Add nacl.bash, the NaCl version of all.bash.
It's a separate script because it builds a variant of package syscall
with a large zip file embedded in it, containing all the input files
needed for tests.

Disable various tests new since the last round, mostly the ones using os/exec.

Fixes #7945.

LGTM=dave
R=golang-codereviews, remyoudompheng, dave, bradfitz
CC=golang-codereviews
https://golang.org/cl/100590044

変更の背景

この変更の主な背景は、Go言語がGoogle Native Client (NaCl) 環境で動作し、そのテストスイートがNaCl上でパスするようにすることです。

Google Native Client (NaCl) とは? Google Native Client (NaCl) は、ウェブブラウザ内でネイティブコード(C/C++など)を安全かつポータブルに実行するためのサンドボックス技術です。これにより、ウェブアプリケーションはネイティブのパフォーマンスを活用しつつ、セキュリティ上のリスクを最小限に抑えることができます。NaClは、特定のCPUアーキテクチャ(x86-32, x86-64, ARM)とオペレーティングシステム(Windows, macOS, Linux, Chrome OS)に依存しないバイナリ形式(Portable Native Client, PNaCl)を提供し、一度コンパイルすればどこでも実行できることを目指していました。

Go言語は、その設計思想としてクロスプラットフォーム対応を重視しており、様々な環境での動作をサポートしています。NaClもその一つであり、Goプログラムをウェブブラウザ内で実行可能にすることは、Goの適用範囲を広げる上で重要な目標でした。

しかし、NaCl環境は通常のオペレーティングシステム環境とは異なる制約を持っています。例えば、ファイルシステムへのアクセスやプロセス間通信、外部プログラムの実行など、一部のシステムコールが制限されるか、異なる方法で提供されます。Goの標準ライブラリ、特にテストスイートは、これらのシステム機能に依存している部分が多く、そのままではNaCl上で動作しませんでした。

このコミットは、GoのテストスイートをNaCl環境で実行可能にするための具体的なステップとして、以下の課題に対処しています。

  1. テストデータの管理: 多くのテストは、外部ファイルからデータを読み込んだり、一時ファイルを作成したりします。NaClのサンドボックス環境では、通常のファイルシステムアクセスが制限されるため、これらのテストデータをどのように提供するかが課題でした。
  2. システムコールと互換性: os/execパッケージのように、外部プロセスを起動する機能はNaCl環境では直接サポートされません。このような機能に依存するテストは、NaClでは実行できないため、適切に処理する必要がありました。
  3. ビルドプロセスの適応: NaCl向けのGoバイナリをビルドするためには、通常のビルドプロセスとは異なる手順や設定が必要になります。

このコミットは、これらの課題に対する解決策を提供し、GoのNaClサポートを強化することを目的としています。

前提知識の解説

このコミットを理解するためには、以下の概念について基本的な知識があると役立ちます。

  1. Go言語のビルドシステム:

    • all.bash: Goプロジェクトのルートディレクトリにあるシェルスクリプトで、Goの標準ライブラリ、ツール、およびテストをビルド・実行するための主要なスクリプトです。これはGoのCI/CDパイプラインや開発者がローカルでGo環境をセットアップする際に広く使用されます。
    • クロスコンパイル: Goは、あるプラットフォーム(例: Linux x86-64)で別のプラットフォーム(例: Windows ARM)向けのバイナリを生成するクロスコンパイルを強力にサポートしています。これは、GOOS(ターゲットOS)やGOARCH(ターゲットアーキテクチャ)といった環境変数を設定することで実現されます。
    • パッケージ: Goのコードはパッケージに分割されており、各パッケージは特定の機能を提供します。syscallパッケージは、オペレーティングシステムのシステムコールへの低レベルなインターフェースを提供します。os/execパッケージは、外部コマンドの実行を可能にします。
  2. Google Native Client (NaCl):

    • サンドボックス: NaClは、実行されるコードを厳しく制限された環境(サンドボックス)内で動作させます。これにより、悪意のあるコードがシステムに損害を与えたり、機密情報にアクセスしたりするのを防ぎます。
    • PNaCl (Portable Native Client): NaClの進化版で、特定のCPUアーキテクチャに依存しない中間表現(LLVM IRベース)を使用します。これにより、開発者は一度PNaClバイナリをコンパイルすれば、Chromeブラウザが実行時にターゲットアーキテクチャに最適化されたネイティブコードに変換して実行します。
    • 制限されたI/O: NaClサンドボックス内では、通常のファイルシステムアクセスやネットワークアクセスが制限されます。ファイルアクセスは、通常、事前にパッケージ化されたリソース(例えば、アプリケーションの.nmfマニフェストファイルに記述されたリソース)や、ブラウザのAPIを介して行われます。
  3. テストとテストデータ:

    • Goのテストは、通常、_test.goファイルに記述され、go testコマンドで実行されます。
    • テストの中には、外部ファイル(設定ファイル、入力データ、期待される出力など)を必要とするものがあります。これらのファイルは「テストデータ」と呼ばれます。
  4. 埋め込みリソース:

    • Goのバイナリに任意のファイルを埋め込む一般的な方法は、Goのコードとしてバイト配列に変換し、それをプログラム内で読み込むことです。これにより、外部ファイルへの依存をなくし、単一のバイナリとして配布できるようになります。このコミットでは、特にテストデータをzipファイルとして埋め込むアプローチが取られています。

これらの知識を前提として、コミットの技術的詳細を掘り下げていきます。

技術的詳細

このコミットは、GoのNaClビルドとテスト実行を可能にするために、いくつかの重要な技術的変更を導入しています。

  1. nacl.bashの導入:

    • src/all.bashのNaCl版としてsrc/nacltest.bashが追加されました。これは、NaCl環境に特化したビルドとテストのロジックを含んでいます。
    • 通常のall.bashがGoの標準的なビルドとテストを行うのに対し、nacltest.bashはNaClの制約と要件に合わせて調整されています。
  2. テストデータの埋め込みとmkzip.go:

    • NaCl環境では、テストが外部ファイルにアクセスすることが困難です。この問題を解決するため、テストに必要なすべての入力ファイルを一つの大きなzipファイルにまとめ、それをGoのバイナリに埋め込むというアプローチが取られました。
    • misc/nacl/mkzip.goという新しいGoプログラムが追加されました。このツールは、特定のプロトコルファイル(testzip.proto)で記述されたファイルツリー構造に基づいて、zipファイルを作成します。
    • mkzip.goは、src.protoという入力ファイルとout.zipという出力ファイルを引数にとります。src.protoは、どのファイルをzipに含めるか、そしてそれらのファイルがzip内でどのようなパスを持つかを定義します。
    • さらに、mkzip.go-pフラグを使用することで、生成されたzipファイルの内容をGoのソースコード(バイト配列として)として出力する機能を持っています。これにより、zipファイルがGoのバイナリに直接埋め込まれることが可能になります。
  3. testzip.protoの役割:

    • misc/nacl/testzip.protoは、mkzip.goがzipファイルを作成する際に参照する「プロトタイプ」ファイルです。これは、Plan 9のmkfsプロトタイプファイル形式にインスパイアされています。
    • このファイルは、タブによるインデントでディレクトリ構造を表現し、各行にはファイル名とオプションの属性(例: src=fooで元のファイルのパスを指定)が記述されます。
    • このプロトファイルには、etc/mime.typesusr/bin、Goの標準ライブラリのテストデータなど、Goのテストスイートが依存する様々なファイルが含まれています。特にmime.typesは非常に大きなファイルであり、これが埋め込まれることで、syscallパッケージのサイズが大きくなることが示唆されています。
  4. syscallパッケージのバリアント:

    • nacltest.bashは、mkzip.goを使用して生成されたzipファイルをsyscallパッケージに埋め込みます。これにより、NaCl環境で実行されるGoプログラムは、外部ファイルシステムにアクセスすることなく、必要なテストデータにアクセスできるようになります。
    • この埋め込みは、syscallパッケージの特定のビルドタグ(おそらくNaCl固有のタグ)が有効な場合にのみ行われるように設計されていると考えられます。
  5. os/execを使用するテストの無効化:

    • NaClのサンドボックスモデルでは、外部プロセスの実行(os/execパッケージが提供する機能)はセキュリティ上の理由から厳しく制限されるか、完全に禁止されます。
    • このコミットでは、os/execに依存するテストがNaCl環境で実行されないように、それらのテストを無効化する変更が含まれています。これは、テストファイルの変更(例: src/pkg/os/exec/exec_test.go)や、nacltest.bashスクリプト内での条件付き実行によって実現されています。

これらの変更により、GoのビルドシステムはNaClの特殊な環境に対応し、テストがサンドボックス内で必要なリソースにアクセスできるようになり、同時にNaClの制約に違反するテストはスキップされるようになります。

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

このコミットにおける主要なコード変更は以下のファイルに集中しています。

  1. misc/nacl/mkzip.go:

    • 新規追加されたファイル。
    • testzip.protoで定義されたファイル構造に基づいてzipファイルを作成するGoプログラム。
    • -pフラグを使用すると、zipの内容をGoのバイト配列として出力し、Goのソースコードに埋め込める形式にする機能を持つ。
  2. misc/nacl/testzip.proto:

    • 新規追加されたファイル。
    • mkzip.goがzipファイルを作成する際に参照するプロトタイプファイル。
    • Goのテストに必要な様々なファイル(例: mime.types, group, hostsなど)のパスと、それらをzip内でどのように配置するかを定義。
  3. src/nacltest.bash:

    • 新規追加されたファイル。
    • all.bashのNaCl版であり、NaCl環境でのGoのビルドとテスト実行をオーケストレーションするシェルスクリプト。
    • mkzip.goを呼び出してテストデータを埋め込んだsyscallパッケージをビルドするロジックが含まれる。
  4. src/all.bash:

    • 既存のファイルへの変更。
    • nacltest.bashの呼び出しや、NaCl関連のビルド設定が追加された可能性がある。
  5. 各種テストファイル (src/cmd/..._test.go, src/pkg/..._test.go, test/...go):

    • 多数の既存テストファイルに修正が加えられています。
    • 主に、os/execパッケージを使用するテストや、NaCl環境で問題を引き起こす可能性のあるテストが、NaClビルドタグが有効な場合にスキップされるように変更されています。これは、if runtime.GOOS == "nacl"のような条件分岐や、ビルドタグ(例: // +build !nacl)の追加によって実現されます。
    • 例: src/pkg/os/exec/exec_test.gosrc/pkg/net/http/cgi/matryoshka_test.goなど。
  6. misc/nacl/testdata/以下のファイル:

    • mime.types, group, hosts, empty, bin/placeholderなどが新規追加されています。
    • これらはtestzip.protoで参照され、最終的に埋め込まれるテストデータの一部となります。特にmime.typesは非常に大きなファイルです。

コアとなるコードの解説

このコミットの核心は、NaCl環境の制約を克服し、GoのテストスイートをNaCl上で実行可能にするための巧妙なデータ埋め込みとビルドプロセスの調整にあります。

mkzip.gotestzip.protoによるテストデータの埋め込み

mkzip.goは、Goのテストが実行時に必要とする外部ファイルを、単一のGoバイナリに埋め込むための重要なツールです。

  1. testzip.protoの解析: mkzip.goは、testzip.protoファイルを読み込み、その内容を解析します。testzip.protoは、以下のような形式でファイルツリーを記述します。

    etc     src=/etc
        mime.types  src=../misc/nacl/testdata/mime.types
        resolv.conf src=../misc/nacl/testdata/empty
    usr     src=../misc/nacl/testdata
        bin
    
    • 行頭のタブの数でディレクトリの階層構造を示します。
    • 最初のフィールドは、zipファイル内のパス名です。
    • src=...属性は、実際のファイルデータがどこから取得されるかを指定します。これが指定されない場合、同名のファイルが現在のソースディレクトリからコピーされます。
    • *+は、ディレクトリ内のすべてのファイルや、サブディレクトリを含めたすべてのファイルを再帰的に追加することを示します。
  2. Zipファイルの生成: mkzip.goは、解析した情報に基づいてarchive/zipパッケージを使用してzipファイルを作成します。各エントリは、testzip.protoで指定されたパスとソースからデータを取得して追加されます。

  3. Goソースコードへの変換(-pフラグ): 最も重要な機能の一つは、-pフラグが指定された場合です。この場合、mkzip.goはzipファイルの内容を直接ファイルに書き込むのではなく、Goのソースコードとして標準出力に出力します。具体的には、zipファイルのバイナリデータを16進数エスケープシーケンス(\xNN)の文字列リテラルに変換し、それをinit()関数内でunzip関数に渡す形式で出力します。

    package somepackage
    
    func init() {
        unzip("\x50\x4b\x03\x04\x14\x00\x00\x00...") // zipファイルのバイナリデータ
    }
    

    この生成されたGoコードは、Goのビルドプロセス中にsyscallパッケージ(または関連するパッケージ)にコンパイルされ、結果としてzipファイルの内容がGoのバイナリに埋め込まれます。

nacltest.bashによるビルドオーケストレーション

nacltest.bashは、NaCl環境向けのGoのビルドとテストを調整するスクリプトです。

  1. mkzip.goの実行: このスクリプトは、mkzip.goを呼び出し、testzip.protoを読み込ませて、テストデータを埋め込んだGoソースファイルを生成させます。この生成されたソースファイルは、Goのビルドシステムによってsyscallパッケージの一部としてコンパイルされます。

  2. syscallパッケージの特殊なビルド: NaCl環境では、syscallパッケージが通常のシステムコールではなく、NaClのnewlibglibcインターフェースを介して動作する必要があります。また、このコミットでは、前述の埋め込まれたテストデータにアクセスするためのロジックもsyscallパッケージ内に含まれるようになります。これにより、テストは実行時に外部ファイルシステムに依存することなく、必要なデータにアクセスできます。

  3. テストの選択的無効化: nacltest.bashは、NaCl環境で実行できないテスト(特にos/execを使用するもの)を特定し、それらをスキップするようにGoのテストコマンドを調整します。これは、テストファイル内のビルドタグ(例: // +build !nacl)や、テスト実行時の環境変数設定によって制御されます。

テストファイルの変更

多くのテストファイルでは、以下のような変更が加えられています。

// Some test code
if runtime.GOOS == "nacl" {
    t.Skip("skipping test on nacl")
}
// Original test logic

または、ファイルの先頭にビルドタグが追加されます。

// +build !nacl

package somepackage_test
// ...

これにより、naclビルドタグが有効な場合(つまりNaCl向けにビルドされる場合)、特定のテストファイル全体またはテスト関数がコンパイルから除外されるか、実行時にスキップされるようになります。これは、NaClのサンドボックスモデルではサポートされない機能(例: 外部プロセスの起動、特定のネットワーク操作、ファイルシステム操作)に依存するテストを適切に処理するために不可欠です。

これらの変更の組み合わせにより、GoはNaCl環境で動作し、そのテストスイートもNaClの制約内で実行可能になります。特に、テストデータの埋め込みは、NaClの制限されたファイルシステムアクセスに対する実用的な解決策を提供しています。

関連リンク

  • Go Issue #7945: https://github.com/golang/go/issues/7945

    • このコミットが修正したGoのIssueです。通常、Issueには問題の詳細な説明や議論が含まれています。
  • Go Code Review (CL) 100590044: https://golang.org/cl/100590044

    • このコミットに対応するGoのコードレビューページです。ここには、コミットがマージされるまでの議論、レビューコメント、変更の差分などが詳細に記録されています。

参考にした情報源リンク

  • Google Native Client (NaCl) 公式ドキュメント:
  • Go言語の公式ドキュメント:
    • Goのビルドシステム、パッケージ、テストに関する一般的な情報。
  • Go言語のソースコード:
    • src/all.bashsrc/make.bashなど、Goのビルドプロセスに関連するスクリプト。
    • os/execパッケージのドキュメント。
  • Plan 9 mkfs:

(注: 上記の参考情報源リンクは、当時の技術背景を理解するための一般的な情報源であり、このコミットが直接参照したものではない可能性があります。特にNaClは現在では非推奨の技術ですが、コミット当時の状況を説明するために言及しています。)