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

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

このコミットは、Go言語のツールチェインをビルドするためのcmd/distツールのWindowsビルドに関する修正です。具体的には、src/make.batファイル内のgccコンパイルコマンドにおいて、cmd/dist/buildgo.ccmd/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.cbuildruntime.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.bashmake.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.ccmd/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.ccmd/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.cbuildruntime.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.ccmd/dist/buildruntime.cが追加されています。これにより、dist.exeのコンパイルに必要なすべてのCソースファイルがgccに渡されるようになり、dist.exeが完全な機能を持つ状態でビルドされることが保証されます。

この修正は、Windows環境でのGoツールチェインのビルドが正しく行われるために不可欠なものでした。

関連リンク

参考にした情報源リンク

  • Go言語のソースコード(src/make.batcmd/distディレクトリの内容)
  • Go言語のビルドプロセスに関する一般的な知識
  • gccコンパイラの基本的な使用方法
  • Windowsバッチスクリプトの構文
  • Gitの差分表示の解釈