[インデックス 11842] ファイルの概要
このコミットは、Go言語プロジェクトのmisc/dist
ディレクトリに、Linux向けのGoバイナリディストリビューションパッケージングスクリプトdist.bash
を新規追加するものです。このスクリプトは、GoのソースコードをMercurialリポジトリからクローンし、指定されたタグのバージョンをビルドし、最終的にtar.gz形式のバイナリパッケージとして出力する一連の自動化されたプロセスを提供します。
コミット
commit 159ee8a42f2ad9216267a1da0217427346d1d331
Author: Andrew Gerrand <adg@golang.org>
Date: Mon Feb 13 21:18:16 2012 +1100
misc/dist: add binary distribution packaging script for linux
R=golang-dev, bradfitz, iant
CC=golang-dev
https://golang.org/cl/5639064
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/159ee8a42f2ad9216267a1da0217427346d1d331
元コミット内容
diff --git a/misc/dist/linux/dist.bash b/misc/dist/linux/dist.bash
new file mode 100755
index 0000000000..9270782ad9
--- /dev/null
+++ b/misc/dist/linux/dist.bash
@@ -0,0 +1,55 @@
+#!/usr/bin/env bash
+# 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.
+
+set -e
+
+TAG=$1
+if [ "$TAG" == "" ]; then
+ echo >&2 'usage: dist.bash <tag>'
+ exit 2
+fi
+
+GOOS=${GOOS:-linux}
+GOARCH=${GOARCH:-amd64}
+
+ROOT=/tmp/godist.linux.$GOARCH
+rm -rf $ROOT
+mkdir -p $ROOT
+pushd $ROOT>/dev/null
+
+# clone Go distribution
+echo "Preparing new GOROOT"
+hg clone -q https://code.google.com/p/go go
+pushd go > /dev/null
+hg update $TAG
+
+# get version
+pushd src > /dev/null
+echo "Building dist tool to get VERSION"
+./make.bash --dist-tool 2>&1 | sed 's/^/ /' >&2
+../bin/tool/dist version > ../VERSION
+popd > /dev/null
+VERSION="$(cat VERSION | awk '{ print $1 }')"
+echo " Version: $VERSION"
+
+# remove mercurial stuff
+rm -rf .hg*
+
+# build Go
+echo "Building Go"
+unset GOROOT
+export GOOS
+export GOARCH
+export GOROOT_FINAL=/usr/local/go
+pushd src > /dev/null
+./all.bash 2>&1 | sed 's/^/ /' >&2
+popd > /dev/null
+popd > /dev/null
+
+# tar it up
+DEST=go.$VERSION.$GOOS-$GOARCH.tar.gz
+echo "Writing tarball: $ROOT/$DEST"
+tar czf $DEST go
+popd > /dev/null
変更の背景
このコミットが行われた2012年当時、Go言語はまだ比較的新しい言語であり、その配布方法は進化の途上にありました。Goのユーザーが特定のバージョン(タグ)のGoバイナリを簡単に取得し、システムにインストールできるようにするためには、自動化されたパッケージングプロセスが必要でした。特にLinux環境では、ソースからビルドする手間を省き、すぐに利用できるバイナリ形式で提供することが、ユーザーエクスペリエンスの向上に直結します。
このスクリプトの追加は、Goプロジェクトが公式なバイナリディストリビューションの提供を強化し、ユーザーがより手軽にGoを利用できる環境を整備するための一環として行われました。これにより、開発者は特定のGoバージョンを簡単にダウンロードし、tar.gz
ファイルを展開するだけでGo開発環境をセットアップできるようになります。
前提知識の解説
このコミットの理解には、以下の技術的知識が役立ちます。
- Bashスクリプト:
dist.bash
はBashシェルスクリプトで書かれています。set -e
(コマンドが失敗した場合にスクリプトを終了する)、echo
(標準出力)、>&2
(標準エラー出力へのリダイレクト)、pushd
/popd
(ディレクトリスタック操作)、rm -rf
(強制削除)、mkdir -p
(ディレクトリ作成)、export
(環境変数設定)、パイプライン(|
)、sed
(ストリームエディタ)、awk
(テキスト処理)などの基本的なコマンドと概念が使われています。 - Mercurial (Hg): 2012年当時、Go言語の公式リポジトリはGitではなくMercurial(Hg)で管理されていました。
hg clone
はリポジトリをクローンするコマンド、hg update
は指定されたタグやリビジョンに作業ディレクトリを更新するコマンドです。このスクリプトはGoのソースコードをMercurialリポジトリから取得しています。 - Go言語のビルドシステム:
GOROOT
: Goのインストールディレクトリを指す環境変数です。GoのツールチェインがGoのソースコードや標準ライブラリを見つけるために使用します。GOOS
/GOARCH
: ビルドターゲットのオペレーティングシステム(例:linux
)とアーキテクチャ(例:amd64
)を指定する環境変数です。GOROOT_FINAL
: Goのバイナリが最終的にインストールされるパスを指定する環境変数です。このスクリプトでは/usr/local/go
に設定されており、これは一般的なGoのインストールパスです。./make.bash
/./all.bash
: Goのソースツリーに含まれるビルドスクリプトです。make.bash
はGoのビルドツールを構築するために使用され、all.bash
はGoのコンパイラ、ツール、標準ライブラリなど、Go全体をビルドするために使用されます。
tar
コマンド: ファイルやディレクトリをアーカイブ(まとめる)および圧縮(サイズを小さくする)するためのUNIX系コマンドです。tar czf <output_file> <input_directory>
は、指定されたディレクトリをgzip
で圧縮されたtarアーカイブとして出力します。
技術的詳細
dist.bash
スクリプトは、GoのLinuxバイナリディストリビューションを作成するための一連のステップを自動化します。
-
引数の検証:
- スクリプトは引数としてGoのバージョンタグ(例:
go1.0
)を一つ受け取ります。 - 引数が提供されない場合、使用法メッセージを表示して終了します。
- スクリプトは引数としてGoのバージョンタグ(例:
-
環境変数の設定:
GOOS
とGOARCH
は、それぞれデフォルトでlinux
とamd64
に設定されますが、環境変数として既に設定されていればその値が優先されます。これにより、異なるOS/アーキテクチャのバイナリをビルドする柔軟性が提供されます。
-
一時作業ディレクトリの準備:
/tmp/godist.linux.$GOARCH
という形式の一時ディレクトリ(例:/tmp/godist.linux.amd64
)を作成します。- 既存のディレクトリがあれば削除し、新しく作成します。
- このディレクトリに移動し、以降の操作のベースとします。
-
Goソースコードのクローンと更新:
hg clone -q https://code.google.com/p/go go
コマンドを使用して、Goの公式Mercurialリポジトリをgo
という名前のディレクトリにクローンします。-q
オプションは静かに(quietly)クローンすることを意味します。- クローンした
go
ディレクトリに移動します。 hg update $TAG
コマンドで、スクリプトに渡されたタグ(例:go1.0
)に対応するバージョンにソースコードを更新します。
-
Goバージョンの取得:
go/src
ディレクトリに移動します。./make.bash --dist-tool
を実行して、Goのビルドツール(dist
ツールなど)をビルドします。この出力は標準エラーにリダイレクトされ、sed
で整形されます。../bin/tool/dist version
を実行し、ビルドされたdist
ツールを使ってGoのバージョン情報を取得し、../VERSION
ファイルに保存します。VERSION
ファイルからawk
を使ってバージョン文字列を抽出し、VERSION
シェル変数に格納します。
-
Mercurial関連ファイルの削除:
- ビルドされたGoのディレクトリから、
.hg*
(Mercurialのリポジトリ情報)ファイルを削除します。これにより、配布されるtarballには不要なリポジトリメタデータが含まれなくなります。
- ビルドされたGoのディレクトリから、
-
Goのビルド:
GOROOT
環境変数をunset
(設定解除)します。これは、ビルドプロセスが現在の環境のGOROOT
に依存しないようにするためです。GOOS
、GOARCH
、そしてGOROOT_FINAL=/usr/local/go
をエクスポートします。GOROOT_FINAL
は、ビルドされたGoバイナリが最終的にインストールされるパスをGoのビルドシステムに伝えます。go/src
ディレクトリに移動し、./all.bash
を実行してGo全体をビルドします。このコマンドはGoのコンパイラ、標準ライブラリ、およびその他のツールをコンパイルします。出力は標準エラーにリダイレクトされ、sed
で整形されます。
-
tarballの作成:
- ビルドが完了した後、一時作業ディレクトリのルートに戻ります。
DEST=go.$VERSION.$GOOS-$GOARCH.tar.gz
という形式で出力ファイル名を定義します(例:go.1.0.linux-amd64.tar.gz
)。tar czf $DEST go
コマンドを使用して、ビルドされたgo
ディレクトリ全体をgzip
圧縮されたtarアーカイブとしてパッケージングします。
このスクリプトは、Goのバイナリ配布に必要なすべてのステップを自動化し、クリーンでポータブルなGoのインストールパッケージを生成します。
コアとなるコードの変更箇所
このコミットは、misc/dist/linux/dist.bash
という新しいファイルを追加しています。
#!/usr/bin/env bash
# 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.
set -e
TAG=$1
if [ "$TAG" == "" ]; then
echo >&2 'usage: dist.bash <tag>'
exit 2
fi
GOOS=${GOOS:-linux}
GOARCH=${GOARCH:-amd64}
ROOT=/tmp/godist.linux.$GOARCH
rm -rf $ROOT
mkdir -p $ROOT
pushd $ROOT>/dev/null
# clone Go distribution
echo "Preparing new GOROOT"
hg clone -q https://code.google.com/p/go go
pushd go > /dev/null
hg update $TAG
# get version
pushd src > /dev/null
echo "Building dist tool to get VERSION"
./make.bash --dist-tool 2>&1 | sed 's/^/ /' >&2
../bin/tool/dist version > ../VERSION
popd > /dev/null
VERSION="$(cat VERSION | awk '{ print $1 }')"
echo " Version: $VERSION"
# remove mercurial stuff
rm -rf .hg*
# build Go
echo "Building Go"
unset GOROOT
export GOOS
export GOARCH
export GOROOT_FINAL=/usr/local/go
pushd src > /dev/null
./all.bash 2>&1 | sed 's/^/ /' >&2
popd > /dev/null
popd > /dev/null
# tar it up
DEST=go.$VERSION.$GOOS-$GOARCH.tar.gz
echo "Writing tarball: $ROOT/$DEST"
tar czf $DEST go
popd > /dev/null
コアとなるコードの解説
#!/usr/bin/env bash
: シバン(shebang)。このスクリプトがBashシェルで実行されることを指定します。set -e
: スクリプト内で実行されるコマンドが一つでも失敗(ゼロ以外の終了ステータスを返す)した場合、スクリプト全体の実行を即座に終了させます。これにより、エラーが発生した際に不完全なパッケージが生成されるのを防ぎます。TAG=$1
: スクリプトに渡された最初の引数をTAG
変数に代入します。これがビルドするGoのバージョンタグになります。if [ "$TAG" == "" ]; then ... fi
:TAG
が空文字列(引数が渡されなかった場合)であれば、使用法メッセージを標準エラー出力に表示し、終了コード2でスクリプトを終了します。GOOS=${GOOS:-linux}
/GOARCH=${GOARCH:-amd64}
: 環境変数GOOS
とGOARCH
が設定されていればその値を使用し、設定されていなければそれぞれlinux
とamd64
をデフォルト値として使用します。ROOT=/tmp/godist.linux.$GOARCH
: 一時作業ディレクトリのパスを定義します。/tmp
以下にアーキテクチャ名を含むユニークなディレクトリを作成します。rm -rf $ROOT
/mkdir -p $ROOT
: 既存の一時ディレクトリを削除し、新しく作成します。-p
オプションは、親ディレクトリが存在しない場合でも作成します。pushd $ROOT>/dev/null
:$ROOT
ディレクトリに移動し、現在のディレクトリをスタックにプッシュします。>/dev/null
は、pushd
コマンドの出力を抑制します。hg clone -q https://code.google.com/p/go go
: GoのMercurialリポジトリをgo
という名前のサブディレクトリにクローンします。-q
は静かに実行するオプションです。hg update $TAG
: クローンしたGoリポジトリを、指定されたTAG
のバージョンに更新します。./make.bash --dist-tool 2>&1 | sed 's/^/ /' >&2
: Goのビルドツールをビルドします。2>&1
は標準エラーを標準出力にリダイレクトし、| sed 's/^/ /'
は各行の先頭にスペース2つを追加してインデントし、>&2
で再び標準エラーに戻しています。これは、ビルドの進行状況をユーザーに分かりやすく表示するための整形です。../bin/tool/dist version > ../VERSION
: ビルドされたdist
ツールを使ってGoのバージョン情報を取得し、親ディレクトリ(go
ディレクトリ)のVERSION
ファイルに保存します。VERSION="$(cat VERSION | awk '{ print $1 }')"
:VERSION
ファイルの内容を読み込み、awk
を使って最初の単語(バージョン番号)を抽出し、VERSION
シェル変数に代入します。rm -rf .hg*
: クローンしたGoリポジトリからMercurial関連の隠しファイルやディレクトリ(.hg
ディレクトリなど)を削除します。これにより、配布されるパッケージがクリーンになります。unset GOROOT
: Goのビルド前にGOROOT
環境変数を解除します。これは、ビルドプロセスが現在の環境のGOROOT
に依存せず、クリーンな状態でビルドを開始できるようにするためです。export GOOS
/export GOARCH
/export GOROOT_FINAL=/usr/local/go
: ビルドターゲットのOS、アーキテクチャ、および最終的なインストールパスを環境変数としてエクスポートします。GOROOT_FINAL
は、Goのビルドシステムがバイナリを生成する際に、そのバイナリが最終的にどこにインストールされるかを考慮するために重要です。./all.bash 2>&1 | sed 's/^/ /' >&2
: Goのコンパイラ、ツール、標準ライブラリなど、Go全体をビルドします。make.bash
と同様に、出力は整形されて標準エラーに表示されます。DEST=go.$VERSION.$GOOS-$GOARCH.tar.gz
: 生成されるtarballのファイル名を定義します。バージョン、OS、アーキテクチャが含まれることで、ファイル名から内容が分かりやすくなります。tar czf $DEST go
:go
ディレクトリ全体をgzip
圧縮されたtarアーカイブとして$DEST
に保存します。popd > /dev/null
:pushd
でプッシュしたディレクトリスタックから一つ戻ります。これにより、スクリプトは元の開始ディレクトリに戻ります。
関連リンク
- Go言語公式サイト: https://go.dev/
- Go言語のダウンロードページ: https://go.dev/dl/ (現在のGoの配布形式を確認できます)
参考にした情報源リンク
- Mercurial公式サイト: https://www.mercurial-scm.org/
- Bashスクリプトの基本的なコマンドと概念に関する一般的なドキュメント
- Go言語のビルドプロセスに関する一般的な情報 (Goの公式ドキュメントやブログ記事)
tar
コマンドのマニュアルページsed
コマンドのマニュアルページawk
コマンドのマニュアルページpushd
/popd
コマンドのマニュアルページset
コマンドのマニュアルページexport
コマンドのマニュアルページunset
コマンドのマニュアルページecho
コマンドのマニュアルページif
文に関するBashのドキュメント[
(test) コマンドのマニュアルページ>
/&>
/2>&1
など、リダイレクトに関するBashのドキュメント- パイプライン (
|
) に関するBashのドキュメント #!/usr/bin/env
に関する一般的な情報- Go言語の歴史とMercurialからGitへの移行に関する情報 (Goの公式ブログやメーリングリストのアーカイブ)