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

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

このコミットは、Go言語のディストリビューションプロセスにおけるWindows環境でのgotourバイナリのファイル名に関する修正です。具体的には、Windows上でgotourが正しく実行可能ファイルとして認識されるように、.exe拡張子を明示的に追加する変更が行われています。

コミット

commit 81063812b4e6923d079dd15bdede237072d4842f
Author: Andrew Gerrand <adg@golang.org>
Date:   Tue Apr 9 18:17:55 2013 +1000

    dist: add .exe extension to tour.exe
    
    Fixes #5246.
    
    R=golang-dev, dsymonds
    CC=golang-dev
    https://golang.org/cl/8558044

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

https://github.com/golang/go/commit/81063812b4e6923d079dd15bdede237072d4842f

元コミット内容

このコミットの元のメッセージは以下の通りです。

dist: add .exe extension to tour.exe

Fixes #5246.

これは、tour.exeという実行可能ファイルに.exe拡張子を追加するという、ディストリビューション関連の修正であることを示しています。Fixes #5246は、このコミットがGoのIssue 5246を解決することを示唆しています。

変更の背景

この変更の背景には、Windowsオペレーティングシステムにおける実行可能ファイルの命名規則と、Go言語のクロスコンパイルおよびディストリビューションの仕組みがあります。

Go言語の公式チュートリアルである「Go Tour」は、gotourというコマンドラインツールとして提供されています。このツールは、Goのソースコードからビルドされ、ユーザーのシステムにインストールされます。

Windows環境では、実行可能ファイルは通常.exeという拡張子を持ちます。しかし、Goのビルドプロセスでは、デフォルトで生成されるバイナリにはプラットフォーム固有の拡張子が付与されない場合があります。このため、Windows上でgotourバイナリが生成された際に、.exe拡張子が付いていないと、システムがそれを直接実行可能ファイルとして認識せず、コマンドラインからの実行が困難になるという問題が発生していました。

Issue #5246("cmd/go: go tool tour fails on windows")は、まさにこの問題、すなわちWindows環境でgo tool tourコマンドが失敗するというバグを報告していました。このコミットは、この問題を解決するために、gotourバイナリをWindows向けにコピーする際に、明示的に.exe拡張子を付与するように修正するものです。

前提知識の解説

Go Tour (gotour)

Go Tourは、Go言語の基本的な概念と構文をインタラクティブに学ぶことができる公式のチュートリアルです。通常、go tool tourコマンドを実行することで、ローカルのWebサーバーが起動し、ブラウザを通じてチュートリアルにアクセスできます。

go toolコマンド

go toolコマンドは、Goツールチェインに含まれる様々な補助ツールを実行するためのコマンドです。例えば、go tool vetはコードの静的解析を行い、go tool pprofはプロファイリングデータ解析に用いられます。go tool tourもこのカテゴリに属します。

クロスコンパイル

Go言語は、異なるオペレーティングシステムやアーキテクチャ向けのバイナリを、現在の環境でビルドする「クロスコンパイル」を強力にサポートしています。例えば、Linux環境でWindows向けの実行可能ファイルをビルドすることができます。この際、ターゲットOSの特性(例: 実行可能ファイルの拡張子)を考慮する必要があります。

misc/dist/bindist.go

このファイルは、Go言語の公式ディストリビューション(バイナリ配布)を構築する際のロジックを定義しているGoのソースファイルです。Goのリリースプロセスにおいて、様々なプラットフォーム向けのバイナリパッケージを作成する際に使用されます。このファイルには、各ツールやライブラリがどのようにパッケージングされ、どのパスに配置されるかといった情報が含まれています。

filepath.Join

Go言語の標準ライブラリpath/filepathパッケージに含まれる関数で、OS固有のパス区切り文字を使用して、複数のパス要素を結合します。これにより、異なるOS環境でも正しくパスを構築できます。

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

Windowsでは、実行可能ファイルは通常.exe.com.bat.cmdなどの拡張子を持ちます。特に.exeは最も一般的で、システムがプログラムとして認識し、直接実行するために不可欠な拡張子です。

技術的詳細

