[インデックス 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/READMEmisc/windows/godocserver.bat→misc/dist/windows/godocserver.batmisc/windows/goenv.bat→misc/dist/windows/goenv.batmisc/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のコードレビューリンクです。)