Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 1907] ファイルの概要

src/cmd/gc/mkbuiltin は、Goコンパイラ(gc)のビルドプロセスの一部として使用されるシェルスクリプトです。このスクリプトの主な目的は、Go言語の組み込み関数や型定義に関するC言語のソースファイル(builtin.c.boot)を生成または更新することです。これは、コンパイラがGoの基本的な要素を認識し、型チェックなどの処理を行うために不可欠なステップです。

コミット

don't write cmp's output to the c file. cope better with p4 not found.

R=r DELTA=3 (0 added, 0 deleted, 3 changed) OCL=26877 CL=26879

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/a2cbc2998d031fb1768c8a40037c558b5411b1e8

元コミット内容

don't write cmp's output to the c file.
cope better with p4 not found.

R=r
DELTA=3  (0 added, 0 deleted, 3 changed)
OCL=26877
CL=26879

変更の背景

このコミットは、mkbuiltin スクリプトの堅牢性とクリーンな実行を向上させることを目的としています。

  1. cmp コマンドの出力問題: 以前のスクリプトでは、_builtin.cbuiltin.c.boot の2つのファイルを比較するために cmp コマンドを使用していました。cmp は、ファイルに差分がある場合にその情報を標準出力に出力します。この出力が、意図せず builtin.c.boot ファイルに書き込まれてしまう可能性がありました。これはビルドプロセスにおける望ましくない副作用であり、生成されるファイルの整合性を損なう可能性がありました。
  2. p4 コマンドの存在問題: Goプロジェクトの初期段階では、Google内部でPerforce (p4) バージョン管理システムが使用されていました。mkbuiltin スクリプトは、builtin.c.boot ファイルをPerforceで「開く」(チェックアウトする)ために p4 open コマンドを呼び出していました。しかし、Goの開発環境は多様であり、すべての開発者がPerforceクライアントをインストールしているわけではありません。p4 コマンドが見つからない場合、スクリプトはエラーで終了してしまい、ビルドプロセスが中断される問題がありました。これは、特にPerforceを使用しない開発者にとって不便でした。

これらの問題を解決し、より多くの環境でスムーズにビルドが実行できるようにするために、この変更が導入されました。

前提知識の解説

このコミットの変更内容を理解するためには、以下の技術的背景知識が役立ちます。

  • Goコンパイラ (gc): Go言語の公式コンパイラです。Goのソースコードを機械語に変換する役割を担います。mkbuiltin スクリプトは、このコンパイラのビルドプロセスの一部として機能します。
  • mkbuiltin スクリプト: Goコンパイラのビルド時に、Goの組み込み関数(例: make, new, len など)や組み込み型に関するC言語の定義を生成するスクリプトです。これらの定義は builtin.c.boot というファイルにまとめられ、コンパイラがGo言語の基本的な要素を理解するために利用されます。
  • cmp コマンド: Unix/Linuxシステムで利用されるコマンドラインユーティリティで、2つのファイルをバイト単位で比較します。ファイルが同一であれば何も出力せず、異なる場合は最初の相違点に関する情報を標準出力に出力します。
  • p4 (Perforce): Perforce Softwareが開発した集中型バージョン管理システム(VCS)です。Google内部では、Goプロジェクトの初期段階でコード管理に利用されていました。p4 open コマンドは、Perforceリポジトリ内のファイルを編集するためにチェックアウトする操作です。
  • 標準出力 (stdout) と標準エラー出力 (stderr): プログラムやコマンドが情報を出力する際の2つの主要なストリームです。
    • 標準出力: 通常の処理結果や情報が出力される場所です。
    • 標準エラー出力: エラーメッセージや診断情報が出力される場所です。
  • リダイレクト (>, 2>): シェルスクリプトにおいて、コマンドの標準出力や標準エラー出力をファイルや他のストリームに転送する機能です。
    • > /dev/null: 標準出力を /dev/null にリダイレクトします。/dev/null は「ブラックホール」のような特殊なデバイスファイルで、そこに書き込まれたデータはすべて破棄されます。これにより、コマンドの出力を完全に抑制できます。
    • 2> /dev/null: 標準エラー出力を /dev/null にリダイレクトします。
  • || true: シェルスクリプトの構文で、前のコマンドが失敗(終了ステータスが0以外)した場合でも、スクリプトの実行を継続させるために使用されます。command || true と記述すると、command が失敗しても true コマンドが実行され、その結果として全体の終了ステータスが0(成功)となるため、スクリプトは中断されません。

技術的詳細