このコミットは、misc/dist/bindist.goファイル内のtour()関数を変更しています。この関数は、Goディストリビューションの一部としてgotourバイナリを準備する役割を担っています。

変更前は、gotourバイナリのファイル名を決定する際に、Windowsの場合にのみ.exe拡張子を追加するロジックが、gotourという変数に直接文字列を結合する形で行われていました。

変更後は、まずextという新しい変数を導入し、これを空文字列で初期化します。そして、runtime.GOOS == "windows"(現在のビルドターゲットOSがWindowsであるか)をチェックし、もしWindowsであればext変数に.exeを設定します。

このext変数を、filepath.Join関数でパスを結合する際に、tourバイナリのコピー元とコピー先のファイル名に適用しています。

具体的には、以下の2つのパスが変更されています。

  1. コピー元パス: filepath.Join(b.root, "pkg", "tool", b.OS+"_"+b.Arch, "tour")

    • 変更前は、tourというファイル名でバイナリを探していました。
    • 変更後は、filepath.Join(b.root, "pkg", "tool", b.OS+"_"+b.Arch, "tour"+ext)となり、Windowsの場合はtour.exeを探すようになります。
  2. コピー先パス: filepath.Join(b.gopath, "bin", gotour)

    • 変更前は、gotourという変数(Windowsの場合はgotour.exe)をそのまま使用していました。
    • 変更後は、filepath.Join(b.gopath, "bin", "gotour"+ext)となり、Windowsの場合はgotour.exeとしてコピーされるようになります。

この修正により、Windows環境でビルドされたgotourバイナリは、常に正しい.exe拡張子を持つようになり、システムによって実行可能ファイルとして正しく認識されるようになります。

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

--- a/misc/dist/bindist.go
+++ b/misc/dist/bindist.go
@@ -423,13 +423,13 @@ func (b *Build) tour() error {
 	}
 
 	// Copy gotour binary to tool directory as "tour"; invoked as "go tool tour".
-	gotour := "gotour"
-	if runtime.GOOS == "windows" {
-		gotour += ".exe"
+	ext := ""
+	if runtime.GOOS == "windows" {
+		ext = ".exe"
 	}
 	return cp(
-		filepath.Join(b.root, "pkg", "tool", b.OS+"_"+b.Arch, "tour"),
-		filepath.Join(b.gopath, "bin", gotour),
+		filepath.Join(b.root, "pkg", "tool", b.OS+"_"+b.Arch, "tour"+ext),
+		filepath.Join(b.gopath, "bin", "gotour"+ext),
 	)
 }

コアとなるコードの解説

変更の中心は、tour()関数内のgotourバイナリのファイル名処理です。

  1. gotour := "gotour" の削除と ext := "" の追加:

    • 変更前は、gotourという変数に初期値として"gotour"が設定されていました。
    • 変更後は、extという新しい変数が導入され、初期値は空文字列""です。これは、拡張子を動的に決定するための準備です。
  2. if runtime.GOOS == "windows" { ... } ブロックの変更:

    • 変更前は、Windowsの場合にgotour変数に直接".exe"を結合していました。
    • 変更後は、Windowsの場合にext変数に".exe"を代入します。これにより、拡張子の有無がext変数によって制御されるようになります。
  3. filepath.Join の引数変更:

    • cp関数(ファイルコピーを行う関数)の第一引数(コピー元パス)において、"tour"extを結合するようになりました。これにより、Windowsではtour.exeという名前のファイルがコピー元として指定されます。
    • cp関数の第二引数(コピー先パス)において、gotour変数ではなく、"gotour"extを結合するようになりました。これにより、Windowsではgotour.exeという名前でファイルがコピーされます。

この変更により、Windows環境でのgotourバイナリのコピー元とコピー先の両方で、.exe拡張子が適切に付与されるようになり、Issue #5246で報告された問題が解決されます。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • GitHubのGoリポジトリのIssueトラッカー
  • Go言語のソースコード(特にmisc/dist/bindist.go
  • path/filepathパッケージのドキュメント
  • Windowsの実行可能ファイルに関する一般的な知識
  • Go言語のクロスコンパイルに関する情報
  • go toolコマンドに関する情報