[インデックス 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言語のビルドシステムに関する一般的な知識