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

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

このコミットは、Go言語のバイナリ配布パッケージングスクリプトの新しい階層構造を導入するものです。具体的には、misc/dist ディレクトリ以下に各OS(GOOS)ごとのパッケージングスクリプトを配置し、特にmacOS (darwin) 向けの配布プロセスを改善しています。

変更されたファイルは以下の通りです。

  • misc/dist/README: misc/dist ディレクトリの目的と、パッケージビルド方法($GOOS/dist.bash の実行)を説明する新しいREADMEファイル。
  • misc/dist/darwin/README: macOS (OS X) 向けのパッケージファイル (Go.pkg) の構築方法と、PackageMaker への依存関係を説明する新しいREADMEファイル。
  • misc/dist/darwin/dist.bash: macOS向けのGoバイナリ配布パッケージを構築するための新しいシェルスクリプト。PackageMaker を利用してGoのソースをビルドし、パッケージ化します。
  • misc/dist/darwin/etc/paths.d/go: macOSのシステムパスにGoのバイナリディレクトリ (/usr/local/go/bin) を追加するための設定ファイル。
  • misc/dist/darwin/scripts/postinstall: macOSパッケージのインストール後に実行されるスクリプト。パーミッションの修正、デバッガの設定、Xcode関連ファイルのインストールなどを行います。

コミット

commit fedc277013d7b8d2812c3ccb869e1a8530b5f6f5
Author: Andrew Gerrand <adg@golang.org>
Date:   Thu Feb 9 11:15:14 2012 +1100

    misc/dist: new hierarchy for binary distribution packaging scripts
    
    R=golang-dev, rsc, bradfitz
    CC=golang-dev
    https://golang.org/cl/5639063

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/fedc277013d7b8d2812c3ccb869e1a8530b5f6f5

元コミット内容

misc/dist: new hierarchy for binary distribution packaging scripts

R=golang-dev, rsc, bradfitz
CC=golang-dev
https://golang.org/cl/5639063

変更の背景

このコミットが行われた2012年当時、Go言語はまだ比較的新しい言語であり、その配布メカニズムは進化の途上にありました。Goのバイナリ配布は、ユーザーがGoを簡単にインストールし、利用を開始できるようにするために非常に重要です。

以前の配布スクリプトの構造は、おそらくOSごとの差異や将来的な拡張性を考慮すると、管理が複雑になる可能性がありました。このコミットの主な目的は、Goのバイナリ配布パッケージを生成するためのスクリプト群に、より整理された新しい階層構造を導入することです。これにより、異なるオペレーティングシステム(GOOS)向けのパッケージングプロセスが明確に分離され、保守性、拡張性、そして理解しやすさが向上します。特にmacOS (当時はOS X) 向けのパッケージングに焦点を当て、PackageMaker を利用したインストーラ作成プロセスを体系化しています。

前提知識の解説

  • GOOS: Go言語における環境変数の1つで、ターゲットとなるオペレーティングシステム(例: linux, darwin (macOS), windows)を示します。Goのビルドシステムは、このGOOSの値に基づいて、特定のOS向けのバイナリを生成します。このコミットでは、misc/dist 以下に darwin ディレクトリが作成され、macOS固有のパッケージングスクリプトが格納されています。
  • PackageMaker: Apple Developer Toolsの一部として提供されていたコマンドラインツールです。macOS向けのインストーラパッケージ(.pkg ファイル)を作成するために使用されました。このツールは、アプリケーションやファイルを特定のディレクトリ構造に配置し、インストールスクリプト(preinstall, postinstallなど)を組み込むことで、ユーザーが簡単にソフトウェアをインストールできるようにします。
  • GOROOT: Go言語のインストールディレクトリのルートパスを示す環境変数です。Goのソースコード、標準ライブラリ、ツールなどがこのディレクトリ以下に配置されます。このコミットのスクリプトでは、一時的なビルドディレクトリ内に GOROOT を設定し、最終的なインストールパス (/usr/local/go) を GOROOT_FINAL として定義しています。
  • Mercurial (hg): このコミットが行われた2012年当時、Go言語の公式リポジトリはGitではなくMercurial(略称hg)で管理されていました。hg root コマンドは、Mercurialリポジトリのルートディレクトリを特定するために使用されます。コミットメッセージ内の Pruning Mercurial metadata という記述は、配布パッケージにMercurialのバージョン管理メタデータ(.hg, .hgignore, .hgtags など)を含めないように削除していることを示しています。これは、配布されるバイナリパッケージが不要なファイルを含まず、クリーンな状態であることを保証するためです。
  • postinstall スクリプト: macOSのインストーラパッケージにおいて、インストールが完了した後に実行されるスクリプトです。このコミットでは、misc/dist/darwin/scripts/postinstall がこれに該当し、インストール後のファイルパーミッションの修正や、デバッガ関連の設定、Xcodeとの連携ファイルの配置など、追加のセットアップ作業を行います。
  • /etc/paths.d: macOSにおいて、システム全体のPATH環境変数を設定するためのディレクトリです。このディレクトリ内にファイルを作成し、そのファイル内にパスを記述することで、システム起動時にそのパスがPATHに追加されます。misc/dist/darwin/etc/paths.d/go ファイルは、Goのバイナリがインストールされる /usr/local/go/bin をシステムPATHに追加するために使用されます。これにより、ユーザーはターミナルから go コマンドを直接実行できるようになります。

