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

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

このコミットは、Go言語のツールチェインの一部である cmd/pack のテストコード pack_test.go における変更です。具体的には、go build コマンドがWindows環境で実行可能ファイルに自動的に .exe サフィックスを追加する挙動に対応するため、テスト内でビルドされる実行可能ファイルの名前を明示的に指定するように修正しています。これにより、テストの安定性とクロスプラットフォーム互換性が向上しました。

コミット

commit 0d11cd1b6ecede754c3bf24c87a955d175568093
Author: Alex Brainman <alex.brainman@gmail.com>
Date:   Thu Feb 20 11:29:37 2014 +1100

    cmd/pack: provide executable name in TestHello
    
    otherwise go build command adds .exe suffix
    
    Fixes #7362
    
    LGTM=bradfitz
    R=golang-codereviews, bradfitz
    CC=golang-codereviews
    https://golang.org/cl/66250043

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

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

元コミット内容

cmd/pack: provide executable name in TestHello

otherwise go build command adds .exe suffix

Fixes #7362

LGTM=bradfitz
R=golang-codereviews, bradfitz
CC=golang-codereviews
https://golang.org/cl/66250043

変更の背景

このコミットは、Go言語のビルドシステムにおける特定の挙動、特にWindows環境での実行可能ファイル名の自動的なサフィックス追加に対応するために行われました。

Go言語の go build コマンドは、デフォルトではビルド対象のパッケージ名に基づいて実行可能ファイル名を決定します。例えば、main パッケージを含む cmd/pack をビルドすると、通常は pack という名前の実行可能ファイルが生成されます。しかし、Windows環境では、実行可能ファイルには慣例的に .exe という拡張子が付与されます。go build はこの慣例に従い、Windows上でビルドを行うと自動的に pack.exe のようなファイル名を生成します。

TestHello というテスト関数では、cmd/pack をビルドした後、そのビルドされた pack バイナリを ./pack というパスで実行しようとしていました。しかし、Windows環境で pack.exe が生成されると、./pack という名前ではファイルが見つからず、テストが失敗するという問題が発生していました。

この問題は、Go issue #7362 として報告されており、このコミットはその問題を解決するために導入されました。テストの実行環境に依存しない形で、ビルドされた実行可能ファイルにアクセスできるようにすることが目的です。

前提知識の解説

Go言語のビルドシステム (go build)

go build はGo言語のソースコードをコンパイルして実行可能バイナリを生成するためのコマンドです。

  • デフォルトの出力ファイル名: go build は、特に指定がない場合、ビルド対象のパッケージ名(main パッケージの場合)またはディレクトリ名に基づいて出力ファイル名を決定します。例えば、go build ./cmd/pack と実行すると、カレントディレクトリに pack (または pack.exe on Windows) という名前のバイナリが生成されます。
  • -o フラグ: go build コマンドには -o フラグがあり、これを使用することで出力される実行可能ファイルの名前とパスを明示的に指定できます。例: go build -o myapp ./cmd/myappmyapp という名前のバイナリを生成します。
  • クロスプラットフォームビルド: Goはクロスプラットフォーム開発を強力にサポートしており、GOOS (オペレーティングシステム) や GOARCH (アーキテクチャ) といった環境変数を設定することで、異なるOSやアーキテクチャ向けのバイナリをビルドできます。この際、OS固有のファイル名規則(例: Windowsの .exe 拡張子)が適用されることがあります。

cmd/pack

cmd/pack は、Go言語の初期のツールチェインの一部であり、Goのアーカイブファイル(.a 拡張子を持つファイル)を操作するためのコマンドでした。これは、C言語の ar コマンドに似た機能を提供し、オブジェクトファイルやライブラリをまとめるために使用されていました。現代のGoでは、go buildgo install が内部的にこれらの処理を抽象化しているため、直接 pack コマンドを使用することは稀です。しかし、Goのビルドシステムやリンカの低レベルなテストでは、このようなツールが使われることがあります。

go tool

go tool は、Goツールチェインに含まれる低レベルなツール(アセンブラ go tool asm、リンカ go tool link、コンパイラ go tool compile など)を実行するためのコマンドです。これらのツールは通常、go buildgo run のような高レベルなコマンドによって内部的に呼び出されますが、開発者やテストコードが特定のビルドステップを細かく制御したい場合に直接使用されることがあります。このコミットでは go tool char+g (コンパイラ) や go tool char+l (リンカ) が使われています。charGOCHAR 環境変数から取得され、ターゲットアーキテクチャを示す文字(例: 8 for amd64)が入ります。

技術的詳細

このコミットの核心は、go build コマンドの呼び出し方にあります。

変更前:

run("go", "build", "cmd/pack") // writes pack binary to dir

このコマンドは、cmd/pack パッケージをビルドし、その結果生成される実行可能ファイルをカレントディレクトリに配置します。Windows環境では、この実行可能ファイルは pack.exe という名前になります。しかし、その後のテストコードでは、このバイナリを ./pack という固定の名前で参照しようとしていました。

変更後:

run("go", "build", "-o", "pack", "cmd/pack") // writes pack binary to dir

この変更では、go build コマンドに -o pack という引数を追加しています。

  • -o フラグは、出力ファイルの名前を明示的に指定します。
  • pack は、出力ファイルの名前として指定された文字列です。

これにより、go build は、オペレーティングシステムに関わらず、常に pack という名前の実行可能ファイルを生成するようになります。Windows環境であっても、pack.exe ではなく pack という名前でファイルが作成されるため、その後の ./pack という参照が正しく機能し、テストが安定して実行されるようになります。

この修正は、テストコードが特定のOSのファイル命名規則に依存しないようにすることで、テストのポータビリティと信頼性を向上させるものです。

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

--- a/src/cmd/pack/pack_test.go
+++ b/src/cmd/pack/pack_test.go
@@ -202,7 +202,7 @@ func TestHello(t *testing.T) {
 	t.Fatal("cannot find GOCHAR in 'go env' output:\n", out)
 	}
 	char := fields[1]
-	run("go", "build", "cmd/pack") // writes pack binary to dir
+	run("go", "build", "-o", "pack", "cmd/pack") // writes pack binary to dir
 	run("go", "tool", char+"g", "hello.go")
 	run("go", "tool", char+"l", "-o", "a.out", "hello.a")

コアとなるコードの解説

変更された行は src/cmd/pack/pack_test.go ファイルの204行目です。

  • 変更前: run("go", "build", "cmd/pack")

    • これは go build cmd/pack というシェルコマンドを実行します。
    • Windowsでは、このコマンドは pack.exe という名前の実行可能ファイルを生成します。
    • テストコードの次のステップでは、このバイナリを ./pack として実行しようとしますが、pack.exe が存在するためファイルが見つからずエラーになります。
  • 変更後: run("go", "build", "-o", "pack", "cmd/pack")

    • これは go build -o pack cmd/pack というシェルコマンドを実行します。
    • -o pack オプションは、出力ファイルの名前を明示的に pack に指定します。
    • これにより、Windowsを含むすべてのOSで、pack という名前の実行可能ファイルが生成されます。
    • 結果として、その後の ./pack という実行コマンドが正しく機能し、テストが成功するようになります。

この修正は、Goのビルドコマンドの挙動をより細かく制御することで、テストの堅牢性を高める典型的な例です。

関連リンク

参考にした情報源リンク