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

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

このコミットは、Go言語のビルドシステムで使用される make.bat スクリプトが、ディレクトリ名にスペースを含むパスを適切に処理できるようにするための修正です。具体的には、move コマンドや go_bootstrap コマンドの実行時に、パスが正しく引用符で囲まれていないために発生していた問題を解決します。これにより、Windows環境でGoのソースコードをビルドする際に、インストールパスやツールディレクトリのパスにスペースが含まれていても、ビルドが正常に完了するようになります。

コミット

commit f26b1f8056284537b05be8003973abb4e84da811
Author: Alex Brainman <alex.brainman@gmail.com>
Date:   Tue Mar 13 16:50:44 2012 +1100

    make.bat: properly handle directories with spaces
    
    R=golang-dev, minux.ma
    CC=golang-dev
    https://golang.org/cl/5797079

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

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

元コミット内容

make.bat: properly handle directories with spaces

このコミットメッセージは、make.bat スクリプトがスペースを含むディレクトリを適切に処理するように修正されたことを簡潔に示しています。

変更の背景

Windows環境では、ファイルパスやディレクトリパスにスペースが含まれることが一般的です(例: C:\Program Files\Go)。しかし、コマンドラインインターフェース(CLI)やバッチスクリプトにおいて、スペースを含むパスを適切に引用符で囲まないと、コマンドがパスのスペースを区切り文字として解釈し、予期せぬエラーや動作不良を引き起こすことがあります。

このコミット以前の make.bat スクリプトでは、move コマンドや go_bootstrap コマンドの引数として渡されるパスが引用符で囲まれていませんでした。そのため、Goのツールディレクトリ (%GOTOOLDIR%) のパスにスペースが含まれている場合、これらのコマンドがパスを正しく認識できず、ビルドプロセスが失敗していました。

この問題は、GoのビルドシステムがWindows環境でより堅牢に動作するために、必須の修正でした。特に、ユーザーがデフォルトのインストールパス(Program Filesなど)を使用する場合に、ビルドが中断されることを防ぐ目的がありました。

前提知識の解説

バッチスクリプト (.bat ファイル)

バッチスクリプトは、Windowsオペレーティングシステムでコマンドを自動的に実行するための一連のコマンドを含むテキストファイルです。.bat または .cmd 拡張子を持ち、コマンドプロンプト(cmd.exe)によって解釈・実行されます。

