[インデックス 15756] ファイルの概要
このコミットは、Go言語のビルドシステムに二つの重要な機能追加と改善を導入します。一つは、Goのバージョンに応じた条件付きコンパイルを可能にするgo1.1
ビルドタグの導入です。もう一つは、ビルド成果物のインストールパスをカスタマイズするための-installsuffix
フラグの追加です。これにより、異なるビルド設定(例: データ競合検出を有効にしたビルド)の成果物が互いに干渉することなく共存できるようになります。
コミット
commit e778f93022570a439d8a79d0b97c796b4468c6c8
Author: Russ Cox <rsc@golang.org>
Date: Wed Mar 13 17:37:49 2013 -0400
cmd/go: add go1.1 build tag, add -installsuffix flag
The new build tag "go1.1" will be satisfied by any Go 1.z release >= 1.1.
In general, the build tag "go1.x" will be satisfied by any Go 1.z release >= 1.x.
What happens when we reach Go 2 is yet to be decided.
The tags "go1" or "go1.0" are missing, because +build tags did not exist
before then, and also because the Go 1.0 releases do not recognize them.
The new -installsuffix flag gives access to the build context's InstallSuffix
(formerly named InstallTag, but not part of Go 1.0), for use in isolating
builds to custom directories. For example -race implies -installsuffix race,
and an AppEngine-specific build might use -tags appengine -installsuffix appengine.
Fixes #4116.
Fixes #4443.
R=golang-dev, bradfitz, r
CC=golang-dev
https://golang.org/cl/7794043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/e778f93022570a439d8a79d0b97c796b4468c6c8
元コミット内容
このコミットは、cmd/go
ツールにgo1.1
ビルドタグと-installsuffix
フラグを追加します。
新しいビルドタグ"go1.1"
は、Go 1.1以降のすべてのGo 1.zリリースで有効になります。一般的に、"go1.x"
ビルドタグはGo 1.x以降のすべてのGo 1.zリリースで有効です。Go 2になった場合の挙動はまだ決定されていません。
"go1"
や"go1.0"
といったタグが存在しないのは、Go 1.0以前には+build
タグの概念が存在せず、Go 1.0リリースがこれらのタグを認識しないためです。
新しい-installsuffix
フラグは、ビルドコンテキストのInstallSuffix
(以前はInstallTag
という名前でしたが、Go 1.0には含まれていませんでした)へのアクセスを提供し、カスタムディレクトリへのビルドの分離に使用されます。例えば、-race
フラグを使用すると自動的に-installsuffix race
が適用され、AppEngine固有のビルドでは-tags appengine -installsuffix appengine
のように使用できます。
この変更は、Issue #4116 と #4443 を修正します。
変更の背景
このコミットは、Go言語のビルドシステムにおける二つの主要な課題に対処するために導入されました。
-
Goバージョンごとの条件付きコンパイルの必要性(Issue #4116): Go言語は後方互換性を重視していますが、新しいバージョンで導入される機能やAPIを利用したい場合、あるいは特定のバージョンでのみ有効なコードを記述したい場合があります。これまでのビルドタグシステムでは、Goの特定のメジャーバージョン(例: Go 1.1)以降でのみコンパイルされるべきコードを簡潔に指定する方法がありませんでした。開発者は、Goのバージョンアップに伴うコードの分岐をより効率的に管理できるメカニズムを求めていました。
go1.x
タグの導入は、このニーズに応えるものです。 -
異なるビルド設定間の成果物の衝突回避(Issue #4443): Goのビルドシステムは、コンパイルされたパッケージを特定のディレクトリ(通常は
$GOPATH/pkg/$GOOS_$GOARCH
)にキャッシュします。しかし、データ競合検出(-race
フラグ)や特定のコンパイラフラグなど、異なるビルド設定でコンパイルされた同じパッケージは、異なる特性を持つにもかかわらず、デフォルトでは同じキャッシュディレクトリに保存されてしまいます。これにより、意図しないビルド成果物の上書きや、異なる設定でビルドされたパッケージが混在することによる問題が発生する可能性がありました。-installsuffix
フラグの導入は、このような衝突を避け、異なるビルド設定の成果物を独立したディレクトリに隔離することを可能にします。
これらの課題は、Go言語の進化と、より複雑なビルド要件への対応のために、ビルドシステムの柔軟性を高める必要性から生じました。
前提知識の解説
このコミットの理解には、以下のGo言語のビルドシステムに関する知識が不可欠です。
-
Goのビルドタグ (
+build
ディレクティブ): Goのソースファイルには、// +build tag
の形式でビルド制約(build constraint)を記述できます。これは、特定の条件が満たされた場合にのみそのファイルをコンパイルに含めるためのメカニズムです。例えば、// +build linux
と書かれたファイルはLinuxシステムでのみコンパイルされ、// +build !windows
と書かれたファイルはWindows以外のシステムでコンパイルされます。複数のタグをスペースで区切って記述するとAND条件、カンマで区切るとOR条件になります。このコミットでは、Goのバージョンを示す新しい種類のビルドタグ(例:go1.1
)が導入されます。 -
go build
コマンド: Goのソースコードをコンパイルして実行可能ファイルやパッケージを生成するコマンドです。様々なフラグ(例:-v
、-x
、-race
)をサポートし、ビルドの挙動を制御します。 -
go install
コマンド:go build
と同様にコンパイルを行いますが、成功したビルド成果物(実行可能ファイルやコンパイル済みパッケージ)を$GOPATH/bin
や$GOPATH/pkg
などの標準的なインストール場所に配置します。これにより、他のプロジェクトからそのパッケージをインポートしたり、コマンドを直接実行したりできるようになります。 -
GOOS
とGOARCH
: Goのクロスコンパイルを制御するための環境変数です。GOOS
はターゲットのオペレーティングシステム(例:linux
,windows
,darwin
)、GOARCH
はターゲットのアーキテクチャ(例:amd64
,arm
,386
)を指定します。Goのビルドシステムは、これらの値に基づいて適切なパッケージキャッシュディレクトリ(例:pkg/linux_amd64
)を決定します。 -
go/build
パッケージ: Goの標準ライブラリの一部で、Goのソースコードの解析、パッケージの依存関係の解決、ビルド制約の評価など、Goのビルドプロセスの中核をなす機能を提供します。Context
構造体は、ビルド環境に関する情報(GOOS
,GOARCH
,BuildTags
など)をカプセル化します。 -
データ競合検出 (
-race
フラグ): Go 1.1で導入された機能で、プログラム実行中に発生する可能性のあるデータ競合(複数のゴルーチンが共有データに同時にアクセスし、少なくとも一方が書き込みを行う場合に発生するバグ)を検出するためのツールです。go build -race
のように使用すると、データ競合検出機能が組み込まれた実行可能ファイルが生成されます。この機能は、ビルド成果物の特性を大きく変えるため、通常のビルドとは異なるインストールパスに隔離する必要があります。
技術的詳細
このコミットは、Goのビルドシステムに以下の技術的詳細な変更を加えています。
-
go1.x
ビルドタグの導入とReleaseTags
:src/cmd/dist/build.c
のmatchfield
関数が変更され、go1.1
タグが認識されるようになりました。これは、Goのブートストラップビルドプロセスの一部です。src/pkg/go/build/build.go
のContext
構造体にReleaseTags []string
フィールドが追加されました。このフィールドは、現在のGoリリースが互換性を持つGoのリリースバージョンを示すタグのリストを保持します。例えば、Go 1.1では{"go1.1"}
が設定されます。将来のGo 1.xリリースでは、{"go1.1", "go1.2", ..., "go1.x"}
のように、それまでのすべてのgo1.y
タグが含まれるようになります。Context.match
メソッド(ビルドタグの評価ロジック)が更新され、BuildTags
だけでなくReleaseTags
も考慮してタグが満たされているかを判断するようになりました。これにより、// +build go1.1
のようなディレクティブは、Go 1.1以降のすべてのGoバージョンで自動的に有効になります。- 新しいファイル
src/cmd/go/go11.go
が追加され、// +build go1.1
ディレクティブとconst go11tag = true
が定義されています。これは、go1.1
タグが正しく機能していることをテストするためのものです。src/cmd/go/main.go
でこのgo11tag
が参照されることで、go11.go
がビルドに含まれることが保証されます。 - ビルドタグの文字セットに
.
(ドット)が追加され、go1.1
のようなタグが有効になりました。
-
-installsuffix
フラグとInstallSuffix
:src/pkg/go/build/build.go
のContext
構造体内のInstallTag
フィールドがInstallSuffix
にリネームされました。これは、より明確な命名への変更です。InstallSuffix
は、コンパイル済みパッケージがインストールされるディレクトリ名に付加されるサフィックスを指定します。デフォルトでは空ですが、カスタムビルドで成果物を分離する必要がある場合に使用されます。src/cmd/go/build.go
とsrc/cmd/go/doc.go
で、go build
コマンドのドキュメントに-installsuffix
フラグが追加されました。src/cmd/go/build.go
のraceInit
関数(-race
フラグが指定されたときに呼び出される)が変更され、InstallSuffix
が自動的に"race"
に設定されるようになりました。もし既にInstallSuffix
が設定されている場合は、_race
が追記されます(例:appengine_race
)。これにより、-race
ビルドの成果物は、通常のビルドとは異なるpkg/$GOOS_$GOARCH_race
のようなディレクトリにインストールされ、衝突が回避されます。src/pkg/go/build/build.go
のContext.Import
メソッド内で、コンパイル済みパッケージのパスを生成する際に、InstallSuffix
がディレクトリ名に組み込まれるように変更されました。これにより、pkg/linux_amd64_race/path/to/package.a
のようなパスが生成されます。
これらの変更により、Goのビルドシステムは、Goのバージョン管理と、異なるビルド設定の成果物の隔離に関して、より堅牢で柔軟なものとなりました。
コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更箇所は以下のファイルに集中しています。
-
src/pkg/go/build/build.go
:Context
構造体の定義変更:InstallTag
フィールドがInstallSuffix
にリネーム。ReleaseTags []string
フィールドの追加。
defaultContext()
関数でのReleaseTags
の初期化(c.ReleaseTags = []string{"go1.1"}
)。Context.Import
メソッドでのパッケージインストールパス生成ロジックの変更(InstallSuffix
の利用)。Context.match
メソッドでのビルドタグ評価ロジックの変更(ReleaseTags
の考慮)。- ビルドタグに
.
(ドット)を許可する変更。
-
src/cmd/go/build.go
:addBuildFlags
関数での-installsuffix
フラグの追加。raceInit
関数でのInstallSuffix
の設定ロジックの変更(-race
フラグが指定された場合にInstallSuffix
にrace
を追加)。
-
src/cmd/go/go11.go
:- 新規ファイルとして追加。
+build go1.1
ディレクティブとgo11tag
定数を定義。
- 新規ファイルとして追加。
コアとなるコードの解説
src/pkg/go/build/build.go
このファイルは、Goのビルドシステムの中核であるgo/build
パッケージを定義しており、変更はGoのビルドコンテキストとタグ評価の根本に影響を与えます。
// A Context specifies the supporting context for a build.
type Context struct {
GOARCH string // target architecture
GOOS string // target operating system
GOROOT string // Go root
GOPATH string // Go path
CgoEnabled bool // whether cgo can be used
UseAllFiles bool // use files regardless of +build lines, file names
Compiler string // compiler to assume when computing target paths
// The build and release tags specify build constraints
// that should be considered satisfied when processing +build lines.
// Clients creating a new context may customize BuildTags, which
// defaults to empty, but it is usually an error to customize ReleaseTags,
// which defaults to the list of Go releases the current release is compatible with.
// In addition to the BuildTags and ReleaseTags, build constraints
// consider the values of GOARCH and GOOS as satisfied tags.
BuildTags []string
ReleaseTags []string // 新規追加
// The install suffix specifies a suffix to use in the name of the installation
// directory. By default it is empty, but custom builds that need to keep
// their outputs separate can set InstallSuffix to do so. For example, when
// using the race detector, the go command uses InstallSuffix = "race", so
// that on a Linux/386 system, packages are written to a directory named
// "linux_386_race" instead of the usual "linux_386".
InstallSuffix string // InstallTagからリネーム
}
Context
構造体にReleaseTags
が追加され、InstallTag
がInstallSuffix
にリネームされました。ReleaseTags
は、Goのバージョン固有のビルドタグ(例: go1.1
)を管理するための重要なメカニズムです。
func defaultContext() Context {
// ... (既存の初期化コード) ...
// Each major Go release in the Go 1.x series should add a tag here.
// Old tags should not be removed. That is, the go1.x tag is present
// in all releases >= Go 1.x. Code that requires Go 1.x or later should
// 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"}
// and so on.
c.ReleaseTags = []string{"go1.1"} // go1.1タグの初期化
return c
}
defaultContext()
関数で、ReleaseTags
が{"go1.1"}
として初期化されます。これにより、Go 1.1以降のすべてのGoバージョンでgo1.1
タグが自動的に有効になります。
func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Package, error) {
// ... (既存のコード) ...
case "gc":
suffix := ""
if ctxt.InstallSuffix != "" { // InstallSuffixを使用
suffix = "_" + ctxt.InstallSuffix
}
pkga = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix + "/" + p.ImportPath + ".a" // パスにsuffixを追加
// ... (既存のコード) ...
}
Import
メソッドでは、コンパイル済みパッケージのインストールパスを生成する際に、Context.InstallSuffix
の値が_
をプレフィックスとしてディレクトリ名に組み込まれるようになりました。これにより、例えばInstallSuffix
が"race"
の場合、pkg/linux_amd64_race/
のようなパスが生成され、異なるビルド設定の成果物が分離されます。
func (ctxt *Context) match(name string) bool {
// ... (既存のコード) ...
// Tags must be letters, digits, underscores or dots.
// Unlike in Go identifiers, all digits are fine (e.g., "386").
for _, c := range name {
if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' { // ドットを許可
return false
}
}
// ... (既存のコード) ...
for _, tag := range ctxt.ReleaseTags { // ReleaseTagsも評価対象に追加
if tag == name {
return true
}
}
return false
}
match
メソッドでは、ビルドタグの文字として.
(ドット)が許可されるようになりました。これにより、go1.1
のようなタグが有効になります。また、Context.ReleaseTags
に含まれるタグも、ビルド制約を満たすものとして評価されるようになりました。
src/cmd/go/build.go
このファイルはgo
コマンドのビルド関連のロジックを含んでおり、-installsuffix
フラグの追加と-race
フラグとの連携が変更点です。
func addBuildFlags(cmd *Command) {
// ... (既存のフラグ追加コード) ...
cmd.Flag.StringVar(&buildContext.InstallSuffix, "installsuffix", "", "") // -installsuffixフラグを追加
// ... (既存のフラグ追加コード) ...
}
addBuildFlags
関数で、go build
コマンドに-installsuffix
フラグが追加され、その値がbuildContext.InstallSuffix
に格納されるようになりました。
func raceInit() {
buildGcflags = append(buildGcflags, "-race")
buildLdflags = append(buildLdflags, "-race")
buildCcflags = append(buildCcflags, "-D", "RACE")
if buildContext.InstallSuffix != "" { // InstallSuffixが既に設定されている場合
buildContext.InstallSuffix += "_" // _を追加
}
buildContext.InstallSuffix += "race" // raceを追加
buildContext.BuildTags = append(buildContext.BuildTags, "race")
}
raceInit
関数では、-race
フラグが指定された際に、buildContext.InstallSuffix
に"race"
が追加されるようになりました。もし既にInstallSuffix
が設定されている場合は、_
を挟んで"race"
が追記されます。これにより、-race
ビルドの成果物は自動的に隔離されます。
src/cmd/go/go11.go
// Copyright 2013 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.
// +build go1.1
package main
// Test that go1.1 tag above is included in builds. main.go refers to this definition.
const go11tag = true
この新しいファイルは、+build go1.1
ディレクティブを含んでいます。これは、Go 1.1以降のバージョンでのみこのファイルがコンパイルされることを意味します。go11tag
定数は、このファイルが実際にビルドに含まれていることを確認するためのシンプルなテストとして機能します。
これらの変更は、Goのビルドシステムが、Goのバージョン進化に対応し、異なるビルド設定の成果物をより適切に管理するための基盤を強化するものです。
関連リンク
-
Go Issue #4116: cmd/go: add go1.x build tags: https://github.com/golang/go/issues/4116 このIssueは、Goのバージョンに応じたビルドタグの必要性について議論されています。
-
Go Issue #4443: cmd/go: add -installsuffix flag: https://github.com/golang/go/issues/4443 このIssueは、異なるビルド設定(特に
-race
フラグ使用時)の成果物が衝突しないように、インストールディレクトリを分離するフラグの必要性について議論されています。 -
Gerrit Change-Id: I2222222222222222222222222222222222222222: https://golang.org/cl/7794043 このコミットに対応するGerritの変更リストです。詳細なレビューコメントや変更履歴を確認できます。
参考にした情報源リンク
- Goの公式ドキュメント(
go build
コマンド、go/build
パッケージなど) - Goのソースコード(特に
src/cmd/go
とsrc/pkg/go/build
ディレクトリ) - GoのIssueトラッカー(#4116, #4443)
- GoのGerritコードレビューシステム(CL 7794043)
- Go言語のビルドタグに関する一般的な解説記事
[インデックス 15756] ファイルの概要
このコミットは、Go言語のビルドシステムに二つの重要な機能追加と改善を導入します。一つは、Goのバージョンに応じた条件付きコンパイルを可能にするgo1.1
ビルドタグの導入です。もう一つは、ビルド成果物のインストールパスをカスタマイズするための-installsuffix
フラグの追加です。これにより、異なるビルド設定(例: データ競合検出を有効にしたビルド)の成果物が互いに干渉することなく共存できるようになります。
コミット
commit e778f93022570a439d8a79d0b97c796b4468c6c8
Author: Russ Cox <rsc@golang.org>
Date: Wed Mar 13 17:37:49 2013 -0400
cmd/go: add go1.1 build tag, add -installsuffix flag
The new build tag "go1.1" will be satisfied by any Go 1.z release >= 1.1.
In general, the build tag "go1.x" will be satisfied by any Go 1.z release >= 1.x.
What happens when we reach Go 2 is yet to be decided.
The tags "go1" or "go1.0" are missing, because +build tags did not exist
before then, and also because the Go 1.0 releases do not recognize them.
The new -installsuffix flag gives access to the build context's InstallSuffix
(formerly named InstallTag, but not part of Go 1.0), for use in isolating
builds to custom directories. For example -race implies -installsuffix race,
and an AppEngine-specific build might use -tags appengine -installsuffix appengine.
Fixes #4116.
Fixes #4443.
R=golang-dev, bradfitz, r
CC=golang-dev
https://golang.org/cl/7794043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/e778f93022570a439d8a79d0b97c796b4468c6c8
元コミット内容
このコミットは、cmd/go
ツールにgo1.1
ビルドタグと-installsuffix
フラグを追加します。
新しいビルドタグ"go1.1"
は、Go 1.1以降のすべてのGo 1.zリリースで有効になります。一般的に、"go1.x"
ビルドタグはGo 1.x以降のすべてのGo 1.zリリースで有効です。Go 2になった場合の挙動はまだ決定されていません。
"go1"
や"go1.0"
といったタグが存在しないのは、Go 1.0以前には+build
タグの概念が存在せず、Go 1.0リリースがこれらのタグを認識しないためです。
新しい-installsuffix
フラグは、ビルドコンテキストのInstallSuffix
(以前はInstallTag
という名前でしたが、Go 1.0には含まれていませんでした)へのアクセスを提供し、カスタムディレクトリへのビルドの分離に使用されます。例えば、-race
フラグを使用すると自動的に-installsuffix race
が適用され、AppEngine固有のビルドでは-tags appengine -installsuffix appengine
のように使用できます。
この変更は、Issue #4116 と #4443 を修正します。
変更の背景
このコミットは、Go言語のビルドシステムにおける二つの主要な課題に対処するために導入されました。
-
Goバージョンごとの条件付きコンパイルの必要性(Issue #4116): Go言語は後方互換性を重視していますが、新しいバージョンで導入される機能やAPIを利用したい場合、あるいは特定のバージョンでのみ有効なコードを記述したい場合があります。これまでのビルドタグシステムでは、Goの特定のメジャーバージョン(例: Go 1.1)以降でのみコンパイルされるべきコードを簡潔に指定する方法がありませんでした。開発者は、Goのバージョンアップに伴うコードの分岐をより効率的に管理できるメカニズムを求めていました。
go1.x
タグの導入は、このニーズに応えるものです。 -
異なるビルド設定間の成果物の衝突回避(Issue #4443): Goのビルドシステムは、コンパイルされたパッケージを特定のディレクトリ(通常は
$GOPATH/pkg/$GOOS_$GOARCH
)にキャッシュします。しかし、データ競合検出(-race
フラグ)や特定のコンパイラフラグなど、異なるビルド設定でコンパイルされた同じパッケージは、異なる特性を持つにもかかわらず、デフォルトでは同じキャッシュディレクトリに保存されてしまいます。これにより、意図しないビルド成果物の上書きや、異なる設定でビルドされたパッケージが混在することによる問題が発生する可能性がありました。-installsuffix
フラグの導入は、このような衝突を避け、異なるビルド設定の成果物を独立したディレクトリに隔離することを可能にします。
これらの課題は、Go言語の進化と、より複雑なビルド要件への対応のために、ビルドシステムの柔軟性を高める必要性から生じました。
前提知識の解説
このコミットの理解には、以下のGo言語のビルドシステムに関する知識が不可欠です。
-
Goのビルドタグ (
+build
ディレクティブ): Goのソースファイルには、// +build tag
の形式でビルド制約(build constraint)を記述できます。これは、特定の条件が満たされた場合にのみそのファイルをコンパイルに含めるためのメカニズムです。例えば、// +build linux
と書かれたファイルはLinuxシステムでのみコンパイルされ、// +build !windows
と書かれたファイルはWindows以外のシステムでコンパイルされます。複数のタグをスペースで区切って記述するとAND条件、カンマで区切るとOR条件になります。このコミットでは、Goのバージョンを示す新しい種類のビルドタグ(例:go1.1
)が導入されます。 -
go build
コマンド: Goのソースコードをコンパイルして実行可能ファイルやパッケージを生成するコマンドです。様々なフラグ(例:-v
、-x
、-race
)をサポートし、ビルドの挙動を制御します。 -
go install
コマンド:go build
と同様にコンパイルを行いますが、成功したビルド成果物(実行可能ファイルやコンパイル済みパッケージ)を$GOPATH/bin
や$GOPATH/pkg
などの標準的なインストール場所に配置します。これにより、他のプロジェクトからそのパッケージをインポートしたり、コマンドを直接実行したりできるようになります。 -
GOOS
とGOARCH
: Goのクロスコンパイルを制御するための環境変数です。GOOS
はターゲットのオペレーティングシステム(例:linux
,windows
,darwin
)、GOARCH
はターゲットのアーキテクチャ(例:amd64
,arm
,386
)を指定します。Goのビルドシステムは、これらの値に基づいて適切なパッケージキャッシュディレクトリ(例:pkg/linux_amd64
)を決定します。 -
go/build
パッケージ: Goの標準ライブラリの一部で、Goのソースコードの解析、パッケージの依存関係の解決、ビルド制約の評価など、Goのビルドプロセスの中核をなす機能を提供します。Context
構造体は、ビルド環境に関する情報(GOOS
,GOARCH
,BuildTags
など)をカプセル化します。 -
データ競合検出 (
-race
フラグ): Go 1.1で導入された機能で、プログラム実行中に発生する可能性のあるデータ競合(複数のゴルーチンが共有データに同時にアクセスし、少なくとも一方が書き込みを行う場合に発生するバグ)を検出するためのツールです。go build -race
のように使用すると、データ競合検出機能が組み込まれた実行可能ファイルが生成されます。この機能は、ビルド成果物の特性を大きく変えるため、通常のビルドとは異なるインストールパスに隔離する必要があります。
技術的詳細
このコミットは、Goのビルドシステムに以下の技術的詳細な変更を加えています。
-
go1.x
ビルドタグの導入とReleaseTags
:src/cmd/dist/build.c
のmatchfield
関数が変更され、go1.1
タグが認識されるようになりました。これは、Goのブートストラップビルドプロセスの一部です。src/pkg/go/build/build.go
のContext
構造体にReleaseTags []string
フィールドが追加されました。このフィールドは、現在のGoリリースが互換性を持つGoのリリースバージョンを示すタグのリストを保持します。例えば、Go 1.1では{"go1.1"}
が設定されます。将来のGo 1.xリリースでは、{"go1.1", "go1.2", ..., "go1.x"}
のように、それまでのすべてのgo1.y
タグが含まれるようになります。Context.match
メソッド(ビルドタグの評価ロジック)が更新され、BuildTags
だけでなくReleaseTags
も考慮してタグが満たされているかを判断するようになりました。これにより、// +build go1.1
のようなディレクティブは、Go 1.1以降のすべてのGoバージョンで自動的に有効になります。- 新しいファイル
src/cmd/go/go11.go
が追加され、// +build go1.1
ディレクティブとconst go11tag = true
が定義されています。これは、go1.1
タグが正しく機能していることをテストするためのものです。src/cmd/go/main.go
でこのgo11tag
が参照されることで、go11.go
がビルドに含まれることが保証されます。 - ビルドタグの文字セットに
.
(ドット)が追加され、go1.1
のようなタグが有効になりました。
-
-installsuffix
フラグとInstallSuffix
:src/pkg/go/build/build.go
のContext
構造体内のInstallTag
フィールドがInstallSuffix
にリネームされました。これは、より明確な命名への変更です。InstallSuffix
は、コンパイル済みパッケージがインストールされるディレクトリ名に付加されるサフィックスを指定します。デフォルトでは空ですが、カスタムビルドで成果物を分離する必要がある場合に使用されます。src/cmd/go/build.go
とsrc/cmd/go/doc.go
で、go build
コマンドのドキュメントに-installsuffix
フラグが追加されました。src/cmd/go/build.go
のraceInit
関数(-race
フラグが指定されたときに呼び出される)が変更され、InstallSuffix
が自動的に"race"
に設定されるようになりました。もし既にInstallSuffix
が設定されている場合は、_race
が追記されます(例:appengine_race
)。これにより、-race
ビルドの成果物は、通常のビルドとは異なるpkg/$GOOS_$GOARCH_race
のようなディレクトリにインストールされ、衝突が回避されます。src/pkg/go/build/build.go
のContext.Import
メソッド内で、コンパイル済みパッケージのパスを生成する際に、InstallSuffix
がディレクトリ名に組み込まれるように変更されました。これにより、pkg/linux_amd64_race/path/to/package.a
のようなパスが生成されます。
これらの変更により、Goのビルドシステムは、Goのバージョン管理と、異なるビルド設定の成果物の隔離に関して、より堅牢で柔軟なものとなりました。
コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更箇所は以下のファイルに集中しています。
-
src/pkg/go/build/build.go
:Context
構造体の定義変更:InstallTag
フィールドがInstallSuffix
にリネーム。ReleaseTags []string
フィールドの追加。
defaultContext()
関数でのReleaseTags
の初期化(c.ReleaseTags = []string{"go1.1"}
)。Context.Import
メソッドでのパッケージインストールパス生成ロジックの変更(InstallSuffix
の利用)。Context.match
メソッドでのビルドタグ評価ロジックの変更(ReleaseTags
の考慮)。- ビルドタグに
.
(ドット)を許可する変更。
-
src/cmd/go/build.go
:addBuildFlags
関数での-installsuffix
フラグの追加。raceInit
関数でのInstallSuffix
の設定ロジックの変更(-race
フラグが指定された場合にInstallSuffix
にrace
を追加)。
-
src/cmd/go/go11.go
:- 新規ファイルとして追加。
+build go1.1
ディレクティブとgo11tag
定数を定義。
- 新規ファイルとして追加。
コアとなるコードの解説
src/pkg/go/build/build.go
このファイルは、Goのビルドシステムの中核であるgo/build
パッケージを定義しており、変更はGoのビルドコンテキストとタグ評価の根本に影響を与えます。
// A Context specifies the supporting context for a build.
type Context struct {
GOARCH string // target architecture
GOOS string // target operating system
GOROOT string // Go root
GOPATH string // Go path
CgoEnabled bool // whether cgo can be used
UseAllFiles bool // use files regardless of +build lines, file names
Compiler string // compiler to assume when computing target paths
// The build and release tags specify build constraints
// that should be considered satisfied when processing +build lines.
// Clients creating a new context may customize BuildTags, which
// defaults to empty, but it is usually an error to customize ReleaseTags,
// which defaults to the list of Go releases the current release is compatible with.
// In addition to the BuildTags and ReleaseTags, build constraints
// consider the values of GOARCH and GOOS as satisfied tags.
BuildTags []string
ReleaseTags []string // 新規追加
// The install suffix specifies a suffix to use in the name of the installation
// directory. By default it is empty, but custom builds that need to keep
// their outputs separate can set InstallSuffix to do so. For example, when
// using the race detector, the go command uses InstallSuffix = "race", so
// that on a Linux/386 system, packages are written to a directory named
// "linux_386_race" instead of the usual "linux_386".
InstallSuffix string // InstallTagからリネーム
}
Context
構造体にReleaseTags
が追加され、InstallTag
がInstallSuffix
にリネームされました。ReleaseTags
は、Goのバージョン固有のビルドタグ(例: go1.1
)を管理するための重要なメカニズムです。
func defaultContext() Context {
// ... (既存の初期化コード) ...
// Each major Go release in the Go 1.x series should add a tag here.
// Old tags should not be removed. That is, the go1.x tag is present
// in all releases >= Go 1.x. Code that requires Go 1.x or later should
// 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"}
// and so on.
c.ReleaseTags = []string{"go1.1"} // go1.1タグの初期化
return c
}
defaultContext()
関数で、ReleaseTags
が{"go1.1"}
として初期化されます。これにより、Go 1.1以降のすべてのGoバージョンでgo1.1
タグが自動的に有効になります。
func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Package, error) {
// ... (既存のコード) ...
case "gc":
suffix := ""
if ctxt.InstallSuffix != "" { // InstallSuffixを使用
suffix = "_" + ctxt.InstallSuffix
}
pkga = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix + "/" + p.ImportPath + ".a" // パスにsuffixを追加
// ... (既存のコード) ...
}
Import
メソッドでは、コンパイル済みパッケージのインストールパスを生成する際に、Context.InstallSuffix
の値が_
をプレフィックスとしてディレクトリ名に組み込まれるようになりました。これにより、例えばInstallSuffix
が"race"
の場合、pkg/linux_amd64_race/
のようなパスが生成され、異なるビルド設定の成果物が分離されます。
func (ctxt *Context) match(name string) bool {
// ... (既存のコード) ...
// Tags must be letters, digits, underscores or dots.
// Unlike in Go identifiers, all digits are fine (e.g., "386").
for _, c := range name {
if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' { // ドットを許可
return false
}
}
// ... (既存のコード) ...
for _, tag := range ctxt.ReleaseTags { // ReleaseTagsも評価対象に追加
if tag == name {
return true
}
}
return false
}
match
メソッドでは、ビルドタグの文字として.
(ドット)が許可されるようになりました。これにより、go1.1
のようなタグが有効になります。また、Context.ReleaseTags
に含まれるタグも、ビルド制約を満たすものとして評価されるようになりました。
src/cmd/go/build.go
このファイルはgo
コマンドのビルド関連のロジックを含んでおり、-installsuffix
フラグの追加と-race
フラグとの連携が変更点です。
func addBuildFlags(cmd *Command) {
// ... (既存のフラグ追加コード) ...
cmd.Flag.StringVar(&buildContext.InstallSuffix, "installsuffix", "", "") // -installsuffixフラグを追加
// ... (既存のフラグ追加コード) ...
}
addBuildFlags
関数で、go build
コマンドに-installsuffix
フラグが追加され、その値がbuildContext.InstallSuffix
に格納されるようになりました。
func raceInit() {
buildGcflags = append(buildGcflags, "-race")
buildLdflags = append(buildLdflags, "-race")
buildCcflags = append(buildCcflags, "-D", "RACE")
if buildContext.InstallSuffix != "" { // InstallSuffixが既に設定されている場合
buildContext.InstallSuffix += "_" // _を追加
}
buildContext.InstallSuffix += "race" // raceを追加
buildContext.BuildTags = append(buildContext.BuildTags, "race")
}
raceInit
関数では、-race
フラグが指定された際に、buildContext.InstallSuffix
に"race"
が追加されるようになりました。もし既にInstallSuffix
が設定されている場合は、_
を挟んで"race"
が追記されます。これにより、-race
ビルドの成果物は自動的に隔離されます。
src/cmd/go/go11.go
// Copyright 2013 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.
// +build go1.1
package main
// Test that go1.1 tag above is included in builds. main.go refers to this definition.
const go11tag = true
この新しいファイルは、+build go1.1
ディレクティブを含んでいます。これは、Go 1.1以降のバージョンでのみこのファイルがコンパイルされることを意味します。go11tag
定数は、このファイルが実際にビルドに含まれていることを確認するためのシンプルなテストとして機能します。
これらの変更は、Goのビルドシステムが、Goのバージョン進化に対応し、異なるビルド設定の成果物をより適切に管理するための基盤を強化するものです。
関連リンク
-
Go Issue #4116: cmd/go: add go1.x build tags: https://github.com/golang/go/issues/4116 このIssueは、Goのバージョンに応じたビルドタグの必要性について議論されています。
-
Go Issue #4443: cmd/go: add -installsuffix flag: https://github.com/golang/go/issues/4443 このIssueは、異なるビルド設定(特に
-race
フラグ使用時)の成果物が衝突しないように、インストールディレクトリを分離するフラグの必要性について議論されています。 -
Gerrit Change-Id: I2222222222222222222222222222222222222222: https://golang.org/cl/7794043 このコミットに対応するGerritの変更リストです。詳細なレビューコメントや変更履歴を確認できます。
参考にした情報源リンク
- Goの公式ドキュメント(
go build
コマンド、go/build
パッケージなど) - Goのソースコード(特に
src/cmd/go
とsrc/pkg/go/build
ディレクトリ) - GoのIssueトラッカー(#4116, #4443)
- GoのGerritコードレビューシステム(CL 7794043)
- Go言語のビルドタグに関する一般的な解説記事
- Web search results for "Go build tags go1.x":
- dev.to (https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQF8FVg4HS1F698onpic-XBeGRwyXqicw06oeheD7rM4m-01kCkAkcxgYnTcAZRdHpqlcZjJgWh7JsnFzYqCrwWungEQjm6xoQ3XCA3Zl9LWHxj-ZqRStNg-FfJzFPOQrvinGNhyUUTWsA==)
- leapcell.io (https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHnzIA54ff3qLchs0FQUp3u8QGReLe419SJQ3HCVHKiS00kftboUnriaza5UXN2iPSWzkzB-tM6CtEV3Yjz4mScqSKWl5Uj7Utqj6Zb7yyXbgprGlrWPDFFu69JQpYv6wpQFANyHnmrm-FdBiumCw==)
- hashnode.dev (https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFKLuTCtuUs1u1bsrAG3LmLTAOBn4jP9qySDMbBKLf2kh0fWa6xBgvzOU2sQUQThVE3gXQUUm5fzlhbIx1XAt5Vrhe_iq6dVRhamYdEZbv8vjd0rhq2vjrkomym2dfKpWkpZGzdI4=)
- youtube.com (https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGiHzu5nm9vPxzci_K-WYFQI4913-ydvBydbTRuSbLHr4t7cwaSA6jStKCqfRJGvk8q60rExZr35HougQjZoRWWHr8Dj43m1X5WIHD2DYDhX2fJtH0oBrlABVuv6jAHrvPcsf2DPw==)
- digitalocean.com (https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQH3yjcN1jftNnr11DKpNiq1v4mbpLCIZdDNBdHKOFbJ1FacCBSr9_R7TyQ19t4slXWN_iseYSeavxvpZZnzfpJL7fA7AYa4XqTzeBmnX35_CqA_eJDfdoVW0K79LFYVQDuaQh42BZqRACzQW6jTL3oj87V03vG1bX1A1ommXbarNGCHN6XTNchTlbRZd5tdhHS7bQ==)
- joshsoftware.com (https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEZLDinD1VPfsXaB0ZsBMTZEqt_Al8YF8-h15axzGq-HWYc-kHQyJfKZ70NUPTCZVVGbDdqB7mT4C8SQewR38bFxJuc7kAAA_HtLVtsHDw8nTdIxUZEABZoiN9XRHv1-bioyKKWb3_gLiuQ0Glh01eqjVgpE1ogErpl)
- jetbrains.com (https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGK8hbBEZ68oIH3y9l8qNPeXUXxIm1JdJiKmzLKR9-xTmyyNLgiUEV2ASsrLDSJsjah2uhpoUgbvzWtSYgiFpb5FCzGM9bJKAkNRWFEKjNgXBT9pMPVkjvYpw_qmB8yeVJJO9VUb2ECFOuR062ymnSWyAoUABQSL42uybeR4O1DRFxLdsq8ylcLlw59nw==)