[インデックス 12305] ファイルの概要
このコミットは、Go言語のビルドシステムの一部である src/cmd/dist/build.c
ファイルに対する変更です。cmd/dist
はGoのソースコードからツールチェーンを構築するためのプログラムであり、Cコンパイラ(CC)の検出と利用を管理しています。build.c
は、このビルドプロセスにおけるCコンパイラの引数処理や特定のコンパイラ(Clangなど)の識別ロジックを担っています。
コミット
このコミットは、GoのビルドシステムがCコンパイラを識別するロジックを改善するものです。具体的には、環境変数 CC
が "ccache clang"
のように設定されている場合に、Goのビルドシステムがこれを正しく clang
コンパイラとして認識できるように修正しています。これにより、clang
に特有のコンパイラフラグ(例: -Wno-dangling-else
, -Wno-unused-value
)が適切に適用されるようになります。
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/03769efe414863be778b80eac7425d5f382d87cf
元コミット内容
cmd/dist: recognize CC="ccache clang" as clang
R=golang-dev, gri
CC=golang-dev
https://golang.org/cl/5711052
変更の背景
Go言語のビルドプロセスでは、C言語で書かれた部分(例: ランタイム、一部の標準ライブラリ)をコンパイルするためにCコンパイラを使用します。このCコンパイラは、通常、環境変数 CC
で指定されます。
以前の cmd/dist
の実装では、CC
環境変数の値が直接 clang
を含んでいるかどうかをチェックしていました。しかし、開発環境によっては、コンパイル時間を短縮するために ccache
のようなコンパイラキャッシュツールをCコンパイラのフロントエンドとして使用することが一般的です。この場合、CC
は "ccache clang"
のように設定されます。
この設定では、従来の cmd/dist
のロジックでは clang
が直接 CC
の先頭にないため、clang
であると正しく認識されませんでした。その結果、clang
に特有の警告抑制フラグ(-Wno-dangling-else
, -Wno-unused-value
)が適用されず、ビルド時に不要な警告が発生したり、最悪の場合、ビルドが失敗する可能性がありました。
このコミットは、このような ccache
を介した clang
の利用シナリオに対応し、Goのビルドシステムがより堅牢にCコンパイラを識別できるようにするために行われました。
前提知識の解説
cmd/dist
: Go言語のソースコードからGoツールチェーン(コンパイラ、リンカ、アセンブラなど)をビルドするためのプログラムです。Goの自己ホスト型コンパイラがまだ存在しない初期段階や、新しいGoのバージョンをビルドする際に使用されます。cmd/dist
は、C言語で書かれたGoのランタイムや一部のライブラリをコンパイルするために、システムにインストールされているCコンパイラ(GCCやClangなど)を利用します。CC
環境変数: Cコンパイラを指定するための標準的な環境変数です。例えば、export CC=clang
と設定すると、ビルドシステムはclang
をCコンパイラとして使用します。clang
: LLVMプロジェクトの一部であるC、C++、Objective-C、Objective-C++コンパイラのフロントエンドです。GCCと互換性のあるコマンドラインオプションを持ち、高速なコンパイルと詳細な診断メッセージが特徴です。ccache
: コンパイラキャッシュツールです。コンパイル結果をキャッシュすることで、同じソースコードを再コンパイルする際の時間を大幅に短縮します。ccache
を使用する場合、実際のコンパイラ(例:clang
)の前にccache
を呼び出すように設定します。例えば、CC="ccache clang"
のように設定します。ccache
は引数を解析し、キャッシュヒットすればキャッシュされた結果を返し、そうでなければ実際のコンパイラを呼び出します。xstrstr
: Goのビルドシステム内で使用されるユーティリティ関数で、文字列haystack
内にneedle
が含まれているかを検索します。標準Cライブラリのstrstr
に似ています。bstr(&b)
:b
はおそらく文字列バッファのような構造体で、bstr(&b)
はそのバッファの内容を文字列として取得する関数呼び出しです。gccargs.p[0]
:gccargs
はCコンパイラに渡される引数を格納する配列またはリストのような構造体で、gccargs.p[0]
はその最初の引数、つまりCコンパイラの実行ファイル名(例:"clang"
,"gcc"
,"ccache"
など)を指します。
技術的詳細
このコミットの核心は、Cコンパイラの識別ロジックの変更にあります。
変更前のコードでは、install
関数内でCコンパイラの引数を処理する際に、gccargs.p[0]
、つまりCコンパイラの実行ファイル名そのものが "clang"
を含んでいるかどうかを xstrstr
でチェックしていました。
// 変更前
if(xstrstr(gccargs.p[0], "clang") != nil) {
vadd(&gccargs, "-Wno-dangling-else");
vadd(&gccargs, "-Wno-unused-value");
}
このロジックの問題点は、CC="ccache clang"
のように設定されている場合、gccargs.p[0]
の値は "ccache"
となり、"clang"
を直接含まないため、clang
特有の警告抑制フラグが適用されませんでした。
変更後のコードでは、xstrstr
の検索対象を bstr(&b)
に変更しています。ここで bstr(&b)
は、CC
環境変数から取得された元のCコンパイラコマンドライン全体、またはその一部を表す文字列であると推測されます。つまり、"ccache clang"
という文字列全体に対して "clang"
が含まれているかをチェックするようになります。
// 変更後
if(xstrstr(bstr(&b), "clang") != nil) {
vadd(&gccargs, "-Wno-dangling-else");
vadd(&gccargs, "-Wno-unused-value");
}
これにより、CC="ccache clang"
の場合でも、bstr(&b)
が "ccache clang"
を返し、その中に "clang"
が含まれているため、条件が真となり、clang
に必要な警告抑制フラグが正しく追加されるようになります。これは、ccache
のようなラッパーを使用している場合でも、実際のコンパイラが clang
であることを正確に識別するための重要な修正です。
コアとなるコードの変更箇所
--- a/src/cmd/dist/build.c
+++ b/src/cmd/dist/build.c
@@ -586,7 +586,7 @@ install(char *dir)
splitfields(&gccargs, bstr(&b));
for(i=0; i<nelem(proto_gccargs); i++)
vadd(&gccargs, proto_gccargs[i]);
- if(xstrstr(gccargs.p[0], "clang") != nil) {
+ if(xstrstr(bstr(&b), "clang") != nil) {
vadd(&gccargs, "-Wno-dangling-else");
vadd(&gccargs, "-Wno-unused-value");
}
コアとなるコードの解説
変更は src/cmd/dist/build.c
ファイルの install
関数内、具体的には588行目で行われています。
-
変更前:
if(xstrstr(gccargs.p[0], "clang") != nil) {
ここでは、
gccargs.p[0]
、つまりCコンパイラコマンドの最初の要素(通常は実行ファイル名、例:gcc
やclang
、またはccache
)に対して、文字列"clang"
が含まれているかを検索していました。CC="ccache clang"
の場合、gccargs.p[0]
は"ccache"
となるため、この条件は偽となり、clang
特有のフラグが追加されませんでした。 -
変更後:
if(xstrstr(bstr(&b), "clang") != nil) {
変更後では、検索対象が
bstr(&b)
になっています。bstr(&b)
は、CC
環境変数から取得された元のCコンパイラコマンドライン全体(例:"ccache clang"
)を表す文字列を返します。この文字列に対して"clang"
が含まれているかを検索することで、ccache
のようなラッパーが介在していても、実際のコンパイラがclang
であることを正確に識別できるようになりました。これにより、clang
に必要な警告抑制フラグが適切に適用されるようになります。
この修正により、Goのビルドシステムは、ccache
を使用している開発環境においても、clang
コンパイラを正しく認識し、適切なコンパイラオプションを適用できるようになり、ビルドの堅牢性と互換性が向上しました。
関連リンク
- Go Gerrit Change-Id: https://golang.org/cl/5711052
参考にした情報源リンク
- Go source code on GitHub
- ccache documentation
- Clang documentation
- Go build process documentation (general) (具体的なコミット時点のドキュメントは特定できないため、一般的な情報源として)
- GCC command options (コンパイラオプションの一般的な理解のため)
- The Go Programming Language Specification (Go言語の背景知識のため)
- Go Wiki: Go on Unix (Goのビルド環境に関する一般的な情報のため)