[インデックス 11620] ファイルの概要
このコミットは、Go言語のビルドツールである cmd/dist
におけるいくつかの修正を含んでいます。具体的には、標準出力と標準エラー出力の順序の保証と、uname -m
コマンドの出力における amd64
の認識に関する改善が行われています。
コミット
- コミットハッシュ:
650e8de0a5fab5cfa32f83dd6d16cf4cfe950fae
- 作者: Russ Cox rsc@golang.org
- 日付: 2012年2月4日 (土) 01:46:46 -0500
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/650e8de0a5fab5cfa32f83dd6d16cf4cfe950fae
元コミット内容
cmd/dist: more build fixes
Flush stdout before writing to stderr, to avoid
reordering output.
Allow amd64 from uname -m (FreeBSD).
TBR=golang-dev
CC=golang-dev
https://golang.org/cl/5629051
変更の背景
このコミットは、Go言語のビルドプロセスにおける2つの異なる問題に対処しています。
- 出力の順序の問題: プログラムが標準出力 (stdout) と標準エラー出力 (stderr) の両方に書き込む際、特にバッファリングの挙動により、出力されるメッセージの順序が意図せず入れ替わってしまうことがあります。
cmd/dist
のfatal
関数はエラーメッセージを標準エラー出力に書き込みますが、その前に標準出力に書き込まれたデータがバッファに残っていると、エラーメッセージよりも後に表示されてしまう可能性がありました。これは、ユーザーやログ解析ツールが正確なエラー発生状況を把握する上で混乱を招く可能性があります。 - アーキテクチャ検出の問題:
cmd/dist
は、ビルド対象のホストシステムのアーキテクチャをuname -m
コマンドの出力に基づいて自動的に検出します。しかし、FreeBSDなどの一部のシステムでは、amd64
アーキテクチャに対してuname -m
がamd64
という文字列を返すことがありました。従来のコードではx86_64
のみを認識していたため、amd64
と返されるシステムで正しくアーキテクチャを識別できず、ビルドが失敗する可能性がありました。
これらの問題を解決し、ビルドプロセスの堅牢性と互換性を向上させることが、このコミットの目的です。
前提知識の解説
cmd/dist
: Go言語のソースコードからGoツールチェイン自体をビルドするためのコマンドラインツールです。Goのビルドシステムの中核をなす部分であり、クロスコンパイルや異なる環境でのビルドをサポートするために、ホストシステムの情報を正確に取得する必要があります。- 標準出力 (stdout) と標準エラー出力 (stderr):
- 標準出力 (stdout): プログラムの通常の出力(結果、情報メッセージなど)が送られるストリームです。通常はコンソールに表示されます。
- 標準エラー出力 (stderr): プログラムのエラーメッセージや診断情報が送られるストリームです。これも通常はコンソールに表示されますが、stdoutとは独立してリダイレクトできるため、エラーログの収集などに利用されます。
- バッファリング: プログラムがファイルやストリームにデータを書き込む際、効率化のためにデータを一時的にメモリに蓄える(バッファリングする)ことがあります。バッファがいっぱいになるか、明示的にフラッシュされるまで、データは実際の出力先に書き込まれません。stdoutは通常行バッファリング(改行コードが出力されるまでバッファリング)またはブロックバッファリング(バッファがいっぱいになるまでバッファリング)されますが、stderrは通常バッファリングされません(または非常に小さいバッファリング)。この違いが、出力順序のずれを引き起こす原因となることがあります。
fflush(stdout)
: C言語の標準ライブラリ関数で、指定された出力ストリームのバッファを強制的にフラッシュ(内容を実際の出力先に書き出す)します。fflush(stdout)
は、標準出力のバッファに溜まっているデータを即座にコンソールなどに書き出すことを保証します。uname -m
: Unix系システムで実行されるコマンドで、システムのハードウェア名(マシンタイプ)を表示します。例えば、Intel/AMD 64ビットシステムではx86_64
やamd64
などの文字列を返します。x86_64
とamd64
: どちらも64ビットのIntel/AMD互換プロセッサアーキテクチャを指す用語です。歴史的な経緯から、Linuxなどではx86_64
が、FreeBSDなどではamd64
が使われる傾向があります。これらは実質的に同じアーキテクチャを指します。
技術的詳細
このコミットは、src/cmd/dist/unix.c
ファイル内の2つの異なる箇所に修正を加えています。
-
fatal
関数におけるfflush(stdout)
の追加:fatal
関数は、致命的なエラーが発生した際に呼び出され、エラーメッセージを標準エラー出力 (stderr
) に出力します。この修正では、fprintf(stderr, ...)
を呼び出す直前にfflush(stdout)
が追加されました。これにより、fatal
関数が呼び出される前に標準出力に書き込まれた可能性のあるすべてのデータが、エラーメッセージが出力される前に確実にフラッシュされます。これにより、エラーメッセージが他の出力に埋もれたり、順序が入れ替わったりするのを防ぎ、エラーの可視性と診断の正確性を向上させます。 -
uname -m
の出力におけるamd64
の認識:main
関数内で、ホストシステムのアーキテクチャを検出するためにuname(&u)
を呼び出し、その結果 (u.machine
) を解析しています。以前のコードでは、u.machine
がx86_64
を含む場合にのみgohostarch
をamd64
に設定していました。この修正では、x86_64
に加えてamd64
という文字列も認識するように条件が拡張されました。具体的には、contains(u.machine, "x86_64")
の条件に|| contains(u.machine, "amd64")
が追加されました。これにより、FreeBSDなどのシステムでuname -m
がamd64
を返す場合でも、Goのビルドシステムが正しくアーキテクチャをamd64
と認識し、適切なビルド設定を選択できるようになります。これは、Goのクロスプラットフォーム互換性を高める上で重要な変更です。
コアとなるコードの変更箇所
--- a/src/cmd/dist/unix.c
+++ b/src/cmd/dist/unix.c
@@ -470,6 +470,7 @@ fatal(char *msg, ...)
{
va_list arg;
+ fflush(stdout);
fprintf(stderr, "go tool dist: ");
va_start(arg, msg);
vfprintf(stderr, msg, arg);
@@ -654,7 +655,7 @@ main(int argc, char **argv)
if(gohostarch == nil) {
if(uname(&u) < 0)
fatal("uname: %s", strerror(errno));
- if(contains(u.machine, "x86_64"))
+ if(contains(u.machine, "x86_64") || contains(u.machine, "amd64"))
gohostarch = "amd64";
else if(hassuffix(u.machine, "86"))
gohostarch = "386";
コアとなるコードの解説
-
fatal
関数内の変更:+ fflush(stdout); fprintf(stderr, "go tool dist: ");
fatal
関数は、エラーメッセージを標準エラー出力 (stderr
) に書き込む前に、fflush(stdout)
を呼び出しています。これにより、標準出力 (stdout
) のバッファに保留されているデータがすべて強制的に書き出されます。この操作は、エラーメッセージが他の通常の出力よりも確実に先に表示されるようにするために重要です。もしfflush(stdout)
がなければ、stdout
のバッファリングの挙動によっては、エラーメッセージがstdout
の内容の後に表示されてしまい、ログの解析や問題の特定を困難にする可能性がありました。 -
main
関数内のアーキテクチャ検出ロジックの変更:- if(contains(u.machine, "x86_64")) + if(contains(u.machine, "x86_64") || contains(u.machine, "amd64")) gohostarch = "amd64";
この部分では、
uname -m
コマンドの出力 (u.machine
) をチェックして、ホストのアーキテクチャを特定しています。変更前はx86_64
という文字列のみを検索していましたが、変更後はx86_64
またはamd64
のいずれかの文字列が含まれていれば、gohostarch
をamd64
に設定するように修正されました。これは、FreeBSDなどの一部のオペレーティングシステムがuname -m
の出力としてamd64
を返す場合があるため、Goのビルドシステムがこれらの環境でも正しく動作するようにするための互換性向上です。
関連リンク
- Go CL 5629051: https://golang.org/cl/5629051
参考にした情報源リンク
fflush
man page: https://man7.org/linux/man-pages/man3/fflush.3.htmluname
man page: https://man7.org/linux/man-pages/man2/uname.2.html- Go
cmd/dist
source code (general context): https://github.com/golang/go/tree/master/src/cmd/dist - Standard streams (stdout, stderr): https://en.wikipedia.org/wiki/Standard_streams
- x86-64: https://en.wikipedia.org/wiki/X86-64