技術的詳細

このコミットは、Go言語のmacOS向けバイナリ配布パッケージの生成プロセスを自動化するためのシェルスクリプト群を導入しています。主要なスクリプトは misc/dist/darwin/dist.bash であり、これは PackageMaker を利用してGoのインストーラパッケージ (.pkg ファイル) を作成します。

dist.bash スクリプトの主な処理フローは以下の通りです。

  1. 環境チェック: スクリプトが正しいディレクトリ ($GOROOT/misc/dist/darwin) から実行されているかを確認します。
  2. PackageMaker の探索: macOSのDeveloper Toolsに含まれる PackageMaker コマンドのパスを /Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker または /Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker から探索します。見つからない場合はエラーで終了します。
  3. 一時ディレクトリの準備: ビルドプロセスで使用する一時ディレクトリ (/tmp/go.build.tmp) を作成し、既存のパッケージファイル (.pkg, .dmg) を削除します。スクリプト終了時にはこの一時ディレクトリがクリーンアップされるように trap コマンドを設定しています。
  4. Goソースのコピーと環境設定:
    • 一時ディレクトリ内にGoのインストール先となるディレクトリ構造 ($BUILD/root/usr/local/go) を作成します。
    • Mercurialリポジトリのルート (hg root) からGoのソースコード全体を $GOROOT (一時ディレクトリ内の /usr/local/go) にコピーします。
    • etc ディレクトリ(paths.d ファイルを含む)を $BUILD/root/etc にコピーします。
    • GOROOTGOROOT_FINAL 環境変数を設定します。
  5. Goバージョンの検出: Goのソースディレクトリ (src) に移動し、./make.bash --dist-tool../bin/tool/dist version を実行してGoのバージョン情報を取得し、VERSION.cache ファイルから VERSION ファイルに移動させます。
  6. Mercurialメタデータの削除: コピーしたGoソースからMercurialのバージョン管理メタデータ (.hg, .hgignore, .hgtags) を削除します。これは、配布パッケージに不要なファイルを含めないためです。
  7. Goのビルド: Goのソースディレクトリ (src) に移動し、./all.bash を実行してGoのツールチェインと標準ライブラリをビルドします。ビルドの出力は標準エラー出力にリダイレクトされ、各行の先頭にスペースが追加されます。
  8. パッケージの構築: 最後に PackageMaker コマンドを実行し、以下の設定でGoのインストーラパッケージ (go.darwin.$VERSION.pkg) を作成します。
    • -v: 詳細出力モード。
    • -r $BUILD/root: パッケージのルートディレクトリとして一時ディレクトリ内の $BUILD/root を指定。
    • -o "go.darwin.$VERSION.pkg": 出力ファイル名。
    • --scripts scripts: インストールスクリプト(postinstall など)が格納されているディレクトリを指定。
    • --id com.googlecode.go: パッケージの識別子。
    • --title Go: インストーラのタイトル。
    • --version "0.1": パッケージのバージョン。
    • --target "10.5": ターゲットとなるmacOSのバージョン(OS X 10.5 Leopard以降)。

また、misc/dist/darwin/scripts/postinstall スクリプトは、インストール後に以下の処理を実行します。

  1. パーミッションの修正: インストールされたGoディレクトリ (/usr/local/go) 内のファイルとディレクトリのパーミッションを適切に設定します。実行可能ファイルには実行権限を付与し、ディレクトリには読み取り・実行権限を付与します。ルートディレクトリ (.) には書き込み権限を与えません。
  2. デバッガの修正: sudo.bash スクリプトを実行して、デバッガ関連のパーミッションを修正します。これは、デバッガが特定のシステムリソースにアクセスするために必要な権限を設定するものです。
  3. Xcode関連ファイルのインストール: XCODE_MISC_DIR (/Library/Application Support/Developer/Shared/Xcode/Specifications/) が存在する場合、$GOROOT/misc/xcode 内のファイルをそのディレクトリにコピーします。これにより、XcodeがGoのプロジェクトを認識し、適切に連携できるようになります。

