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

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

このコミットは、Go言語のテストスイートの一部である test/run.go ファイルにおける、Windows環境での実行可能ファイル名の取り扱いに関するバグ修正です。具体的には、Windows上でビルドされるテスト実行可能ファイルの出力名を、従来の .out 拡張子からWindows標準の .exe 拡張子に変更し、それによってビルドおよびテスト実行が正しく行われるように修正しています。

コミット

commit e8246569075c98c6cf13b158a11d0b968b1b6297
Author: Shenghou Ma <minux.ma@gmail.com>
Date:   Mon Oct 8 01:54:56 2012 +0800

    test/run.go: use correct executable filename on Windows, fix build
    
    R=golang-dev, daniel.morsing
    CC=golang-dev
    https://golang.org/cl/6624060

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

https://github.com/golang/go/commit/e8246569075c98c6cf13b158a11d0b968b1b6297

元コミット内容

test/run.go: use correct executable filename on Windows, fix build

このコミットは、test/run.go ファイルにおいて、Windows環境での実行可能ファイル名が正しく使用されるように修正し、それによってビルドの問題を解決することを目的としています。

変更の背景

Go言語のテストフレームワークやビルドシステムは、様々なオペレーティングシステム(OS)上で動作するように設計されています。しかし、OSごとに実行可能ファイルの命名規則や慣習が異なります。特にWindows環境では、実行可能ファイルには通常 .exe という拡張子が付与されます。

このコミット以前の test/run.go では、テスト実行可能ファイルの出力名として、OSに関わらず一律に .out 拡張子を使用していたと考えられます。これは、Unix系OS(LinuxやmacOSなど)では実行可能ファイルに特定の拡張子を必要としないため問題になりませんが、Windowsでは .exe 拡張子がないと、システムがそのファイルを直接実行可能ファイルとして認識しない、あるいは実行時に問題が発生する可能性があります。

この不一致が原因で、Windows環境でのGoのテストビルドが失敗したり、ビルドされたテストバイナリが正しく実行できないという問題が発生していました。このコミットは、この問題を解決するために、Windows環境での実行可能ファイル名を .exe に変更する必要がありました。

前提知識の解説

Go言語のビルドプロセスと go tool ld

Go言語のプログラムは、go build コマンドによってコンパイルされ、実行可能ファイルが生成されます。このプロセスには、コンパイラ(go tool compile)とリンカ(go tool ld)が関与します。

  • コンパイラ (go tool compile): Goのソースコードをオブジェクトファイル(.o)に変換します。
  • リンカ (go tool ld): コンパイラによって生成されたオブジェクトファイルや、Goの標準ライブラリ、その他の依存関係を結合し、最終的な実行可能ファイルを生成します。リンカは -o オプションを使用して出力ファイル名を指定できます。

このコミットで変更されている runcmd("go", "tool", ld, "-o", ...) の部分は、まさにこのリンカ (ld) を呼び出して実行可能ファイルを生成している箇所です。

Windowsにおける実行可能ファイル

Windowsオペレーティングシステムでは、実行可能ファイルは通常、ファイル名の末尾に .exe 拡張子を持ちます。例えば、program.exe のように命名されます。これはWindowsがファイルを識別し、実行するための標準的な慣習です。.exe 拡張子がないファイルでも実行可能な場合がありますが、それは稀であり、通常はシステムがそのファイルを直接実行可能ファイルとして認識しません。

filepath.Join

Go言語の path/filepath パッケージに含まれる Join 関数は、OS固有のパス区切り文字(Windowsでは \、Unix系では /)を使用して、複数のパス要素を結合します。これにより、異なるOS環境でも正しくパスを構築できます。

技術的詳細

