[インデックス 17720] ファイルの概要
このコミットは、Go言語のビルドコマンド cmd/go
において、インクルードディレクトリの決定方法を改善するものです。具体的には、go build
コマンドに渡される -installsuffix
フラグの値が、生成されるインクルードディレクトリのパスに適切に反映されるように変更されています。
コミット
commit 57f69710d5d0f8fb24bb07aa3ce83f98077d9112
Author: Dave Day <djd@golang.org>
Date: Tue Oct 1 20:44:57 2013 -0400
cmd/go: use -installsuffix to determine the includes directory list
Currently, the directories generaed by includeArgs can have the "_race"
suffix added if invoked with -race flag, but ignores -installsuffix if
set.
R=adg, rsc
CC=golang-dev
https://golang.org/cl/14174043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/57f69710d5d0f8fb24bb07aa3ce83f98077d9112
元コミット内容
cmd/go: use -installsuffix to determine the includes directory list
現在、includeArgs
によって生成されるディレクトリは、-race
フラグが指定された場合に _race
サフィックスが追加されることがありますが、-installsuffix
が設定されていても無視されます。
変更の背景
Go言語のビルドシステムでは、コンパイルされたパッケージやライブラリが特定のディレクトリにインストールされます。これらのディレクトリは、Goのツールチェーンが依存関係を解決し、適切なバイナリをリンクするために使用されます。
従来、go build
コマンドに -race
フラグ(データ競合検出を有効にするためのフラグ)が渡された場合、生成されるインクルードディレクトリのパスには _race
というサフィックスが自動的に追加されていました。これは、race検出が有効なビルドとそうでないビルドの成果物を区別し、衝突を避けるための仕組みです。
しかし、Goには -installsuffix
という別のフラグも存在します。このフラグは、インストールされるパッケージのディレクトリ名に任意のサフィックスを追加するために使用されます。例えば、異なるバージョンのGoや異なるビルド設定でコンパイルされたパッケージを共存させたい場合などに利用されます。
このコミット以前は、-installsuffix
が指定されても、インクルードディレクトリのパスにはそのサフィックスが反映されませんでした。これは、ユーザーが -installsuffix
を使って意図的に異なるビルド環境を分離しようとしても、インクルードパスの不整合により問題が発生する可能性を意味していました。特に、Cgo(GoからC言語のコードを呼び出す機能)を使用する場合、Cコンパイラが正しいヘッダーファイルを見つけるために、正確なインクルードパスが必要となります。
この不整合を解消し、-installsuffix
の意図された挙動を完全にサポートするために、この変更が導入されました。これにより、-installsuffix
を使用してビルドされたパッケージのインクルードパスも、指定されたサフィックスを含むようになり、より堅牢で予測可能なビルド環境が提供されるようになりました。
前提知識の解説
- Go言語のビルドシステム (
cmd/go
):go build
,go install
,go get
などのコマンドを提供するGo言語の公式ツールチェーンの中核をなす部分です。ソースコードをコンパイルし、実行可能ファイルやライブラリを生成する役割を担います。 - インクルードディレクトリ (Include Directories): C/C++などの言語において、ヘッダーファイル(
.h
ファイルなど)が置かれているディレクトリを指します。コンパイラはこれらのディレクトリを検索して、ソースコード中でinclude
ディレクティブによって指定されたヘッダーファイルを見つけます。Go言語の文脈では、特にCgoを使用する際に、C言語のヘッダーファイルを探すためにこの概念が重要になります。 -race
フラグ:go build
やgo test
コマンドに渡されるビルドフラグの一つです。これを指定すると、Goランタイムにデータ競合検出機能が組み込まれます。これにより、並行処理における潜在的なデータ競合バグをランタイムで検出できるようになります。このフラグが有効な場合、ビルド成果物や関連するディレクトリには_race
サフィックスが付与されることがあります。-installsuffix
フラグ:go build
やgo install
コマンドに渡されるビルドフラグの一つです。このフラグを使用すると、インストールされるパッケージのディレクトリ名に任意のサフィックスを追加できます。例えば、go install -installsuffix=mybuild
とすると、通常pkg/linux_amd64
にインストールされるパッケージがpkg/linux_amd64_mybuild
のようなディレクトリにインストールされます。これは、異なるビルド設定やGoのバージョンでコンパイルされたパッケージを同じGOPATH内で共存させるために非常に有用です。filepath.Join
: Go言語のpath/filepath
パッケージにある関数で、オペレーティングシステムに応じた適切なパス区切り文字を使用して、複数のパス要素を結合します。これにより、クロスプラットフォームでのパス操作が容易になります。buildContext.InstallSuffix
: Goのビルドコンテキスト内で、-installsuffix
フラグによって指定された値が格納されるフィールドです。この値は、ビルドプロセス全体で利用され、インストールパスの決定などに影響を与えます。buildRace
: ビルドコンテキスト内で、-race
フラグが有効になっているかどうかを示すブール値の変数です。
技術的詳細
このコミットは、src/cmd/go/build.go
ファイル内の includeArgs
関数を変更しています。この関数は、Cgoを使用する際にCコンパイラに渡すインクルードパスを生成する役割を担っています。
変更前は、includeArgs
関数内でインクルードディレクトリのパスを構築する際、buildRace
フラグが true
の場合にのみ _race
サフィックスを追加していました。しかし、buildContext.InstallSuffix
の値は考慮されていませんでした。
変更後は、buildRace
のチェックの代わりに buildContext.InstallSuffix != ""
のチェックが行われるようになりました。これにより、-installsuffix
フラグが指定され、その値が空文字列でない場合に、その値がインクルードディレクトリのパスにサフィックスとして追加されるようになります。具体的には、dir += "_" + buildContext.InstallSuffix
という形でサフィックスが追加されます。
この変更により、-installsuffix
を使用してビルドされたパッケージのインクルードパスも、そのサフィックスを含むようになります。これにより、Cgoを使用するプロジェクトにおいて、異なる -installsuffix
でビルドされたライブラリが正しくリンクされるようになり、ビルドの整合性が向上します。
例えば、-installsuffix=debug
を指定してビルドした場合、以前はインクルードパスが pkg/linux_amd64
のような形になっていましたが、この変更後は pkg/linux_amd64_debug
のような形になり、Cコンパイラが正しいヘッダーファイルを見つけられるようになります。
コアとなるコードの変更箇所
変更は src/cmd/go/build.go
ファイルの includeArgs
関数内で行われています。
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -1052,8 +1052,8 @@ func (b *builder) includeArgs(flag string, all []*action) []string {
dir = filepath.Join(dir, "gccgo_"+goos+"_"+goarch)
} else {
dir = filepath.Join(dir, goos+"_"+goarch)
- if buildRace {
- dir += "_race"
+ if buildContext.InstallSuffix != "" {
+ dir += "_" + buildContext.InstallSuffix
}
}
inc = append(inc, flag, dir)
コアとなるコードの解説
上記の差分は、src/cmd/go/build.go
ファイル内の includeArgs
関数の一部を示しています。
dir = filepath.Join(dir, goos+"_"+goarch)
: この行は、GoのOS (goos
) とアーキテクチャ (goarch
) に基づいて、プラットフォーム固有のディレクトリパスを構築しています。例えば、Linux AMD64環境であればlinux_amd64
のようなサフィックスが追加されます。- if buildRace {
と- dir += "_race"
: 変更前のコードでは、buildRace
というブール変数がtrue
(つまり、-race
フラグが指定されている)の場合にのみ、ディレクトリパスに_race
というサフィックスを追加していました。+ if buildContext.InstallSuffix != "" {
と+ dir += "_" + buildContext.InstallSuffix
: 変更後のコードでは、buildRace
のチェックが削除され、代わりにbuildContext.InstallSuffix
が空文字列でないかどうかがチェックされます。buildContext.InstallSuffix
は、-installsuffix
フラグによって指定された値が格納されているフィールドです。もしこの値が設定されていれば、その値の前にアンダースコア (_
) を付けてディレクトリパスに追加します。
この変更により、インクルードディレクトリの命名規則が -race
フラグだけでなく、より汎用的な -installsuffix
フラグによって制御されるようになりました。これにより、ユーザーはビルド成果物のインストールパスをより柔軟にカスタマイズできるようになり、異なるビルド設定間での衝突を避けることが可能になります。
関連リンク
- Go言語の公式ドキュメント: https://golang.org/
- Goコマンドのドキュメント (
go build
など): https://golang.org/cmd/go/ - Goのビルドフラグに関する情報: https://golang.org/cmd/go/#hdr-Build_flags
参考にした情報源リンク
- https://golang.org/cl/14174043 (元のGerritチェンジリスト)
- Go言語のソースコード (
src/cmd/go/build.go
) - Go言語の公式ドキュメント
- Go言語のビルドシステムに関する一般的な知識