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

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

コミット

このコミットは、Go言語のビルドシステムにおいて、Go 1.3リリースに対応するビルドタグ go1.3 を追加するものです。具体的には、src/pkg/go/build/build.go ファイル内の Context 構造体の ReleaseTags フィールドに go1.3 を追加しています。これにより、Go 1.3以降で利用可能となる機能やAPIに依存するコードを、ビルドタグ +build go1.3 を用いて条件付きでコンパイルできるようになります。

コミットハッシュ: 3100088743190239846d758f6a7d83de5af0efb8 作者: Brad Fitzpatrick bradfitz@golang.org コミット日時: 2014年5月1日 木曜日 12:16:03 -0400

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

https://github.com/golang/go/commit/3100088743190239846d758f6a7d83de5af0efb8

元コミット内容

go/build: add go1.3 release tag

Fixes #7918

LGTM=dave
R=rsc, dave
CC=golang-codereviews
https://golang.org/cl/91980043

変更の背景

Go言語では、特定のGoバージョンで導入された機能や変更に依存するコードを、そのバージョンが利用可能な場合にのみビルドするメカニズムとして「ビルドタグ(build tags)」を提供しています。これは、ソースファイルの先頭に +build ディレクティブ(Go 1.17以降は //go:build)を記述することで実現されます。

Goのリリースサイクルでは、新しいメジャーバージョン(例: Go 1.1, Go 1.2, Go 1.3など)がリリースされるたびに、そのバージョンに対応するビルドタグが go/build パッケージの Context 構造体内の ReleaseTags リストに追加されます。このリストは、Goツールチェインがソースファイルをコンパイルする際に、どのビルドタグが有効であるかを判断するために使用されます。

このコミットは、Go 1.3のリリースに先立って、go1.3 というビルドタグをシステムに認識させるために行われました。これにより、開発者はGo 1.3の新機能を利用するコードに対して +build go1.3 を指定し、Go 1.3がインストールされた環境でのみそのコードがビルドされるように制御できるようになります。これは、後方互換性を保ちつつ、新しいGoバージョンへの移行をスムーズに行う上で非常に重要な仕組みです。

コミットメッセージにある Fixes #7918 は、この変更が特定の課題(おそらくGo 1.3のリリース準備に関連する内部的な課題)を解決するものであることを示唆していますが、公開されているGoのIssueトラッカーでは該当するIssueは見つかりませんでした。これは内部的なトラッカーのIDであるか、あるいは古い情報である可能性があります。

前提知識の解説

Goのビルドタグ(Build Tags / Build Constraints)

Goのビルドタグは、ソースコードの条件付きコンパイルを可能にするためのメカニズムです。これにより、特定のオペレーティングシステム、アーキテクチャ、Goのバージョン、またはカスタムの条件に基づいて、ファイル全体をビルドに含めるか除外するかを制御できます。

  • 構文:

    • 旧構文 (Go 1.16まで): // +build tag1,tag2 tag3
      • カンマ区切り (tag1,tag2) はAND条件(tag1tag2 の両方が存在する場合)。
      • スペース区切り (tag1 tag2) はOR条件(tag1 または tag2 のいずれかが存在する場合)。
      • !tag はNOT条件(tag が存在しない場合)。
    • 新構文 (Go 1.17以降): //go:build tag1 && tag2 || tag3
      • より直感的で、&& (AND), || (OR), ! (NOT) を使用したブール式をサポートします。
      • このコミットが行われた2014年時点では、旧構文が主流でした。
  • 配置: ビルドタグは、Goソースファイルの先頭に、パッケージ宣言やインポートの前に記述する必要があります。タグの後に空行を挟むことで、通常のコメントと区別されます。

  • Goバージョンタグ: Goツールチェインは、Goのリリースバージョンに対応する特別なビルドタグを自動的に有効にします。例えば、Go 1.3環境では go1.1, go1.2, go1.3 のタグが有効になります。これにより、開発者は +build go1.3 のように記述することで、Go 1.3以降でしか利用できないコードを安全に記述できます。

go/build パッケージ

go/build パッケージは、Goのソースコードを解析し、パッケージのビルドに関する情報を提供する標準ライブラリです。このパッケージは、Goツールチェイン(go build, go install など)の内部で利用され、ソースファイルの依存関係の解決、ビルドタグの評価、および環境に応じたファイルの選択を行います。

  • Context 構造体: go/build パッケージの中心的な構造体の一つが Context です。これは、ビルド環境に関する情報(例: OS、アーキテクチャ、GOROOT、GOPATHなど)をカプセル化します。
  • ReleaseTags フィールド: Context 構造体には ReleaseTags というフィールドがあり、これは現在有効なGoのリリースバージョンに対応するビルドタグの文字列スライスを保持しています。Goツールチェインは、このリストに含まれるタグに基づいて、ソースファイル内の +build ディレクティブを評価します。

Goのリリースサイクル

Go言語は、通常6ヶ月ごとに新しいメジャーバージョンをリリースしています。各リリースでは、新しい機能の追加、パフォーマンスの改善、バグ修正などが行われます。この定期的なリリースサイクルにより、Goは継続的に進化し、開発者に最新の機能を提供しています。ビルドタグは、このリリースサイクルの中で、異なるGoバージョン間でのコードの互換性を管理するための重要なツールとなっています。

技術的詳細

このコミットの技術的な核心は、go/build パッケージの Context 構造体における ReleaseTags フィールドの更新です。

Context 構造体は、Goのビルドプロセスにおける環境設定を定義します。これには、ターゲットとなるオペレーティングシステム (GOOS)、アーキテクチャ (GOARCH)、Goのインストールパス (GOROOT) などが含まれます。ReleaseTags フィールドは、Goの特定のリリースバージョンに対応するビルドタグのリストを保持します。

Goツールチェインがソースファイルをコンパイルする際、ファイルに記述された +build ディレクティブを評価します。この評価は、現在の Context の情報、特に ReleaseTags に基づいて行われます。例えば、Go 1.3環境でコンパイルする場合、ContextReleaseTags には go1.1, go1.2, go1.3 が含まれます。これにより、+build go1.3 と記述されたファイルはビルドに含まれ、+build !go1.3 と記述されたファイルは除外されます。

このコミットでは、c.ReleaseTags = []string{"go1.1", "go1.2"} という行が c.ReleaseTags = []string{"go1.1", "go1.2", "go1.3"} に変更されました。これは、Go 1.3がリリースされる準備が整ったことを意味し、Goツールチェインが go1.3 タグを認識し、それに対応するコードをビルドに含めることができるようになったことを示します。

この変更は、Goのビルドシステムが将来のリリースに備えてどのように進化していくかを示す良い例でもあります。コメントで「When we reach Go 1.4 the line will read c.ReleaseTags = []string{"go1.1", "go1.2", "go1.3", "go1.4"}」とあるように、新しいGoバージョンがリリースされるたびに、この ReleaseTags リストが更新されることが慣例となっています。

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

--- a/src/pkg/go/build/build.go
+++ b/src/pkg/go/build/build.go
@@ -292,10 +292,10 @@ func defaultContext() Context {
 	// say "+build go1.x", and code that should only be built before Go 1.x
 	// (perhaps it is the stub to use in that case) should say "+build !go1.x".
 	//
-	// When we reach Go 1.3 the line will read
-	//		c.ReleaseTags = []string{"go1.1", "go1.2", "go1.3"}
+	// When we reach Go 1.4 the line will read
+	//		c.ReleaseTags = []string{"go1.1", "go1.2", "go1.3", "go1.4"}
 	// and so on.
-	c.ReleaseTags = []string{"go1.1", "go1.2"}
+	c.ReleaseTags = []string{"go1.1", "go1.2", "go1.3"}
 
 	switch os.Getenv("CGO_ENABLED") {
 	case "1":

コアとなるコードの解説

変更は src/pkg/go/build/build.go ファイル内の defaultContext() 関数にあります。この関数は、Goのビルドプロセスで使用されるデフォルトの Context 構造体を初期化します。

変更前のコードでは、c.ReleaseTags{"go1.1", "go1.2"} と初期化されていました。これは、Go 1.2までのリリースバージョンに対応するビルドタグが有効であることを示していました。

変更後のコードでは、c.ReleaseTags{"go1.1", "go1.2", "go1.3"} となっています。この変更により、Go 1.3がリリースされた際に、Goツールチェインが go1.3 ビルドタグを認識し、それを使用するソースファイルを適切に処理できるようになります。

また、コメントも更新されており、次のリリースであるGo 1.4では go1.4 タグが追加されることが示唆されています。これは、Goのリリースプロセスとビルドタグの管理がどのように連携しているかを明確に示しています。このシンプルな変更は、Goエコシステム全体における条件付きコンパイルの基盤を更新する重要なステップです。

関連リンク

  • Go CL (Code Review) リンク: https://golang.org/cl/91980043
  • 関連する可能性のあるIssue: Fixes #7918 との記述がありますが、公開されているGoのIssueトラッカーでは該当するIssueは見つかりませんでした。

参考にした情報源リンク

  • Go公式ドキュメント: https://go.dev/
  • Go Packages (go/build): https://pkg.go.dev/go/build
  • Go Build Constraints (ビルドタグに関する詳細): https://go.dev/cmd/go/#hdr-Build_constraints
  • Web検索結果 (Go build tags, Go go/build packageに関する情報)
    • dev.to, leapcell.io, digitalocean.com, wawand.co, stackoverflow.com, jetbrains.com, medium.com (Go build tagsに関する一般的な情報源)
    • go.dev (go/build packageに関する公式ドキュメント)
    • (Go issue 7918については、関連する公開情報は見つかりませんでした。)