[インデックス 17007] ファイルの概要
このコミットは、Go言語のツールチェインをビルドするためのcmd/dist
ツールのWindowsビルドに関する修正です。具体的には、src/make.bat
ファイル内のgcc
コンパイルコマンドにおいて、cmd/dist/buildgo.c
とcmd/dist/buildruntime.c
という2つの重要なCソースファイルの指定が漏れていた問題を修正しています。これにより、Windows環境でのGoツールチェインのビルドが正常に完了するようになります。
コミット
cmd/dist: fix windows build.
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/12351045
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/0fe65c4f4979f0ad43bad30721821096e489de56
元コミット内容
commit 0fe65c4f4979f0ad43bad30721821096e489de56
Author: Rémy Oudompheng <oudomphe@phare.normalesup.org>
Date: Fri Aug 2 14:29:04 2013 -0700
cmd/dist: fix windows build.
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/12351045
変更の背景
Go言語のビルドシステムは、異なるプラットフォーム(Windows, Linux, macOSなど)に対応するために、それぞれの環境に合わせたビルドスクリプトを持っています。このコミットが行われた当時、Windows環境でGoのツールチェインをビルドする際に使用されるsrc/make.bat
スクリプトに問題がありました。
具体的には、Goのビルドプロセスにおいて、初期のコンパイラやツールを構築するために「ブートストラップ」と呼ばれる段階が存在します。このブートストラップ段階で利用される重要なツールの一つがcmd/dist
です。cmd/dist
は、GoのソースコードからGoのコンパイラ、リンカ、アセンブラ、ランタイムなどをビルドするために必要なC言語で書かれた補助ツール群をコンパイルして生成します。
Windowsのmake.bat
スクリプト内で、cmd/dist
ツールをコンパイルするためのgcc
コマンドが、必要なCソースファイルの一部(buildgo.c
とbuildruntime.c
)を含んでいませんでした。このため、dist.exe
が正しくビルドされず、結果としてGoツールチェイン全体のWindowsビルドが失敗していました。このコミットは、この不足しているソースファイルを追加することで、Windowsビルドの健全性を回復することを目的としています。
前提知識の解説
- Go言語のブートストラップ (Bootstrap): Go言語のコンパイラ自体はGo言語で書かれています。しかし、Goコンパイラを最初にビルドするためには、Goコンパイラが存在しない状態から始める必要があります。この問題を解決するために、Goの初期バージョンではC言語で書かれたミニマルなコンパイラ(
cmd/dist
の一部)が使用され、これを使って最初のGoコンパイラをビルドします。このプロセスをブートストラップと呼びます。 cmd/dist
: Goのソースツリーにあるディレクトリで、Goツールチェイン(コンパイラ、リンカ、アセンブラなど)をビルドするためのブートストラップツール群が含まれています。これらのツールは主にC言語で書かれており、Goのビルドプロセスの初期段階で利用されます。dist
ツールは、GoのソースコードからGoのバイナリを生成する際の様々なタスク(例えば、GoのソースファイルをCのコードに変換したり、Goのランタイムをビルドしたり)を管理します。src/make.bat
: Goのソースツリーのルートにある、Windows環境でGoをビルドするためのバッチスクリプトです。Unix系のシステムではmake.bash
やmake.rc
のようなシェルスクリプトが使われますが、Windowsでは.bat
ファイルが使われます。gcc
: GNU Compiler Collectionの略で、C、C++、Goなど様々なプログラミング言語に対応したコンパイラ群です。このコミットでは、cmd/dist
内のC言語ソースファイルをコンパイルするために使用されています。- Cソースファイル (
.c
ファイル):cmd/dist/buf.c
: バッファ操作に関するユーティリティ関数が含まれている可能性があります。cmd/dist/build.c
:dist
ツールの主要なビルドロジックが含まれている可能性があります。cmd/dist/buildgc.c
: Goのガベージコレクタ(GC)のビルドに関連するロジックが含まれている可能性があります。cmd/dist/buildgo.c
: Goコンパイラ自体のビルドに関連するロジックが含まれている可能性があります。cmd/dist/buildruntime.c
: Goランタイムのビルドに関連するロジックが含まれている可能性があります。cmd/dist/goc2c.c
: GoのCコード生成に関連するロジックが含まれている可能性があります。cmd/dist/main.c
:dist
ツールのエントリポイント(main
関数)が含まれています。cmd/dist/windows.c
: Windows固有のビルド処理やシステムコールに関連するロジックが含まれている可能性があります。cmd/dist/arm.c
: ARMアーキテクチャ固有のビルド処理に関連するロジックが含まれている可能性があります。
- グロブ展開 (Glob Expansion): Unix系のシェルでは、
*.c
のようにワイルドカードを使用すると、シェルが自動的にそのパターンに一致するファイル名に展開してコマンドに渡します。しかし、Windowsのコマンドプロンプト(cmd.exe
)では、このようなグロブ展開は行われません。そのため、make.bat
のようなスクリプトでは、コンパイル対象のファイルを一つ一つ明示的に列挙する必要があります。コミットの差分にあるコメント「:: Windows has no glob expansion, so spell out cmd/dist/*.c.
」はこの事実を説明しています。
技術的詳細
このコミットの技術的な核心は、src/make.bat
ファイル内のgcc
コマンドの引数リストの修正にあります。
Goのビルドプロセスでは、まずcmd/dist
ディレクトリにあるC言語のソースファイル群をgcc
でコンパイルし、dist.exe
という実行ファイルを生成します。このdist.exe
が、その後のGoコンパイラやランタイムなどのビルドをオーケストレーションする役割を担います。
修正前のsrc/make.bat
の該当行は以下のようになっていました。
gcc -O2 -Wall -Werror -o cmd/dist/dist.exe -Icmd/dist %DEFGOROOT% cmd/dist/buf.c cmd/dist/build.c cmd/dist/buildgc.c cmd/dist/goc2c.c cmd/dist/main.c cmd/dist/windows.c cmd/dist/arm.c
このコマンドでは、cmd/dist/buildgo.c
とcmd/dist/buildruntime.c
という2つの重要なソースファイルが欠落していました。
cmd/dist/buildgo.c
: Goコンパイラのビルドロジックに関連するCコードが含まれています。cmd/dist/buildruntime.c
: Goランタイムのビルドロジックに関連するCコードが含まれています。
これらのファイルがdist.exe
のコンパイル時に含まれていないと、dist.exe
はGoコンパイラやランタイムを正しくビルドするために必要な機能の一部を欠いた状態になります。結果として、Goツールチェインのビルドが途中で失敗するか、生成されたツールチェインが不完全なものになってしまいます。
このコミットでは、これらの欠落していたファイルをgcc
コマンドの引数リストに追加することで、dist.exe
が完全な形でビルドされるように修正しています。
修正後の行は以下の通りです。
gcc -O2 -Wall -Werror -o cmd/dist/dist.exe -Icmd/dist %DEFGOROOT% cmd/dist/buf.c cmd/dist/build.c cmd/dist/buildgc.c cmd/dist/buildgo.c cmd/dist/buildruntime.c cmd/dist/goc2c.c cmd/dist/main.c cmd/dist/windows.c cmd/dist/arm.c
この変更により、dist.exe
は必要なすべてのコンポーネントを正しくビルドできるようになり、Windows環境でのGoツールチェインのビルドが成功するようになりました。これは、Goのクロスプラットフォーム対応と、ブートストラッププロセスの堅牢性を維持するために不可欠な修正でした。
コアとなるコードの変更箇所
--- a/src/make.bat
+++ b/src/make.bat
@@ -60,7 +60,7 @@ echo # Building C bootstrap tool.
echo cmd/dist
if not exist ..\bin\tool mkdir ..\bin\tool
:: Windows has no glob expansion, so spell out cmd/dist/*.c.
-gcc -O2 -Wall -Werror -o cmd/dist/dist.exe -Icmd/dist %DEFGOROOT% cmd/dist/buf.c cmd/dist/build.c cmd/dist/buildgc.c cmd/dist/goc2c.c cmd/dist/main.c cmd/dist/windows.c cmd/dist/arm.c
+gcc -O2 -Wall -Werror -o cmd/dist/dist.exe -Icmd/dist %DEFGOROOT% cmd/dist/buf.c cmd/dist/build.c cmd/dist/buildgc.c cmd/dist/buildgo.c cmd/dist/buildruntime.c cmd/dist/goc2c.c cmd/dist/main.c cmd/dist/windows.c cmd/dist/arm.c
if errorlevel 1 goto fail
.\\cmd\\dist\\dist env -wp >env.bat
if errorlevel 1 goto fail
コアとなるコードの解説
この差分は、src/make.bat
ファイル内の単一の行の変更を示しています。
-
で始まる行は、変更前のコードです。+
で始まる行は、変更後のコードです。
変更点は、gcc
コマンドの引数リストにcmd/dist/buildgo.c
とcmd/dist/buildruntime.c
という2つのファイルが追加されたことです。
-
変更前 (
-
行):gcc -O2 -Wall -Werror -o cmd/dist/dist.exe -Icmd/dist %DEFGOROOT% cmd/dist/buf.c cmd/dist/build.c cmd/dist/buildgc.c cmd/dist/goc2c.c cmd/dist/main.c cmd/dist/windows.c cmd/dist/arm.c
この行では、cmd/dist/dist.exe
という実行ファイルをビルドするために、指定されたCソースファイル群をgcc
でコンパイルしています。しかし、buildgo.c
とbuildruntime.c
がこのリストから漏れていました。 -
変更後 (
+
行):gcc -O2 -Wall -Werror -o cmd/dist/dist.exe -Icmd/dist %DEFGOROOT% cmd/dist/buf.c cmd/dist/build.c cmd/dist/buildgc.c cmd/dist/buildgo.c cmd/dist/buildruntime.c cmd/dist/goc2c.c cmd/dist/main.c cmd/dist/windows.c cmd/dist/arm.c
この行では、cmd/dist/buildgc.c
の直後にcmd/dist/buildgo.c
とcmd/dist/buildruntime.c
が追加されています。これにより、dist.exe
のコンパイルに必要なすべてのCソースファイルがgcc
に渡されるようになり、dist.exe
が完全な機能を持つ状態でビルドされることが保証されます。
この修正は、Windows環境でのGoツールチェインのビルドが正しく行われるために不可欠なものでした。
関連リンク
- Go CL 12351045: https://golang.org/cl/12351045
参考にした情報源リンク
- Go言語のソースコード(
src/make.bat
、cmd/dist
ディレクトリの内容) - Go言語のビルドプロセスに関する一般的な知識
gcc
コンパイラの基本的な使用方法- Windowsバッチスクリプトの構文
- Gitの差分表示の解釈