[インデックス 18603] ファイルの概要
このコミットは、Go言語のsyscall
パッケージ内で使用されるmkerrors.sh
スクリプトが、clang
コンパイラでも動作するように修正するものです。具体的には、スクリプト内でハードコードされていたgcc
コマンドの呼び出しを、環境変数CC
で指定されたコンパイラを使用するように変更し、CC
が設定されていない場合はデフォルトでgcc
を使用するようにフォールバックするようになります。
コミット
commit fe330cf5bb28c3e29514ce78ed4b88ba89508de7
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date: Mon Feb 24 16:34:51 2014 +0900
syscall: make mkerrors.sh work with clang
LGTM=iant
R=golang-codereviews, minux.ma, gobot, iant
CC=golang-codereviews
https://golang.org/cl/67170043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/fe330cf5bb28c3e29514ce78ed4b88ba89508de7
元コミット内容
syscall: make mkerrors.sh work with clang
このコミットは、syscall
パッケージのmkerrors.sh
スクリプトがclang
コンパイラでも正しく動作するように修正することを目的としています。
変更の背景
Go言語のビルドシステムやツールチェーンは、様々な環境やコンパイラに対応する必要があります。mkerrors.sh
スクリプトは、システムコールに関連するエラーコードやシグナル名を生成するために、Cコンパイラ(通常はgcc
)を使用してヘッダーファイルを解析していました。しかし、特定の環境や開発ワークフローでは、gcc
の代わりにclang
を使用することが一般的です。
このコミット以前は、mkerrors.sh
スクリプトがgcc
を直接呼び出すようにハードコードされていたため、clang
がデフォルトのCコンパイラとして設定されている環境では、スクリプトが期待通りに動作しない可能性がありました。この変更は、より柔軟なコンパイラ選択を可能にし、clang
を使用する開発者やビルドシステムがGoのsyscall
パッケージを問題なくビルドできるようにするために行われました。
前提知識の解説
syscall
パッケージ: Go言語の標準ライブラリの一つで、オペレーティングシステムの低レベルな機能(システムコール)にアクセスするためのインターフェースを提供します。ファイル操作、ネットワーク通信、プロセス管理など、OSに依存する多くの機能がこのパッケージを通じて実現されます。mkerrors.sh
:syscall
パッケージのビルドプロセスの一部として実行されるシェルスクリプトです。このスクリプトの主な目的は、C言語のシステムヘッダーファイル(例:<errno.h>
,<signal.h>
)を解析し、Go言語のコードから利用できるエラーコード(EACCES
,ENOENT
など)やシグナル名(SIGINT
,SIGTERM
など)の定数を自動生成することです。これにより、GoプログラムがOS固有のエラーやシグナルを適切に処理できるようになります。gcc
(GNU Compiler Collection): GNUプロジェクトによって開発された、C、C++、Objective-C、Fortran、Ada、Goなどのプログラミング言語をサポートするコンパイラ群です。Linux環境で広く利用されています。clang
: LLVMプロジェクトの一部として開発されているC、C++、Objective-C、Objective-C++コンパイラです。gcc
と比較して、より高速なコンパイル、優れたエラーメッセージ、モジュール性などの利点があります。macOSやiOS開発環境で広く採用されています。export LC_ALL=C
,export LC_CTYPE=C
: シェルスクリプトの冒頭で設定されている環境変数です。これらはロケール設定をCロケール(POSIXロケール)に強制することで、スクリプトの実行環境に依存しない安定した挙動を保証します。特に、文字列処理や正規表現の挙動がロケールによって変わることを防ぐために重要です。-x c - -E -dM
:gcc
やclang
などのCコンパイラに渡されるオプションです。-x c
: 入力ファイルの種類をC言語として扱います。-
: 標準入力から読み込むことを意味します。-E
: プリプロセスのみを実行し、コンパイルやリンクは行いません。-dM
: プリプロセッサが定義したすべてのマクロを出力します。これにより、ヘッダーファイル内で定義されている#define
マクロの情報を抽出できます。
awk
: テキスト処理を行うためのプログラミング言語です。このスクリプトでは、コンパイラの-dM
オプションの出力から、特定のマクロ定義(エラーコードやシグナル名)を抽出するために使用されています。egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)'
:egrep
(grep -E
と同じ)は拡張正規表現をサポートするgrep
コマンドです。-v
オプションは、指定されたパターンにマッチしない行を出力します。ここでは、SIGSTKSIZE
,SIGSTKSZ
,SIGRT
を含むシグナル名をフィルタリングして除外しています。これらは通常、Goのsyscall
パッケージで直接扱う必要がないか、特定のプラットフォームに依存する可能性があるためです。sort
: 行をソートするコマンドです。抽出されたエラーコードやシグナル名をアルファベット順に並べ替えるために使用されます。
技術的詳細
このコミットの核心は、mkerrors.sh
スクリプトがCコンパイラを呼び出す方法の変更にあります。
変更前は、スクリプト内でGCC=gcc
とハードコードされており、Cコンパイラの呼び出しはすべて$GCC
変数を通じて行われていました。これは、gcc
がシステムにインストールされていることを前提としており、clang
のような別のコンパイラを使用したい場合には、スクリプトを直接編集するか、gcc
へのシンボリックリンクを作成するなどの回避策が必要でした。
変更後は、CC=${CC:-gcc}
という行が追加されました。これはシェルスクリプトのパラメータ展開の機能を利用しています。
${CC:-gcc}
: 環境変数CC
が設定されている場合はその値を使用し、設定されていない(または空の)場合はデフォルト値としてgcc
を使用するという意味です。
これにより、スクリプトを実行する前にexport CC=clang
のように環境変数CC
を設定することで、mkerrors.sh
がclang
をCコンパイラとして使用するようになります。もしCC
が設定されていなければ、以前と同様にgcc
が使用されるため、後方互換性も維持されます。
スクリプト内の$GCC
のすべての出現箇所が$CC
に置き換えられています。これにより、エラーコードやシグナル名を抽出するためにCヘッダーファイルをプリプロセスする際に、ユーザーが指定した(またはデフォルトの)Cコンパイラが使用されるようになります。
この変更は、Goのビルドシステムがより柔軟になり、異なるCコンパイラ環境での互換性を向上させる上で重要です。特に、macOSのようなclang
がデフォルトのCコンパイラである環境でのGoのビルドを容易にします。
コアとなるコードの変更箇所
変更はsrc/pkg/syscall/mkerrors.sh
ファイルに集中しています。
--- a/src/pkg/syscall/mkerrors.sh
+++ b/src/pkg/syscall/mkerrors.sh
@@ -11,7 +11,7 @@ unset LANG
export LC_ALL=C
export LC_CTYPE=C
-GCC=gcc
+CC=${CC:-gcc}
uname=$(uname)
@@ -194,7 +194,7 @@ ccflags="$@"
# The gcc command line prints all the #defines
# it encounters while processing the input
- echo "${!indirect} $includes" | $GCC -x c - -E -dM $ccflags |
+ echo "${!indirect} $includes" | $CC -x c - -E -dM $ccflags |
awk '
$1 != "#define" || $2 ~ /\(/ || $3 == "" {next}
@@ -263,24 +263,24 @@ ccflags="$@"
# Pull out the error names for later.
errors=$(
- echo '#include <errno.h>' | $GCC -x c - -E -dM $ccflags |
+ echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' |
sort
)
# Pull out the signal names for later.
signals=$(
- echo '#include <signal.h>' | $GCC -x c - -E -dM $ccflags |
+ echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
sort
)
# Again, writing regexps to a file.
-echo '#include <errno.h>' | $GCC -x c - -E -dM $ccflags |
+echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print "^\t" $2 "[ \t]*=" }' |
sort >_error.grep
-echo '#include <signal.h>' | $GCC -x c - -E -dM $ccflags |
+echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
sort >_signal.grep
@@ -390,4 +390,4 @@ main(void)\n \'\n ) >_errors.c
-$GCC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out
+$CC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out
コアとなるコードの解説
-
GCC=gcc
からCC=${CC:-gcc}
への変更:- 元のコードでは、Cコンパイラとして
gcc
が直接指定されていました。 - 変更後では、環境変数
CC
が設定されていればその値を使用し、設定されていなければgcc
をデフォルトとして使用するように変更されました。これにより、ユーザーがCC
環境変数を設定することで、任意のCコンパイラ(例:clang
)を使用できるようになります。
- 元のコードでは、Cコンパイラとして
-
$GCC
から$CC
への置換:- スクリプト内でCコンパイラを呼び出しているすべての箇所(
echo ... | $GCC -x c - -E -dM ...
や$GCC $ccflags -o _errors _errors.c ...
など)で、変数名が$GCC
から$CC
に変更されました。 - これにより、
mkerrors.sh
スクリプトは、環境変数CC
で指定されたコンパイラ(またはデフォルトのgcc
)を使用して、システムヘッダーファイルの解析や中間Cファイルのコンパイルを行うようになります。
- スクリプト内でCコンパイラを呼び出しているすべての箇所(
この変更により、mkerrors.sh
はより汎用的なCコンパイララッパーとして機能し、Goのビルドシステムが異なるCコンパイラ環境(特にclang
が主流の環境)でもスムーズに動作するようになりました。
関連リンク
- Go言語の
syscall
パッケージのドキュメント: https://pkg.go.dev/syscall - Go言語の公式リポジトリ: https://github.com/golang/go
- LLVMプロジェクト (Clang): https://llvm.org/
- GNU Compiler Collection (GCC): https://gcc.gnu.org/
参考にした情報源リンク
- Go言語のソースコード (GitHub): https://github.com/golang/go
- Go言語のコードレビューシステム (Gerrit): https://go.dev/cl/67170043 (コミットメッセージに記載されているCLリンク)
- シェルスクリプトのパラメータ展開に関するドキュメント (例: Bashのmanページなど)
gcc
およびclang
のmanページ(-E
,-dM
,-x
オプションについて)awk
,grep
,sort
コマンドのmanページ- Go言語のビルドプロセスに関する一般的な情報源