[インデックス 12010] ファイルの概要
このコミットは、Go言語のWindows向けディストリビューションビルドプロセスにおける重要な更新を含んでいます。具体的には、Goのソースツリー内のmisc/windows
ディレクトリにあった配布関連ファイルがmisc/dist/windows
に移動され、既存のBashスクリプトであるpackage.bash
がWindowsバッチファイルであるdist.bat
に置き換えられました。これにより、Windows環境でのGoのパッケージングとインストーラー作成プロセスが、よりWindowsネイティブなツールとスクリプトに移行されました。
コミット
commit 4f5ffe568466cdd571a6fbae1c8af56474f3db99
Author: Joe Poirier <jdpoirier@gmail.com>
Date: Fri Feb 17 11:07:34 2012 -0600
misc/dist/windows: distro builder updates
files moved from misc/windows, bash packager file replaced with Windows batch file
R=golang-dev, alex.brainman, rsc
CC=golang-dev
https://golang.org/cl/5677074
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/4f5ffe568466cdd571a6fbae1c8af56474f3db99
元コミット内容
misc/dist/windows: distro builder updates
files moved from misc/windows, bash packager file replaced with Windows batch file
R=golang-dev, alex.brainman, rsc
CC=golang-dev
https://golang.org/cl/5677074
変更の背景
この変更の背景には、Go言語のWindows向け配布物のビルドおよびパッケージングプロセスを改善し、よりWindows環境に適合させるという目的があります。以前はmisc/windows/package.bash
というBashスクリプトが使用されており、これはUnix系システムでの利用を前提としたものでした。しかし、Windows環境でGoの公式ディストリビューションをビルドする際には、Bash環境(例えばCygwinやMinGW)の導入が必要となり、ビルドプロセスの複雑さや依存関係が増大していました。
このコミットでは、package.bash
をWindowsネイティブなバッチファイルであるdist.bat
に置き換えることで、Windows上でのビルドプロセスを簡素化し、外部のBash環境への依存を排除しています。また、関連するファイル群をmisc/windows
からmisc/dist/windows
へ移動することで、配布物(distribution)関連のファイルをより明確に整理し、プロジェクト構造の改善も図っています。これにより、WindowsユーザーがGoをより簡単に利用できるよう、配布物の品質とビルドの効率性を向上させる狙いがありました。
前提知識の解説
このコミットの変更内容を理解するためには、以下の技術要素に関する前提知識が必要です。
-
Windows Batch File (.bat): Windowsオペレーティングシステムでコマンドを実行するためのスクリプトファイルです。
.bat
拡張子を持ち、コマンドプロンプト(cmd.exe)によって解釈・実行されます。Unix系のシェルスクリプト(Bashなど)とは異なる構文を持ち、Windows環境での自動化タスクによく用いられます。このコミットでは、GoのWindows向け配布物作成プロセスを自動化するために利用されています。 -
WiX Toolset (Windows Installer XML Toolset): Microsoft Windows Installer (MSI) パッケージを作成するためのオープンソースのツールセットです。XML形式のソースコードからMSIインストーラーをビルドすることができます。WiX Toolsetは主に以下の主要なツールで構成されます。
candle.exe
: WiXソースファイル(.wxs)をコンパイルしてオブジェクトファイル(.wixobj)を生成します。light.exe
: コンパイルされたオブジェクトファイルとライブラリをリンクして、最終的なMSIインストーラーパッケージを生成します。heat.exe
: 既存のファイルやディレクトリ構造をスキャンし、それらをWiXソースファイル(.wxs)のフラグメントとして自動的に生成します。これにより、手動で大量のファイルエントリを記述する手間を省くことができます。 このコミットでは、GoのWindowsインストーラー(MSI)を作成するためにWiX Toolsetが活用されています。
-
7-Zip (
7za.exe
): オープンソースのファイルアーカイバであり、高圧縮率を特徴とする7z形式をサポートしています。また、ZIP、GZIP、BZIP2、TARなど、他の多くのアーカイブ形式にも対応しています。このコミットでは、Goの配布物をZIP形式で圧縮するために7za.exe
が使用されています。 -
Mercurial (
hg.exe
): 分散型バージョン管理システム(DVCS)の一つです。Gitと同様に、コードの変更履歴を管理し、複数の開発者間での共同作業を可能にします。GoプロジェクトはかつてMercurialを主要なバージョン管理システムとして使用していました(現在はGitに移行しています)。このコミットが作成された2012年時点では、Goのソースコードのクローンやバージョン情報の取得にhg.exe
が利用されていました。 -
Go言語のビルドと配布: Go言語は、クロスコンパイルを強力にサポートしており、異なるOSやアーキテクチャ向けのバイナリを簡単に生成できます。公式のGo配布物には、コンパイラ、標準ライブラリ、ツールなどが含まれており、これらは通常、ZIPアーカイブやOS固有のインストーラー(WindowsではMSI)として提供されます。このコミットは、そのWindows向け配布物の作成パイプラインの一部を構成しています。
技術的詳細
このコミットの主要な変更は、Go言語のWindows向け配布物を作成するためのスクリプトが、Bashスクリプトのpackage.bash
からWindowsバッチファイルのdist.bat
に移行したことです。この移行により、ビルドプロセスがWindowsネイティブな環境で完結するようになりました。
新しいdist.bat
スクリプトの技術的な詳細を以下に示します。
-
環境設定と変数定義:
@echo off
: コマンドの実行結果を非表示にします。setlocal
: 環境変数の変更をこのスクリプトの実行範囲に限定します。for /f %%i in ('hg.exe root') do set ROOT=%%i
: Mercurialコマンドhg.exe root
を実行し、Goリポジトリのルートパスを取得してROOT
変数に設定します。for /f %%i in ('hg.exe id -n') do set ID=%%i
: Mercurialコマンドhg.exe id -n
を実行し、現在のリビジョンID(コミットハッシュ)を取得してID
変数に設定します。for /f "tokens=3" %%i in ('%ROOT%\bin\go.exe version') do set VER=%%i
: Goコンパイラgo.exe version
を実行し、その出力からGoのバージョン情報(例:go1.0.1
の1.0.1
部分)を抽出してVER
変数に設定します。
-
GOARCHの取得:
%ROOT%\bin\go tool dist env > env.txt
:go tool dist env
コマンドを実行し、Goのビルド環境変数(GOARCHなど)をenv.txt
ファイルに出力します。set GOARCH /p = find "GOARCH" "env.txt">NUL
:env.txt
からGOARCH
の値を抽出し、GOARCH
変数に設定します。/p
オプションは通常プロンプトを表示しますが、ここではfind
コマンドの出力から直接設定しているため、ユーザー入力は不要です。del /F /Q /S env.txt>NUL
: 一時ファイルenv.txt
を削除します。
-
Goツリーのクローンとクリーンアップ:
rmdir /S /Q go>NUL
: 既存のgo
ディレクトリがあれば削除します。mkdir go
: 新しいgo
ディレクトリを作成します。hg clone -r %ID% %ROOT% go
: 現在のリビジョンID(%ID%
)で、Goリポジトリのルート(%ROOT%
)からgo
ディレクトリにGoのソースツリーをクローンします。rmdir /S /Q go\.hg>NUL
: クローンしたGoツリー内のMercurialリポジトリ情報(.hg
ディレクトリ)を削除します。del /F /Q /S go\.hgignore go\.hgtags>NUL
:.hgignore
や.hgtags
といったMercurial関連ファイルを削除します。これは、配布物にはバージョン管理システムの情報は不要なためです。
-
必要なファイルのコピー:
xcopy %ROOT%\pkg go\pkg /V /E /Y /I
: コンパイル済みのパッケージファイル(.a
ファイルなど)を含むpkg
ディレクトリをコピーします。xcopy %ROOT%\bin go\bin /V /E /Y /I
: Goの実行可能ファイル(go.exe
など)を含むbin
ディレクトリをコピーします。xcopy %ROOT%\src\pkg\runtime\z*.c go\src\pkg\runtime /V /E /Y
: ランタイム関連のCソースファイル(z*.c
)をコピーします。xcopy %ROOT%\src\pkg\runtime\z*.go go\src\pkg\runtime /V /E /Y
: ランタイム関連のGoソースファイル(z*.go
)をコピーします。xcopy %ROOT%\src\pkg\runtime\z*.h go\src\pkg\runtime /V /E /T
: ランタイム関連のヘッダーファイル(z*.h
)をコピーします。 これらのz*
ファイルは、Goのランタイムが特定のアーキテクチャやOS向けに生成するアセンブリコードやデータを含むファイルで、クロスコンパイル時に必要となる場合があります。
-
ZIPパッケージの作成:
7za a -tzip -mx=9 gowin%GOARCH%_%VER%.zip "go/"
:7za.exe
を使用して、go
ディレクトリの内容をZIPアーカイブに圧縮します。ファイル名はgowin<GOARCH>_<VERSION>.zip
の形式になります(例:gowin386_1.0.1.zip
)。-mx=9
は最高の圧縮率を指定します。
-
WiXによるインストーラーパッケージの作成:
heat dir go -nologo -cg AppFiles -gg -g1 -srd -sfrag -template fragment -dr INSTALLDIR -var var.SourceDir -out AppFiles.wxs
:heat.exe
を使用して、go
ディレクトリ内のファイル構造をスキャンし、それらを記述するWiXソースファイルAppFiles.wxs
を生成します。-nologo
: 著作権表示を非表示にします。-cg AppFiles
: コンポーネントグループの名前をAppFiles
に設定します。-gg
: GUIDを生成します。-g1
: コンポーネントのGUIDを生成します。-srd
: 空のディレクトリをスキップします。-sfrag
: フラグメントとして出力します。-template fragment
: 出力テンプレートをフラグメントに設定します。-dr INSTALLDIR
: ディレクトリリファレンスをINSTALLDIR
に設定します。-var var.SourceDir
: ソースディレクトリ変数をvar.SourceDir
に設定します。-out AppFiles.wxs
: 出力ファイル名をAppFiles.wxs
に設定します。
candle -nologo -dVersion=%VER% -dArch=%GOARCH% -dSourceDir=go installer.wxs AppFiles.wxs
:candle.exe
を使用して、installer.wxs
とAppFiles.wxs
をコンパイルし、オブジェクトファイル(.wixobj
)を生成します。-dVersion=%VER%
:Version
という名前のマクロにGoのバージョンを設定します。-dArch=%GOARCH%
:Arch
という名前のマクロにGOARCH
の値を設定します。-dSourceDir=go
:SourceDir
という名前のマクロにソースディレクトリgo
を設定します。
light -nologo -ext WixUIExtension -ext WixUtilExtension installer.wixobj AppFiles.wixobj -o gowin%GOARCH%_%VER%.msi
:light.exe
を使用して、コンパイルされたオブジェクトファイルをリンクし、最終的なMSIインストーラーパッケージを生成します。-ext WixUIExtension
: WiXUI拡張機能をロードします(インストーラーのUI関連)。-ext WixUtilExtension
: WiXユーティリティ拡張機能をロードします。-o gowin%GOARCH%_%VER%.msi
: 出力ファイル名をgowin<GOARCH>_<VERSION>.msi
の形式に設定します。
-
クリーンアップ:
del /F /Q /S *.wixobj AppFiles.wxs *.wixpdb>NUL
: 生成された一時ファイル(.wixobj
、AppFiles.wxs
、.wixpdb
)を削除します。
このdist.bat
スクリプトは、GoのソースコードからWindows向けのZIPアーカイブとMSIインストーラーを自動的に生成する、包括的なビルドパイプラインを構築しています。
コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更箇所は以下のファイルです。
- ファイル移動とリネーム:
misc/windows/README
→misc/dist/windows/README
misc/windows/godocserver.bat
→misc/dist/windows/godocserver.bat
misc/windows/goenv.bat
→misc/dist/windows/goenv.bat
misc/windows/installer.wxs
→misc/dist/windows/installer.wxs
- 新規追加ファイル:
misc/dist/windows/dist.bat
(Windowsバッチファイル)
- 削除ファイル:
misc/windows/LICENSE
(バイナリファイルとして削除と表示されていますが、実質的には移動または処理方法の変更を示唆しています)misc/windows/package.bash
(Bashスクリプト)
最も重要な変更は、misc/windows/package.bash
が削除され、代わりにmisc/dist/windows/dist.bat
が追加された点です。これにより、GoのWindows向け配布物のビルドロジックがBashからWindowsバッチスクリプトに完全に移行しました。
コアとなるコードの解説
このコミットのコアとなるコードは、新しく追加されたmisc/dist/windows/dist.bat
ファイルです。このバッチファイルは、Go言語のWindows向け配布物(ZIPアーカイブとMSIインストーラー)を自動的に生成する一連のステップを定義しています。
以下に、dist.bat
スクリプトの主要なセクションとその役割を解説します。
+:: Copyright 2012 The Go Authors. All rights reserved.
+:: Use of this source code is governed by a BSD-style
+:: license that can be found in the LICENSE file.
+@echo off
+
+setlocal
+
+:: Requires WiX (candle light heat), 7zip, and hg
+
+echo # Setting variable info
+for /f %%i in ('hg.exe root') do set ROOT=%%i
+for /f %%i in ('hg.exe id -n') do set ID=%%i
+for /f "tokens=3" %%i in ('%ROOT%\bin\go.exe version') do set VER=%%i
+if errorlevel 1 goto end
+
+echo # Getting GOARCH
+%ROOT%\bin\go tool dist env > env.txt
+set GOARCH /p = find "GOARCH" "env.txt">NUL
+del /F /Q /S env.txt>NUL
+if errorlevel 1 goto end
+
+rmdir /S /Q go>NUL
+mkdir go
+
+echo # Cloning the go tree
+hg clone -r %ID% %ROOT% go
+if errorlevel 1 goto end
+
+rmdir /S /Q go\.hg>NUL
+del /F /Q /S go\.hgignore go\.hgtags>NUL
+
+echo # Copying pkg, bin and src/pkg/runtime/z*
+xcopy %ROOT%\pkg go\pkg /V /E /Y /I
+xcopy %ROOT%\bin go\bin /V /E /Y /I
+xcopy %ROOT%\src\pkg\runtime\\z*.c go\src\pkg\runtime /V /E /Y
+xcopy %ROOT%\src\pkg\runtime\\z*.go go\src\pkg\runtime /V /E /Y
+xcopy %ROOT%\src\pkg\runtime\\z*.h go\src\pkg\runtime /V /E /T
+
+echo # Starting zip packaging
+7za a -tzip -mx=9 gowin%GOARCH%\"_\"%VER%.zip "go/"
+if errorlevel 1 goto end
+
+echo # Starting Go directory file harvesting
+heat dir go -nologo -cg AppFiles -gg -g1 -srd -sfrag -template fragment -dr INSTALLDIR -var var.SourceDir -out AppFiles.wxs
+if errorlevel 1 goto end
+
+echo # Starting installer packaging
+candle -nologo -dVersion=%VER% -dArch=%GOARCH% -dSourceDir=go installer.wxs AppFiles.wxs
+light -nologo -ext WixUIExtension -ext WixUtilExtension installer.wixobj AppFiles.wixobj -o gowin%GOARCH%\"_\"%VER%.msi
+if errorlevel 1 goto end
+
+del /F /Q /S *.wixobj AppFiles.wxs *.wixpdb>NUL
+
+:end
-
初期設定と依存関係の明示:
- スクリプトの冒頭で著作権情報とライセンスが示されています。
@echo off
は、コマンドプロンプトでのコマンドのエコー表示を無効にします。setlocal
は、スクリプト内で設定される環境変数が、スクリプトの終了時に自動的に元に戻るようにします。- コメント行
:: Requires WiX (candle light heat), 7zip, and hg
は、このスクリプトを実行するために必要な外部ツール(WiX Toolset、7-Zip、Mercurial)を明示しています。
-
変数情報の取得:
hg.exe root
、hg.exe id -n
、go.exe version
コマンドを実行し、それぞれGoリポジトリのルートパス、現在のリビジョンID、Goのバージョン情報を取得して、ROOT
、ID
、VER
という環境変数に設定しています。これにより、ビルドプロセスが動的にこれらの情報を使用できるようになります。if errorlevel 1 goto end
は、直前のコマンドがエラーを返した場合(errorlevel
が1以上の場合)にスクリプトを終了させるエラーハンドリングです。
-
GOARCHの取得:
go tool dist env
コマンドの出力を一時ファイルenv.txt
にリダイレクトし、そのファイルからGOARCH
(Goのターゲットアーキテクチャ、例:amd64
,386
)の値を抽出しています。これは、生成されるパッケージ名やインストーラー名にアーキテクチャ情報を含めるために必要です。
-
Goソースツリーの準備:
rmdir /S /Q go
とmkdir go
で、作業用のgo
ディレクトリをクリーンアップし、新しく作成します。hg clone -r %ID% %ROOT% go
で、指定されたリビジョンIDでGoのソースツリーをクローンします。これは、配布物を作成するために特定のバージョンのソースコードが必要だからです。- クローン後、
go\.hg
ディレクトリや.hgignore
、.hgtags
といったMercurial関連のメタデータを削除しています。これは、最終的な配布物にはバージョン管理システムの情報は不要であり、配布物のサイズを削減するためです。
-
必要なファイルのコピー:
xcopy
コマンドを使用して、Goのビルド済みパッケージ(pkg
)、実行可能ファイル(bin
)、およびランタイム関連のソースファイル(src\pkg\runtime\z*
)を、クローンしたgo
ディレクトリ内にコピーしています。これらのファイルは、Goの実行環境を構成するために不可欠です。
-
ZIPパッケージの作成:
7za a -tzip -mx=9 gowin%GOARCH%\"_\"%VER%.zip "go/"
コマンドで、準備されたgo
ディレクトリの内容をZIP形式で圧縮します。ファイル名には、Windows (gowin
)、ターゲットアーキテクチャ (%GOARCH%
)、およびGoのバージョン (%VER%
) が含まれます。-mx=9
は最高の圧縮率を指定し、配布物のダウンロードサイズを最小限に抑えます。
-
WiXによるインストーラーの作成:
heat.exe
によるファイル情報の収集:heat dir go ... -out AppFiles.wxs
コマンドは、go
ディレクトリ内のすべてのファイルとディレクトリ構造をスキャンし、それらをWindows Installerのコンポーネントとして記述するXMLファイルAppFiles.wxs
を自動生成します。これにより、手動でインストーラーに含めるファイルを一つ一つ記述する手間が省けます。candle.exe
によるコンパイル:candle -nologo -dVersion=%VER% -dArch=%GOARCH% -dSourceDir=go installer.wxs AppFiles.wxs
コマンドは、installer.wxs
(インストーラーの基本構造やUIを定義するファイル)とAppFiles.wxs
(heat
で生成されたファイル情報)をコンパイルし、中間オブジェクトファイル(.wixobj
)を生成します。-d
オプションは、バージョンやアーキテクチャなどの情報をXMLソースに渡すために使用されます。light.exe
によるリンクとMSI生成:light -nologo -ext WixUIExtension -ext WixUtilExtension installer.wixobj AppFiles.wixobj -o gowin%GOARCH%\"_\"%VER%.msi
コマンドは、コンパイルされたオブジェクトファイルをリンクし、最終的なMSIインストーラーパッケージを生成します。-ext
オプションは、インストーラーのUIやユーティリティ機能を提供するWiXの拡張機能をロードするために使用されます。
-
クリーンアップ:
del /F /Q /S *.wixobj AppFiles.wxs *.wixpdb
コマンドで、ビルドプロセス中に生成された一時ファイルや中間ファイルを削除し、作業ディレクトリをクリーンな状態に保ちます。
このdist.bat
スクリプトは、GoのWindows向け配布物作成における、ソースコードの取得から最終的なインストーラーの生成までの一連の複雑なタスクを自動化する、堅牢なパイプラインを構築しています。
関連リンク
- Go言語公式サイト: https://go.dev/
- WiX Toolset公式サイト: https://wixtoolset.org/
- 7-Zip公式サイト: https://www.7-zip.org/
- Mercurial公式サイト: https://www.mercurial-scm.org/
参考にした情報源リンク
- WiX Toolset Documentation: https://wixtoolset.org/documentation/
- 7-Zip Command Line Version: https://www.7-zip.org/7z.html
- Mercurial Command Reference: https://www.mercurial-scm.org/doc/hgrbook.html
- Microsoft Batch File Commands: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands
- Go Wiki - Go on Windows: (当時の情報源は特定が難しいですが、GoのWindowsサポートに関する公式ドキュメントやコミュニティの議論が参考になった可能性があります。)
- Go Source Code (GitHub): https://github.com/golang/go
- Go Code Review (Gerrit): https://go-review.googlesource.com/ (コミットメッセージに記載されている
https://golang.org/cl/5677074
は、当時のGerritのコードレビューリンクです。)