コアとなるコードの変更箇所

misc/dist/darwin/dist.bash

+#!/bin/bash
+# Copyright 2011 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
+
+if ! test -f ../../../src/all.bash; then
+	echo >&2 "dist.bash must be run from $GOROOT/misc/dist/darwin"
+	exit 1
+fi
+
+echo >&2 "Locating PackageMaker..."
+PM=/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker
+if [ ! -x $PM ]; then
+	PM=/Developer$PM
+	if [ ! -x $PM ]; then
+		echo >&2 "could not find PackageMaker; aborting"
+		exit 1
+	fi
+fi
+echo >&2 "  Found: $PM"
+
+BUILD=/tmp/go.build.tmp
+ROOT=`hg root`
+export GOROOT=$BUILD/root/usr/local/go
+export GOROOT_FINAL=/usr/local/go
+
+echo >&2 "Removing old images"
+rm -f *.pkg *.dmg
+
+echo >&2 "Preparing temporary directory"
+rm -rf $BUILD
+mkdir -p $BUILD
+trap "rm -rf $BUILD" 0
+
+echo >&2 "Copying go source distribution"
+mkdir -p $BUILD/root/usr/local
+cp -r $ROOT $GOROOT
+cp -r etc $BUILD/root/etc
+
+pushd $GOROOT > /dev/null
+
+echo >&2 "Detecting version..."
+pushd src > /dev/null
+./make.bash --dist-tool > /dev/null
+../bin/tool/dist version > /dev/null
+popd > /dev/null
+mv VERSION.cache VERSION
+VERSION="$(cat VERSION | awk '{ print $1 }')"
+echo >&2 "  Version: $VERSION"
+
+echo >&2 "Pruning Mercurial metadata"
+rm -rf .hg .hgignore .hgtags
+
+echo >&2 "Building Go"
+pushd src
+./all.bash 2>&1 | sed "s/^/  /" >&2
+popd > /dev/null
+
+popd > /dev/null
+
+echo >&2 "Building package"
+$PM -v -r $BUILD/root -o "go.darwin.$VERSION.pkg" \
+	--scripts scripts \
+	--id com.googlecode.go \
+	--title Go \
+	--version "0.1" \
+	--target "10.5"

misc/dist/darwin/scripts/postinstall

