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

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

このコミットは、Goプロジェクトのビルドスクリプトであるsrc/make.batファイルから、環境変数GOROOTおよびGOROOT_FINALを設定する際の二重引用符を削除する変更です。これにより、Windows環境でのビルドプロセスにおけるパス解釈の問題を解決し、Fixes #2974で報告された不具合に対応しています。

コミット

commit 9a469e6ab536e32600d7a3e002ce387bf10a6780
Author: Alex Brainman <alex.brainman@gmail.com>
Date:   Fri Feb 10 11:48:22 2012 +1100

    make.bat: remove double quotes
    
    Fixes #2974.
    
    R=golang-dev, r, rsc
    CC=golang-dev
    https://golang.org/cl/5653052

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

https://github.com/golang/go/commit/9a469e6ab536e32600d7a3e002ce387bf10a6780

元コミット内容

make.bat: remove double quotes

Fixes #2974.

R=golang-dev, r, rsc
CC=golang-dev
https://golang.org/cl/5653052

変更の背景

この変更は、Windows環境でGoのビルドを行う際に使用されるmake.batスクリプトにおける、パスの解釈に関する問題を修正するために行われました。具体的には、GOROOTおよびGOROOT_FINALという環境変数を設定する際に、パスを二重引用符で囲んでいたことが原因で、cmd.exe(Windowsのコマンドプロンプト)がこれらのパスを正しく解釈できない場合がありました。

Windowsのバッチファイル(.bat)では、コマンドライン引数や環境変数の値にスペースが含まれる場合、通常は二重引用符で囲むことが推奨されます。しかし、cmd.exeの内部的なパス解釈や、Goのツールチェインがこれらの変数をどのように利用するかによっては、二重引用符が存在することで予期せぬ問題が発生することがあります。例えば、パスが既に二重引用符で囲まれているにもかかわらず、さらに別の処理で引用符が追加されたり、引用符自体がパスの一部として誤って解釈されたりするケースが考えられます。

このコミットは、Fixes #2974として参照されており、これはGoプロジェクトのIssueトラッカーで報告された特定の不具合に対応しています。この不具合は、make.batGOROOTを設定する際に、二重引用符が原因でビルドが失敗したり、予期せぬ動作を引き起こしたりする状況を示唆しています。二重引用符を削除することで、cmd.exeがパスをより直接的に、かつ意図した通りに解釈できるようになり、ビルドプロセスの堅牢性が向上します。