このコミットの技術的変更は、シェルスクリプトの堅牢性と移植性を高めるための典型的なプラクティスを反映しています。

  1. cmp 出力の抑制:

    • 変更前: if ! cmp _builtin.c builtin.c.boot
    • 変更後: if ! cmp _builtin.c builtin.c.boot >/dev/null 2>/dev/null
    • cmp コマンドは、比較対象のファイルが異なる場合に標準出力にメッセージを出力します。このメッセージが、スクリプトの他の部分でファイルにリダイレクトされる可能性があったため、>/dev/null 2>/dev/null を追加して、cmp の標準出力と標準エラー出力を完全に破棄するようにしました。これにより、cmp の出力がビルドプロセスに悪影響を与えることを防ぎ、スクリプトの実行がよりクリーンになります。
  2. p4 コマンドのエラーハンドリング強化:

    • 変更前: p4 open builtin.c.boot >/dev/null
    • 変更後: p4 open builtin.c.boot >/dev/null 2>/dev/null || true
    • p4 open コマンドは、Perforceクライアントがインストールされていない場合や、その他の理由で失敗した場合にエラーを返します。変更前は、このエラーによってスクリプトが中断されていました。
    • 2>/dev/null を追加することで、p4 open の標準エラー出力も抑制し、コンソールに不要なエラーメッセージが表示されるのを防ぎます。
    • 最も重要な変更は || true の追加です。これにより、p4 open コマンドが失敗した場合でも、シェルは true コマンドを実行し、その結果として全体の終了ステータスが成功(0)と見なされます。これにより、p4 が利用できない環境でもスクリプトが中断することなく、ビルドプロセスを続行できるようになります。これは、p4 が必須ではない開発環境でのビルドの柔軟性を高めるための重要な変更です。
  3. コメントの追加:

    • PATH=$PATH:/usr/local/bin の行に # find p4 on OS X というコメントが追加されました。これは、macOS環境で p4 コマンドのパスを見つけるためのヒントであり、スクリプトの意図を明確にしています。
    • p4 open ... || true の行に # if p4 is missing, so be it というコメントが追加されました。これは、p4 が見つからない場合でも処理を続行するという設計意図を明確に示しています。

これらの変更は、スクリプトの実行時のノイズを減らし、特定の外部ツール(Perforce)への依存度を下げ、より多様な開発環境でのビルドの成功率を高めることに貢献しています。

コアとなるコードの変更箇所

--- a/src/cmd/gc/mkbuiltin
+++ b/src/cmd/gc/mkbuiltin
@@ -19,10 +19,10 @@ rm -f _builtin.c
 # in end user Go repositories.
 case "$USER" in
 ken | r | rsc)
-	if ! cmp _builtin.c builtin.c.boot
+	if ! cmp _builtin.c builtin.c.boot >/dev/null 2>/dev/null
 	then
-		PATH=$PATH:/usr/local/bin
-		p4 open builtin.c.boot >/dev/null
+		PATH=$PATH:/usr/local/bin	# find p4 on OS X
+		p4 open builtin.c.boot >/dev/null 2>/dev/null || true	# if p4 is missing, so be it
 		cp _builtin.c builtin.c.boot
 	fi
 esac

コアとなるコードの解説

  • - if ! cmp _builtin.c builtin.c.boot
    • 変更前は、_builtin.cbuiltin.c.boot を比較し、差分があれば cmp が標準出力にメッセージを出力していました。この出力が問題を引き起こす可能性がありました。
  • + if ! cmp _builtin.c builtin.c.boot >/dev/null 2>/dev/null
    • >/dev/null を追加することで、cmp コマンドの標準出力を破棄します。
    • 2>/dev/null を追加することで、cmp コマンドの標準エラー出力を破棄します。
    • これにより、cmp の出力が他のファイルに書き込まれたり、コンソールに表示されたりするのを防ぎ、スクリプトの実行をクリーンに保ちます。
  • - PATH=$PATH:/usr/local/bin
    • 変更前は、p4 コマンドを見つけるために PATH 環境変数に /usr/local/bin を追加していました。
  • + PATH=$PATH:/usr/local/bin # find p4 on OS X
    • 行末に # find p4 on OS X というコメントが追加されました。これは、このパス追加がmacOS環境で p4 を見つけるためのものであることを示唆しています。
  • - p4 open builtin.c.boot >/dev/null
    • 変更前は、builtin.c.boot をPerforceで開く(チェックアウトする)コマンドを実行し、その標準出力を破棄していました。しかし、p4 が見つからない場合やコマンドが失敗した場合、スクリプトはエラーで中断していました。
  • + p4 open builtin.c.boot >/dev/null 2>/dev/null || true # if p4 is missing, so be it
    • 2>/dev/null を追加することで、p4 open コマンドの標準エラー出力も破棄します。
    • || true を追加することで、p4 open コマンドが失敗した場合(例: p4 がインストールされていない、またはコマンドがエラーを返した場合)でも、スクリプトの実行が中断されることなく継続するようにします。これは、p4 が必須ではない環境でのビルドを可能にするための重要な変更です。
    • 行末に # if p4 is missing, so be it というコメントが追加され、p4 が見つからない場合でも処理を続行するという意図が明確にされています。

関連リンク

参考にした情報源リンク