このコミットは、test/run.go ファイル内の2つの箇所を変更しています。これらの変更は、Windows環境での実行可能ファイルの命名規則に準拠させることを目的としています。

  1. linkFile 関数内の出力ファイル名変更: linkFile 関数は、Goのソースファイルをリンクして実行可能ファイルを生成する役割を担っています。変更前は、リンカの出力ファイル名として "run.out" を指定していました。

    // 変更前
    _, err = runcmd("go", "tool", ld, "-o", "run.out", "-L", ".", pfile)
    // 変更後
    _, err = runcmd("go", "tool", ld, "-o", "a.exe", "-L", ".", pfile)
    

    この変更により、リンカは run.out ではなく a.exe という名前で実行可能ファイルを生成するようになります。a.exe は、Unix系OSにおける a.out に相当する、一般的なデフォルトの実行可能ファイル名です。

  2. test.run メソッド内の実行ファイルパス変更: test.run メソッドは、ビルドされたテスト実行可能ファイルを実際に実行する部分です。変更前は、filepath.Join(t.tempDir, "run.out") を使用して実行ファイルのパスを構築していました。

    // 変更前
    out, err := runcmd(append([]string{filepath.Join(t.tempDir, "run.out")}, args...)...)
    // 変更後
    out, err := runcmd(append([]string{filepath.Join(t.tempDir, "a.exe")}, args...)...)
    

    この変更により、test.run メソッドは、linkFile 関数によって生成された新しい名前 (a.exe) の実行可能ファイルを正しく参照し、実行できるようになります。

これらの変更は、Windows環境でGoのテストが正しくビルドされ、実行されるために不可欠でした。

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

diff --git a/test/run.go b/test/run.go
index c22bfb2ec3..a6464e3802 100644
--- a/test/run.go
+++ b/test/run.go
@@ -177,7 +177,7 @@ func compileInDir(runcmd runCmd, dir, name string) (out []byte, err error) {
 
  func linkFile(runcmd runCmd, goname string) (err error) {
  	pfile := strings.Replace(goname, ".go", "."+letter, -1)
-	_, err = runcmd("go", "tool", ld, "-o", "run.out", "-L", ".", pfile)
+	_, err = runcmd("go", "tool", ld, "-o", "a.exe", "-L", ".", pfile)
  	return
  }
 
@@ -440,7 +440,7 @@ func (t *test) run() {
  		t.err = err
  		return
  	}
-	out, err := runcmd(append([]string{filepath.Join(t.tempDir, "run.out")}, args...)...)
+	out, err := runcmd(append([]string{filepath.Join(t.tempDir, "a.exe")}, args...)...)
  	if err != nil {
  		t.err = err
  		return

コアとなるコードの解説

上記の差分は、test/run.go ファイル内の2つの重要な変更を示しています。

  1. linkFile 関数内の変更:

    -	_, err = runcmd("go", "tool", ld, "-o", "run.out", "-L", ".", pfile)
    +	_, err = runcmd("go", "tool", ld, "-o", "a.exe", "-L", ".", pfile)
    

    この行は、Goのリンカ (go tool ld) を呼び出して実行可能ファイルを生成する部分です。

    • -o フラグは出力ファイル名を指定します。
    • 変更前は "run.out" という名前で出力されていました。これはUnix系OSでは問題ありませんが、Windowsでは実行可能ファイルとして認識されにくい名前です。
    • 変更後は "a.exe" という名前に変更されています。これはWindowsにおける実行可能ファイルの標準的な拡張子であり、システムが正しく実行可能ファイルとして認識できるようになります。
  2. test.run メソッド内の変更:

    -	out, err := runcmd(append([]string{filepath.Join(t.tempDir, "run.out")}, args...)...)
    +	out, err := runcmd(append([]string{filepath.Join(t.tempDir, "a.exe")}, args...)...)
    

    この行は、ビルドされたテスト実行可能ファイルを実際に実行する部分です。

    • filepath.Join(t.tempDir, "run.out") は、一時ディレクトリ (t.tempDir) 内の run.out というファイルを指していました。
    • 変更後は filepath.Join(t.tempDir, "a.exe") となり、linkFile 関数によって生成される新しい名前の実行可能ファイルを正しく参照するようになります。

これらの変更により、Windows環境でのGoのテストビルドと実行が、OSの命名規則に準拠し、正常に動作するようになりました。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • Windowsオペレーティングシステムのファイル命名規則に関する一般的な知識