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

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

このコミットは、Go 1.3のリリースノートドキュメント(doc/go1.3.html)に、go buildコマンドの新しいオプションである-iについての記述を追加するものです。この-iオプションは、指定されたターゲットの依存関係をインストールしますが、ターゲット自体はビルドしないという機能を提供します。

コミット

doc/go1.3.html: mention go build -i

LGTM=iant
R=golang-codereviews, iant
CC=golang-codereviews, r
https://golang.org/cl/95010049

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

https://github.com/golang/go/commit/2702ad38066a43ef6af5217ee0148c3d6424ee72

元コミット内容

--- a/doc/go1.3.html
+++ b/doc/go1.3.html
@@ -168,6 +168,12 @@ now always builds the package, even if it has no test files.
 Previously, it would do nothing if no test files were present.
 </p>
 
+<p>
+The <a href="/cmd/go/"><code>go build</code></a> subcommand
+supports a new <code>-i</code> option to install dependencies
+of the specified target, but not the target itself.
+</p>
+
 <p>
 Finally, the go command now supports packages that import Objective-C
 files (suffixed <code>.m</code>) through cgo.

変更の背景

Goのビルドシステムにおいて、プロジェクトの依存関係を管理し、効率的なビルドプロセスを実現することは常に重要な課題でした。go buildコマンドは通常、指定されたパッケージとその依存関係をコンパイルしますが、場合によっては、依存関係のみを事前にビルドしてインストールし、メインのターゲットパッケージのビルドは後回しにしたいというニーズが生じます。

例えば、大規模なプロジェクトで、多くの開発者が共通の依存ライブラリを使用している場合、各開発者が個別に依存ライブラリをビルドするのではなく、一度ビルドされた依存ライブラリを共有したいというシナリオが考えられます。また、CI/CDパイプラインにおいて、依存関係のビルドとメインアプリケーションのビルドを分離することで、ビルド時間の短縮やキャッシュの効率化を図ることも可能です。

このような背景から、Go 1.3ではgo buildコマンドに-iオプションが導入されました。このオプションは、ターゲットパッケージ自体をビルドせずに、その依存関係のみを$GOPATH/pkg(または$GOROOT/pkg)にインストールすることを可能にします。これにより、開発者は依存関係の管理をより細かく制御できるようになり、ビルドプロセスの柔軟性と効率性が向上しました。

前提知識の解説

Goのビルドシステムとコマンド

Go言語には、ソースコードのコンパイル、パッケージの管理、テストの実行などを行うための強力なコマンドラインツールが標準で提供されています。その中でも、本コミットに関連する主要なコマンドは以下の通りです。

  • go build: このコマンドは、Goのソースファイルをコンパイルして実行可能バイナリを生成します。引数としてパッケージパスやファイルパスを指定できます。go buildは、指定されたパッケージとそのすべての依存関係をコンパイルし、実行可能ファイルを現在のディレクトリに生成します(mainパッケージの場合)。ライブラリパッケージの場合、実行可能ファイルは生成されず、コンパイルされたパッケージはキャッシュされます。

  • go install: go installコマンドは、go buildと同様にパッケージをコンパイルしますが、コンパイルされたパッケージや実行可能ファイルを特定の場所にインストールします。実行可能ファイルは$GOPATH/bin(または$GOBIN)に、コンパイル済みパッケージは$GOPATH/pkg(または$GOROOT/pkg)にインストールされます。go installは、ビルドされた成果物を再利用可能な形で保存し、他のプロジェクトやシステム全体から参照できるようにするために使用されます。

Goのパッケージと依存関係

Goのコードは「パッケージ」という単位で整理されます。パッケージは、関連するGoのソースファイルの集まりであり、他のパッケージから関数や変数などをインポートして利用することができます。あるパッケージが別のパッケージの機能を利用する場合、その利用される側のパッケージは利用する側のパッケージの「依存関係」となります。

Goのビルドシステムは、これらの依存関係を自動的に解決し、必要なすべてのパッケージをコンパイルしてリンクします。コンパイルされたパッケージは、通常、$GOPATH/pkgディレクトリにキャッシュされ、その後のビルドで再利用されることで、ビルド時間の短縮に貢献します。

技術的詳細

go build -iオプションは、go buildコマンドの動作を拡張し、特定のユースケースに対応するために導入されました。

