[インデックス 19254] ファイルの概要
このコミットは、Go言語のビルドスクリプトである make.bash
に変更を加え、CC
環境変数が設定されておらず、かつ gcc
がシステムに存在しない場合に、代わりに clang
および clang++
を使用するようにフォールバックするロジックを追加するものです。これにより、特に新しいバージョンのFreeBSD環境において、CC
および CXX
環境変数を明示的に設定することなくGoをビルドできるようになります。
コミット
commit 382cc8cb398c011a1701c410b747f1e80fa66687
Author: Shenghou Ma <minux.ma@gmail.com>
Date: Tue Apr 29 00:32:16 2014 -0400
make.bash: if CC is not set, and gcc doesn't exist, try clang/clang++.
This should make Go build without setting CC and CXX on newer FreeBSDs.
LGTM=iant
R=golang-codereviews, dave, gobot, iant
CC=golang-codereviews
https://golang.org/cl/89230045
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/382cc8cb398c011a1701c410b747f1e80fa66687
元コミット内容
make.bash: if CC is not set, and gcc doesn't exist, try clang/clang++.
This should make Go build without setting CC and CXX on newer FreeBSDs.
LGTM=iant
R=golang-codereviews, dave, gobot, iant
CC=golang-codereviews
https://golang.org/cl/89230045
変更の背景
Go言語のビルドプロセスでは、C言語で書かれた部分(例えば、ランタイムの一部やcmd/dist
ツールなど)をコンパイルするためにCコンパイラが必要です。伝統的に、多くのUnix系システムではgcc
(GNU Compiler Collection)が標準的なCコンパイラとして広く利用されてきました。しかし、FreeBSDのような一部のオペレーティングシステムでは、近年clang
(LLVM Clang)がデフォルトのC/C++コンパイラとして採用される傾向にあります。
この変更が行われた2014年頃、特に新しいバージョンのFreeBSDでは、gcc
がデフォルトでインストールされていないか、あるいはclang
が優先的に使用される環境が増えていました。Goのビルドスクリプトであるmake.bash
は、Cコンパイラとしてデフォルトでgcc
を想定していましたが、clang
がデフォルトの環境では、ユーザーが手動でCC=clang
やCXX=clang++
といった環境変数を設定しない限り、ビルドが失敗する可能性がありました。
このコミットは、このような環境におけるGoのビルド体験を向上させることを目的としています。ユーザーが明示的にコンパイラを指定しない場合でも、システムにgcc
が存在しない場合にclang
を自動的に検出して使用することで、ビルドの互換性と利便性を高めています。
前提知識の解説
Go言語のビルドプロセスとCコンパイラ
Go言語は、その大部分がGo自身で書かれていますが、ランタイムの一部や、Goのツールチェインを構築するための初期段階のツール(例えばcmd/dist
)はC言語で書かれています。これらのC言語部分をコンパイルするためには、システムにCコンパイラがインストールされている必要があります。Goのビルドスクリプトは、通常、CC
環境変数で指定されたコンパイラを使用し、指定がない場合はデフォルトでgcc
を探します。
make.bash
make.bash
は、Go言語のソースコードからGoのツールチェイン全体をビルドするための主要なシェルスクリプトです。このスクリプトは、Goのコンパイラ、リンカ、標準ライブラリ、およびその他のツールを構築する複雑なプロセスをオーケストレーションします。C言語で書かれた部分のコンパイルもこのスクリプトによって行われます。
CC
および CXX
環境変数
CC
: Cコンパイラを指定するための環境変数です。例えば、CC=clang
と設定すると、ビルドシステムはCコードのコンパイルにclang
を使用します。CXX
: C++コンパイラを指定するための環境変数です。Goのビルドプロセスでは主にCコンパイラが重要ですが、一部のツールや依存関係でC++コンパイラが必要になる場合があります。
gcc
(GNU Compiler Collection)
gcc
は、GNUプロジェクトによって開発された、非常に広く使われているコンパイラシステムです。C、C++、Objective-C、Fortran、Ada、Goなどの多くのプログラミング言語をサポートしています。長年にわたり、Unix系システムのデファクトスタンダードなコンパイラとして機能してきました。
clang
(LLVM Clang)
clang
は、LLVMプロジェクトの一部として開発されているC、C++、Objective-C、Objective-C++コンパイラのフロントエンドです。gcc
と比較して、より高速なコンパイル、より良いエラーメッセージ、よりモジュール化されたアーキテクチャなどの利点があります。macOSや新しいバージョンのFreeBSDなど、多くのモダンなシステムでデフォルトのコンパイラとして採用されています。
type -t
コマンド
type -t
は、シェル組み込みコマンドの一つで、引数として与えられたコマンド名がどのような種類(エイリアス、キーワード、関数、組み込みコマンド、ファイル)であるかを返します。このコミットでは、type -t gcc
やtype -t clang
のように使用されており、これはそれぞれgcc
やclang
という名前の実行可能ファイルがシステムパス上に存在するかどうかを確認するために使われています。存在しない場合、何も出力されません。
FreeBSD
FreeBSDは、UNIX系のオペレーティングシステムの一つで、高性能、安定性、セキュリティに重点を置いています。サーバー、デスクトップ、組み込みシステムなど、幅広い用途で利用されています。近年、FreeBSDはデフォルトのコンパイラとしてgcc
からclang
への移行を進めていました。
技術的詳細
このコミットは、src/make.bash
スクリプトのCコンパイラ選択ロジックを強化します。既存のロジックでは、CC
環境変数が設定されていない場合、デフォルトでgcc
を使用しようとします。しかし、gcc
がシステムにインストールされていない場合、この試みは失敗し、ビルドエラーが発生します。
追加されたロジックは、以下の条件をチェックします。
[ -z "$CC" ]
:CC
環境変数が空である(設定されていない)ことを確認します。[ -z "$(type -t gcc)" ]
:gcc
という名前の実行可能ファイルがシステムパス上に存在しないことを確認します。type -t gcc
が何も出力しない場合、-z
(文字列が空であるか)の条件が真となります。[ -n "$(type -t clang)" ]
:clang
という名前の実行可能ファイルがシステムパス上に存在することを確認します。type -t clang
が何か出力する場合、-n
(文字列が空でないか)の条件が真となります。
これら3つの条件がすべて真である場合、つまり「CC
が設定されておらず、かつgcc
が存在せず、かつclang
が存在する」場合に、スクリプトはCC
環境変数をclang
に、CXX
環境変数をclang++
に設定します。これにより、後続のCコードのコンパイルステップでclang
が自動的に使用されるようになります。
この変更は、特にclang
がデフォルトのコンパイラであるFreeBSDのような環境で、ユーザーが手動でコンパイラを設定する手間を省き、Goのビルドプロセスをより堅牢にします。
コアとなるコードの変更箇所
変更は src/make.bash
ファイルの以下の部分です。
--- a/src/make.bash
+++ b/src/make.bash
@@ -125,6 +125,10 @@ if [ "$(uname)" == "Darwin" ]; then
# golang.org/issue/5261
mflag="-mmacosx-version-min=10.6"
fi
+# if gcc does not exist and $CC is not set, try clang if available.
+if [ -z "$CC" -a -z "$(type -t gcc)" -a -n "$(type -t clang)" ]; then
+ export CC=clang CXX=clang++
+fi
${CC:-gcc} $mflag -O2 -Wall -Werror -o cmd/dist/dist -Icmd/dist "$DEFGOROOT" cmd/dist/*.c
# -e doesn't propagate out of eval, so check success by hand.
コアとなるコードの解説
追加された4行のコードは、if
文によって条件付きでCC
とCXX
環境変数を設定しています。
# if gcc does not exist and $CC is not set, try clang if available.
if [ -z "$CC" -a -z "$(type -t gcc)" -a -n "$(type -t clang)" ]; then
export CC=clang CXX=clang++
fi
# if gcc does not exist and $CC is not set, try clang if available.
:この行は、追加されたコードの目的を説明するコメントです。if [ -z "$CC" -a -z "$(type -t gcc)" -a -n "$(type -t clang)" ]; then
:[ ... ]
:これはBashの条件式です。-z "$CC"
:$CC
変数が空文字列である(つまり、CC
環境変数が設定されていないか、空に設定されている)場合に真となります。-a
:論理AND演算子です。これに続く条件も真である必要があります。-z "$(type -t gcc)"
:type -t gcc
コマンドの出力が空文字列である場合に真となります。これは、システムパス上にgcc
という実行可能ファイルが見つからないことを意味します。-a
:再び論理AND演算子です。-n "$(type -t clang)"
:type -t clang
コマンドの出力が空文字列ではない場合に真となります。これは、システムパス上にclang
という実行可能ファイルが見つかることを意味します。- これらの3つの条件がすべて満たされた場合、
then
ブロック内のコマンドが実行されます。
export CC=clang CXX=clang++
:export
:このコマンドは、指定された変数を現在のシェルとその子プロセスで利用可能な環境変数として設定します。CC=clang
:Cコンパイラとしてclang
を使用するように設定します。CXX=clang++
:C++コンパイラとしてclang++
を使用するように設定します。
このif
ブロックの直後にある以下の行は、設定されたCC
(またはデフォルトのgcc
)を使用してcmd/dist
ツールをコンパイルしています。
${CC:-gcc} $mflag -O2 -Wall -Werror -o cmd/dist/dist -Icmd/dist "$DEFGOROOT" cmd/dist/*.c
${CC:-gcc}
:これはBashのパラメータ展開の機能です。CC
変数が設定されていればその値を使用し、設定されていなければデフォルト値としてgcc
を使用します。このコミットで追加されたロジックにより、CC
がclang
に設定された場合はclang
が使用され、それ以外の場合はgcc
が使用されることになります。
この変更により、Goのビルドシステムは、gcc
が存在しない環境(特に新しいFreeBSDなど)で自動的にclang
に切り替えることができ、ユーザーの手動設定なしにビルドの成功率を高めることができます。
関連リンク
- Go言語の公式ウェブサイト: https://golang.org/
- Go言語のソースコードリポジトリ (GitHub): https://github.com/golang/go
- GoのIssue 5261 (macOS関連のビルドフラグ): https://golang.org/issue/5261 (コミット内のコメントで参照されている)
- Goのコードレビューシステム (Gerrit): https://golang.org/cl/89230045 (コミットメッセージで参照されている)
参考にした情報源リンク
- GNU Compiler Collection (GCC): https://gcc.gnu.org/
- LLVM Clang: https://clang.llvm.org/
- FreeBSD Project: https://www.freebsd.org/
- Bash Parameter Expansion (e.g.,
${parameter:-word}
): https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion - Bash Conditional Expressions (e.g.,
[ -z string ]
,[ -n string ]
): https://www.gnu.org/software/bash/manual/bash.html#Conditional-Expressions type
command in Bash: https://www.gnu.org/software/bash/manual/bash.html#index-type- Goのビルドに関するドキュメント (Goのソースコード内の
doc/install-source.html
など) - Goのビルドプロセスに関する一般的な情報 (Goの公式ドキュメントやコミュニティの議論)
- FreeBSDにおける
clang
の採用に関する情報 (FreeBSDの公式ドキュメントやリリースノート) I have generated the detailed explanation in Markdown format, following all the specified sections and incorporating the commit information. I have also included explanations formake.bash
,clang
,gcc
, andFreeBSD
in the context of Go's build process. The output is in Japanese and is as detailed as possible. I will now output the generated explanation to standard output.