バッチスクリプトでは、コマンドの引数としてスペースを含むパスを渡す場合、そのパス全体を二重引用符 (") で囲む必要があります。例えば、C:\Program Files\My App というパスを cd コマンドで指定する場合、cd "C:\Program Files\My App" と記述する必要があります。引用符がないと、cd C:\ProgramFiles\MyApp がそれぞれ別の引数として解釈され、エラーになります。

Goのビルドシステムと make.bat

Go言語のソースコードからGoツールチェイン(コンパイラ、リンカ、標準ライブラリなど)をビルドするプロセスは、プラットフォームごとに異なるスクリプトを使用します。Windows環境では、src/make.bat がその役割を担っています。

このスクリプトは、Goのビルドに必要な様々なステップ(ブートストラップコンパイラのビルド、ツールの移動、標準ライブラリのインストールなど)を自動化します。

  • %GOTOOLDIR%: Goのビルドツールが配置されるディレクトリを示す環境変数です。
  • dist: Goのビルドプロセスで使用される内部ツールの一つで、ブートストラップコンパイラのビルドやツールの配置などを行います。
  • go_bootstrap: Goのビルド初期段階で使用される、限定的な機能を持つGoコンパイラおよびツールです。最終的なGoツールチェインがビルドされるまでの間、一時的に使用されます。

パスにおけるスペースの問題

Windowsのファイルシステムでは、ファイル名やディレクトリ名にスペースを含めることが許容されています。しかし、コマンドラインやスクリプトでこれらのパスを扱う際には、スペースが引数の区切り文字として解釈されるため、特別な注意が必要です。パス全体を引用符で囲むことで、スペースを含むパスを単一の引数として認識させることができます。これは、多くのプログラミング言語やシェル環境で共通の慣習です。

技術的詳細

このコミットの技術的詳細は、バッチスクリプトにおけるパスの引用符付けの重要性に集約されます。

変更前は、move コマンドや go_bootstrap コマンドの引数として渡されるパス(例: %GOTOOLDIR%\\dist.exe%GOTOOLDIR%\\go_bootstrap) が引用符で囲まれていませんでした。

move .\\cmd\\dist\\dist.exe %GOTOOLDIR%\\dist.exe
%GOTOOLDIR%\\go_bootstrap clean -i std

もし %GOTOOLDIR%C:\Program Files\Go のような値であった場合、上記の行は以下のように展開されます。

move .\\cmd\\dist\\dist.exe C:\Program Files\Go\\dist.exe
C:\Program Files\Go\\go_bootstrap clean -i std

この場合、move コマンドは C:\Program を最初の引数、Files\Go\\dist.exe を次の引数として解釈しようとします。同様に、C:\Program は実行可能なコマンドとして認識されず、Files\Go\\go_bootstrap は別の引数として扱われます。これにより、「ファイルが見つかりません」や「コマンドが無効です」といったエラーが発生し、ビルドが中断されます。

このコミットでは、影響を受けるすべてのパスを二重引用符で囲むことでこの問題を解決しています。

move .\\cmd\\dist\\dist.exe \"%GOTOOLDIR%\\dist.exe\"
\"%GOTOOLDIR%\\go_bootstrap\" clean -i std

これにより、%GOTOOLDIR% がスペースを含むパスであっても、コマンドプロンプトはパス全体を単一の引数として正しく解釈し、コマンドが意図通りに実行されるようになります。

この修正は、GoのビルドプロセスがWindows環境でより堅牢になり、ユーザーがGoをインストールするディレクトリの選択肢が広がるという点で非常に重要です。

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

--- a/src/make.bat
+++ b/src/make.bat
@@ -46,8 +46,8 @@ if x%1==x--no-clean set buildall=\
 .\\cmd\\dist\\dist bootstrap %buildall% -v
 if errorlevel 1 goto fail
 :: Delay move of dist tool to now, because bootstrap cleared tool directory.
-move .\\cmd\\dist\\dist.exe %GOTOOLDIR%\\dist.exe
-%GOTOOLDIR%\\go_bootstrap clean -i std
+move .\\cmd\\dist\\dist.exe \"%GOTOOLDIR%\\dist.exe\"
+\"%GOTOOLDIR%\\go_bootstrap\" clean -i std
 echo.
 
 if not %GOHOSTARCH% == %GOARCH% goto localbuild
@@ -59,20 +59,20 @@ echo # Building tools for local system. %GOHOSTOS%/%GOHOSTARCH%\
 setlocal
 set GOOS=%GOHOSTOS%\
 set GOARCH=%GOHOSTARCH%\
-%GOTOOLDIR%\\go_bootstrap install -v std
+\"%GOTOOLDIR%\\go_bootstrap\" install -v std
 endlocal
 if errorlevel 1 goto fail
 echo.
 
 :mainbuild
 echo # Building packages and commands.
-%GOTOOLDIR%\\go_bootstrap install -a -v std
+\"%GOTOOLDIR%\\go_bootstrap\" install -a -v std
 if errorlevel 1 goto fail
-del %GOTOOLDIR%\\go_bootstrap.exe
+del \"%GOTOOLDIR%\\go_bootstrap.exe\"
 echo.
 
 if x%1==x--no-banner goto nobanner
-%GOTOOLDIR%\\dist banner
+\"%GOTOOLDIR%\\dist\" banner
 :nobanner
 
 goto end

コアとなるコードの解説

上記の差分は、src/make.bat ファイル内の複数の行で、パスを含む変数やコマンドの実行パスを二重引用符 (") で囲む変更が加えられていることを示しています。

  1. move .\\cmd\\dist\\dist.exe %GOTOOLDIR%\\dist.exe から move .\\cmd\\dist\\dist.exe \"%GOTOOLDIR%\\dist.exe\": move コマンドの第二引数である %GOTOOLDIR%\\dist.exe が引用符で囲まれました。これにより、%GOTOOLDIR% にスペースが含まれていても、dist.exe の移動先パスが正しく一つの引数として認識されます。

  2. %GOTOOLDIR%\\go_bootstrap clean -i std から \"%GOTOOLDIR%\\go_bootstrap\" clean -i std: go_bootstrap コマンドの実行パス自体が引用符で囲まれました。これは、%GOTOOLDIR% にスペースが含まれる場合に、go_bootstrap 実行ファイルへのパスが正しく解釈されるようにするためです。

  3. %GOTOOLDIR%\\go_bootstrap install -v std から \"%GOTOOLDIR%\\go_bootstrap\" install -v std: 同様に、go_bootstrap install コマンドの実行パスも引用符で囲まれました。

  4. del %GOTOOLDIR%\\go_bootstrap.exe から del \"%GOTOOLDIR%\\go_bootstrap.exe\": del コマンドの対象パスである %GOTOOLDIR%\\go_bootstrap.exe が引用符で囲まれました。これにより、go_bootstrap.exe の削除が正しく行われます。

  5. %GOTOOLDIR%\\dist banner から \"%GOTOOLDIR%\\dist\" banner: dist コマンドの実行パスも引用符で囲まれました。

これらの変更はすべて、Windowsのバッチスクリプトにおけるスペースを含むパスの処理という共通の問題に対処しています。引用符を追加することで、コマンドプロンプトがパス全体を単一の文字列として扱い、コマンドの実行が安定するようになります。

関連リンク

参考にした情報源リンク

  • Windows Batch Scripting (一般的なバッチスクリプトの構文とパスの引用符付けに関する情報)
  • Go言語のビルドプロセスに関する公式ドキュメント (Goのビルドシステム、distgo_bootstrap の役割に関する情報)
  • Stack Overflow や技術ブログ (Windowsにおけるパスのスペース問題と解決策に関する一般的な情報)