go build -iの機能

このオプションの主な機能は以下の通りです。

  1. 依存関係のインストール: go build -iは、指定されたターゲットパッケージが依存するすべてのパッケージをコンパイルし、それらを$GOPATH/pkg(または$GOROOT/pkg)ディレクトリにインストールします。
  2. ターゲットパッケージのスキップ: 重要な点として、-iオプションを使用した場合、go buildは指定されたターゲットパッケージ自体はビルドしません。つまり、mainパッケージを指定しても実行可能ファイルは生成されませんし、ライブラリパッケージを指定してもそのパッケージ自体はコンパイルされません。コンパイルされるのは、あくまでそのターゲットが依存するパッケージのみです。

なぜこのオプションが必要か?

従来のgo buildgo installコマンドは、常にターゲットパッケージを含めてビルドまたはインストールを行いました。しかし、以下のようなシナリオでは、依存関係のみを事前に準備したいというニーズがありました。

  • 大規模なモノレポ環境: 複数のプロジェクトが共通の内部ライブラリに依存している場合、各プロジェクトのビルド前に共通ライブラリを一度だけビルドしてキャッシュしておきたい。
  • CI/CDパイプラインの最適化: ビルドステージとテストステージを分離する際に、テスト実行前に必要な依存関係をすべて準備しておきたいが、メインのアプリケーションバイナリはまだ必要ない場合。
  • 開発環境のセットアップ: 新しい開発者がプロジェクトに参加した際に、最初にすべての依存関係をローカルにキャッシュしておくことで、その後の開発作業をスムーズに進めたい場合。

go build -iは、これらのシナリオにおいて、不要なターゲットパッケージのビルドを避けつつ、必要な依存関係を効率的に準備するための手段を提供します。これにより、ビルド時間の短縮、リソースの節約、およびビルドプロセスのよりきめ細やかな制御が可能になります。

内部的な動作(推測)

go build -iが実行されると、Goツールチェーンは以下のステップを実行すると考えられます。

  1. 指定されたターゲットパッケージの依存グラフを解析します。
  2. 依存グラフ内の各依存パッケージについて、コンパイルが必要かどうかを判断します(既にキャッシュされている場合はスキップ)。
  3. コンパイルが必要な依存パッケージをコンパイルし、その結果を$GOPATH/pkg(または$GOROOT/pkg)ディレクトリにインストールします。
  4. ターゲットパッケージ自体のコンパイルは行いません。

このプロセスにより、依存関係のビルドとキャッシュが効率的に行われ、その後のターゲットパッケージのビルド時にこれらのキャッシュされた依存関係が再利用されることになります。

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

このコミットは、Goのソースコード自体を変更するものではなく、Go 1.3のリリースノートドキュメント(doc/go1.3.html)に新しい機能の記述を追加するものです。

具体的には、以下のHTMLスニペットがdoc/go1.3.htmlファイルに追加されました。

<p>
The <a href="/cmd/go/"><code>go build</code></a> subcommand
supports a new <code>-i</code> option to install dependencies
of the specified target, but not the target itself.
</p>

この変更は、ファイルの168行目付近に挿入されています。

コアとなるコードの解説

追加されたHTMLスニペットは、Go 1.3のリリースノートにおいて、go buildコマンドの新しい-iオプションについて公式に説明するものです。

  • <p>タグは、新しい段落を開始することを示します。
  • The <a href="/cmd/go/"><code>go build</code></a> subcommand:これは、go buildコマンドへのリンクと、それがサブコマンドであることを示しています。/cmd/go/は、Goコマンドの公式ドキュメントへの相対パスです。
  • supports a new <code>-i</code> optiongo buildが新しい-iオプションをサポートすることを示しています。<code>タグは、コードスニペット(この場合はオプション名)を表現するために使用されます。
  • to install dependencies of the specified target, but not the target itself.:これが-iオプションの核心的な機能説明です。つまり、「指定されたターゲットの依存関係をインストールするが、ターゲット自体はインストールしない」という動作を明確に述べています。

このドキュメントの追加により、Go 1.3のユーザーは、go build -iオプションの存在とその目的を公式のリリースノートを通じて知ることができるようになりました。これは、新しい機能の採用と理解を促進するために非常に重要です。

関連リンク

参考にした情報源リンク