前提知識の解説

  • make.bat: Go言語のソースコードをWindows環境でビルドするためのバッチスクリプトです。Unix/Linux環境におけるMakefileに相当する役割を果たします。Goの初期のビルドシステムの一部であり、Goのコンパイラや標準ライブラリなどを構築するために使用されます。
  • GOROOT: Goのインストールディレクトリ、またはGoのソースコードが配置されているルートディレクトリを示す環境変数です。Goのツールチェイン(コンパイラ、リンカなど)は、このGOROOTを基準にして必要なファイルやライブラリを探します。
  • GOROOT_FINAL: GOROOTと同様にGoのルートディレクトリを示す変数ですが、これは最終的にビルドされたGoのバイナリが使用するGOROOTの値を表すことが多いです。ビルド時にGOROOTが一時的なパスを指している場合でも、最終的なインストールパスをGOROOT_FINALで指定することで、ビルド後の実行環境でのパス解決を適切に行うことができます。
  • setコマンド (Windows Batch): Windowsのバッチファイルで環境変数を設定するために使用されるコマンドです。例えば、set VAR=valueのように記述します。
  • %CD% (Windows Batch): 現在のディレクトリのパスを表す特殊な環境変数です。
  • 二重引用符 (") とWindows Batchのパス解釈: Windowsのバッチファイルでは、パスにスペースが含まれる場合、そのパス全体を二重引用符で囲むのが一般的です(例: set PATH="C:\Program Files\Go")。しかし、cmd.exeのコマンドラインパーサーは、二重引用符の扱いに関して特定のルールを持っています。場合によっては、引用符がパスの一部として誤って解釈されたり、コマンドが期待する形式と異なる形で引数が渡されたりすることがあります。特に、setコマンドで環境変数を設定する際に、値自体に二重引用符を含めるかどうかは、その変数を後続のコマンドがどのように利用するかによって挙動が変わる可能性があります。

技術的詳細

このコミットの技術的な核心は、Windowsのバッチファイルにおける環境変数の設定と、cmd.exeのコマンドライン引数および環境変数解釈の挙動にあります。

従来のmake.batでは、GOROOTGOROOT_FINALを以下のように設定していました。

set GOROOT="%CD%"
if "x%GOROOT_FINAL%"=="x" set GOROOT_FINAL="%GOROOT%"

ここで、%CD%は現在のディレクトリのパスを返しますが、このパスが二重引用符で囲まれています。例えば、現在のディレクトリがC:\Goであれば、GOROOT"C:\Go"という文字列として設定されます。

問題は、このGOROOT変数が後続のビルドプロセスでどのように利用されるかにありました。Goのツールチェインや他のコマンドがこのGOROOTの値を読み取る際、もしそれらのツールがパスの先頭と末尾にある二重引用符を自動的に取り除かない場合、パスが"C:\Go"のように引用符を含んだまま解釈されてしまいます。これにより、ファイルが見つからない、パスが不正であるといったエラーが発生する可能性がありました。

例えば、GoのコンパイラがGOROOTを基に標準ライブラリのパスを構築する際に、"C:\Go"\src\pkgのような不正なパスを生成してしまうことが考えられます。

このコミットでは、二重引用符を削除することで、GOROOTGOROOT_FINALが純粋なパス文字列として設定されるように変更しました。

set GOROOT=%CD%
if "x%GOROOT_FINAL%"=="x" set GOROOT_FINAL=%GOROOT%

これにより、GOROOTC:\Goのような形式で設定され、後続のツールがパスを正しく解釈できるようになります。Windowsのバッチファイルでは、setコマンドで設定された環境変数の値は、通常、スペースが含まれていても二重引用符なしで正しく扱われます。二重引用符が必要になるのは、コマンドラインで引数として渡す場合や、パスにスペースが含まれる場合に、その引数全体を一つの単位として扱う必要があるときです。

この変更は、make.batが内部的に設定する環境変数に対しては、二重引用符が不要であり、むしろ問題を引き起こす可能性があるという理解に基づいています。これにより、Windows環境でのGoのビルドの安定性と互換性が向上しました。

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

--- a/src/make.bat
+++ b/src/make.bat
@@ -16,9 +16,9 @@ goto fail
 :: backslashes.  Then we wrap that in quotes to create
 :: a C string.
 cd ..
-set GOROOT="%CD%"
+set GOROOT=%CD%
 cd src
-if "x%GOROOT_FINAL%Н=="x" set GOROOT_FINAL="%GOROOT%"
+if "x%GOROOT_FINAL%Н=="x" set GOROOT_FINAL=%GOROOT%
 set DEFGOROOT=-DGOROOT_FINAL="\"%GOROOT_FINAL:\\=\\\\%\""
 
 echo # Building C bootstrap tool.

コアとなるコードの解説

変更された行は以下の2行です。

  1. - set GOROOT="%CD%" から + set GOROOT=%CD%

    • 変更前は、現在のディレクトリパスを示す%CD%を二重引用符で囲んでGOROOT環境変数に設定していました。これにより、GOROOTの値自体が"C:\path\to\go"のような文字列になっていました。
    • 変更後は、二重引用符を削除し、%CD%が返す純粋なパス文字列(例: C:\path\to\go)をGOROOTに設定するようにしました。これにより、GOROOTが後続のコマンドやツールによって正しくパスとして解釈されるようになります。
  2. - if "x%GOROOT_FINAL%Н=="x" set GOROOT_FINAL="%GOROOT%" から + if "x%GOROOT_FINAL%Н=="x" set GOROOT_FINAL=%GOROOT%

    • この行は、GOROOT_FINALがまだ設定されていない場合に、GOROOTの値をGOROOT_FINALにコピーする処理です。
    • 変更前は、ここでも%GOROOT%の値を二重引用符で囲んでGOROOT_FINALに設定していました。GOROOT自体が既に引用符を含んでいる場合、これは二重に引用符が付与されるか、あるいは引用符がパスの一部として誤って解釈される原因となっていました。
    • 変更後は、%GOROOT%の値をそのままGOROOT_FINALに設定するようにしました。これにより、GOROOTが純粋なパス文字列として設定されていれば、GOROOT_FINALも同様に純粋なパス文字列として設定されます。

これらの変更により、GOROOTGOROOT_FINALという重要な環境変数が、Windowsのバッチスクリプト内で正しく、かつ他のGoツールチェインが期待する形式でパスを保持するようになります。これは、Windows環境でのGoのビルドの信頼性を高める上で重要な修正です。

関連リンク

参考にした情報源リンク