+#!/bin/bash
+
+GOROOT=/usr/local/go
+
+echo "Fixing permissions"
+cd $GOROOT
+find . -exec chmod ugo+r {} \;
+find bin -exec chmod ugo+rx {} \;
+find . -type d -exec chmod ugo+rx {} \;
+chmod o-w .
+
+echo "Fixing debuggers via sudo.bash"
+# setgrp procmod the debuggers (sudo.bash)
+cd $GOROOT/src
+./sudo.bash
+
+echo "Installing miscellaneous files:"
+XCODE_MISC_DIR="/Library/Application Support/Developer/Shared/Xcode/Specifications/"
+if [ -f $XCODE_MISC_DIR ]; then
+	echo "  XCode"
+	cp $GOROOT/misc/xcode/* $XCODE_MISC_DIR
+fi

コアとなるコードの解説

misc/dist/darwin/dist.bash の解説

このスクリプトは、macOS上でGoのインストーラパッケージを生成するための中心的な役割を担っています。

  • set -e: コマンドが失敗した場合、スクリプトの実行を即座に停止させる設定です。これにより、エラーが発生した際に不完全なパッケージが生成されるのを防ぎます。
  • if ! test -f ../../../src/all.bash; then ... fi: スクリプトがGoのソースツリー内の正しい位置 ($GOROOT/misc/dist/darwin) から実行されていることを確認します。これは、ビルドに必要なファイル (all.bash) への相対パスが正しく解決されるようにするためです。
  • PM=/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker ...: PackageMaker コマンドの実行パスを特定します。macOSのDeveloper Toolsのインストール状況によってパスが異なる可能性があるため、複数の候補を試しています。
  • BUILD=/tmp/go.build.tmp: 一時的なビルドディレクトリを /tmp/go.build.tmp に設定しています。このディレクトリは、Goのソースコードのコピー、ビルドされたバイナリ、およびパッケージ化されるファイルの一時的な格納場所として使用されます。
  • ROOT=hg root``: Mercurialリポジトリのルートディレクトリを取得します。これは、Goのソースコード全体をコピーするために使用されます。
  • export GOROOT=$BUILD/root/usr/local/go: ビルドプロセス中に使用される GOROOT を、一時ディレクトリ内のGoインストールパスに設定します。これにより、実際のシステムに影響を与えることなく、独立した環境でGoをビルドできます。
  • export GOROOT_FINAL=/usr/local/go: 最終的にGoがインストールされるパスを定義します。これは PackageMaker がパッケージを作成する際に、インストール先のルートとして使用されます。
  • trap "rm -rf $BUILD" 0: スクリプトが終了する際に、一時ビルドディレクトリ $BUILD を削除するように設定しています。これにより、ビルドプロセス中に作成された一時ファイルがシステムに残るのを防ぎ、クリーンアップを自動化します。
  • cp -r $ROOT $GOROOT: MercurialリポジトリのルートからGoのソースコード全体を、一時的な GOROOT ディレクトリにコピーします。
  • cp -r etc $BUILD/root/etc: misc/dist/darwin/etc ディレクトリ(paths.d ファイルを含む)を、パッケージのルートディレクトリにコピーします。これにより、インストール時に /etc/paths.d/go が配置されます。
  • ./make.bash --dist-tool../bin/tool/dist version: Goのビルドシステムの一部である dist ツールを使用して、Goのバージョン情報を取得します。これは、生成されるパッケージファイル名にバージョンを含めるために使用されます。
  • rm -rf .hg .hgignore .hgtags: コピーされたGoソースからMercurialのバージョン管理メタデータを削除します。これは、配布パッケージのサイズを削減し、不要なファイルを含めないようにするためです。
  • ./all.bash 2>&1 | sed "s/^/ /" >&2: Goのソースディレクトリで all.bash スクリプトを実行し、Goのツールチェインと標準ライブラリをビルドします。2>&1 | sed "s/^/ /" >&2 は、標準出力と標準エラー出力を両方とも標準エラー出力にリダイレクトし、各行の先頭にスペースを追加して、スクリプトの出力を見やすくするためのものです。
  • $PM -v -r $BUILD/root -o "go.darwin.$VERSION.pkg" ...: PackageMaker コマンドの呼び出しです。
    • -r $BUILD/root: パッケージのコンテンツが配置されるルートディレクトリを指定します。PackageMaker はこのディレクトリの内容を基にパッケージを作成します。
    • --scripts scripts: インストールスクリプト(postinstall など)が格納されているディレクトリを指定します。PackageMaker はこのディレクトリからスクリプトを読み込み、パッケージに組み込みます。
    • その他のオプション (--id, --title, --version, --target) は、生成されるインストーラパッケージのメタデータを設定します。

misc/dist/darwin/scripts/postinstall の解説

このスクリプトは、GoのインストーラパッケージがmacOSシステムにインストールされた後に自動的に実行されます。

  • GOROOT=/usr/local/go: インストールされたGoのルートディレクトリを定義します。
  • find . -exec chmod ugo+r {} \;: インストールされたGoディレクトリ内のすべてのファイルに、所有者、グループ、その他のユーザーに対して読み取り権限 (+r) を付与します。
  • find bin -exec chmod ugo+rx {} \;: bin ディレクトリ内のすべてのファイル(Goの実行可能バイナリ)に、読み取り権限と実行権限 (+rx) を付与します。これにより、ユーザーはこれらのコマンドを実行できるようになります。
  • find . -type d -exec chmod ugo+rx {} \;: Goディレクトリ内のすべてのディレクトリに、読み取り権限と実行権限 (+rx) を付与します。これにより、ディレクトリの内容をリスト表示したり、その中に入ったりできるようになります。
  • chmod o-w .: Goのルートディレクトリ (.) から、その他のユーザーの書き込み権限 (o-w) を削除します。これにより、一般ユーザーが誤ってGoのインストールディレクトリを変更するのを防ぎます。
  • ./sudo.bash: GOROOT/src ディレクトリに移動し、sudo.bash スクリプトを実行します。このスクリプトは、デバッガが正しく機能するために必要な特別なパーミッション(例えば、procmod グループへの設定)を設定するものです。これは通常、特権を必要とする操作です。
  • XCODE_MISC_DIR="/Library/Application Support/Developer/Shared/Xcode/Specifications/": Xcodeの追加設定ファイルが配置される可能性のあるディレクトリを定義します。
  • if [ -f $XCODE_MISC_DIR ]; then ... fi: XCODE_MISC_DIR が存在する場合、$GOROOT/misc/xcode 内のファイルをそのディレクトリにコピーします。これにより、XcodeがGoのプロジェクトを認識し、Goのビルドシステムと連携するための設定が提供されます。

これらのスクリプトは、Goのバイナリ配布を自動化し、ユーザーがGoをmacOSシステムに簡単にインストールできるようにするための重要なコンポーネントです。

関連リンク

参考にした情報源リンク