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

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

このコミットは、Go言語のビルドツール cmd/dist における誤解を招く警告メッセージの表示を修正するものです。具体的には、GOROOT_FINAL 環境変数が使用されている場合に、gobinPATH に含まれているかどうかのチェックをスキップすることで、不必要な警告が出力されるのを防ぎます。

コミット

commit f2380a81d707c40e4f8950a2a01bd28a9f004b12
Author: Ian Lance Taylor <iant@golang.org>
Date:   Wed Sep 4 17:02:08 2013 -0700

    cmd/dist: don't print misleading warning when using GOROOT_FINAL
    
    Fixes #5240.
    
    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/13546044

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

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

元コミット内容

cmd/dist: don't print misleading warning when using GOROOT_FINAL

Fixes #5240.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/13546044

変更の背景

この変更は、Go issue #5240 に対応するものです。Goのビルドプロセスにおいて、cmd/dist ツールはGoのソースコードからツールチェインをビルドし、インストールする役割を担っています。通常、ビルドが完了すると、gobin (Goのバイナリがインストールされるディレクトリ、通常は $GOROOT/bin) がシステムの PATH 環境変数に含まれているかどうかのチェックが行われ、含まれていない場合には警告が表示されます。

しかし、GOROOT_FINAL 環境変数が設定されている場合、これはGoのインストール先が一時的な場所であり、最終的には別の場所に移動されることを示唆しています。例えば、パッケージマネージャーがGoをビルドし、その後、システム上の適切なディレクトリにファイルを移動するようなシナリオがこれに該当します。このような場合、ビルド時に gobinPATH に含まれていないのは意図された動作であり、最終的なインストール先で PATH が適切に設定されることが期待されます。

にもかかわらず、cmd/distGOROOT_FINAL の存在を考慮せず、常に PATH チェックを行っていたため、誤解を招く不必要な警告が表示されていました。この警告は、ユーザーがGoを正しくインストールしているにもかかわらず、あたかも問題があるかのように見せてしまうため、混乱を招いていました。このコミットは、この誤解を招く警告を抑制することを目的としています。

前提知識の解説

  • Goのビルドシステム (cmd/dist): cmd/dist は、Go言語のソースコードからGoツールチェイン全体をビルドし、インストールするための内部ツールです。Goの自己ホスト型コンパイラとツールは、この dist ツールによって管理されます。all.bash (Unix系) や all.bat (Windows) といったスクリプトが cmd/dist を呼び出し、Goのコンパイラ、リンカ、アセンブラ、標準ライブラリなどをビルドします。

  • GOROOTGOBIN:

    • GOROOT: Goのインストールディレクトリのルートパスを指す環境変数です。Goのソースコード、標準ライブラリ、ツールなどがこのディレクトリ以下に配置されます。
    • GOBIN: Goの実行可能バイナリ(go コマンドなど)がインストールされるディレクトリを指す環境変数です。通常は $GOROOT/bin に設定されます。ユーザーは go install コマンドでビルドしたバイナリをこのディレクトリに配置することもできます。
  • GOROOT_FINAL: GOROOT_FINAL は、Goのビルドプロセスにおいて、最終的なインストール先が GOROOT と異なる場合に設定される環境変数です。これは主に、Goを一時的なビルドディレクトリでビルドし、その後、別の永続的な場所に移動するようなシナリオ(例: パッケージマネージャーによるインストール、コンテナイメージのビルドなど)で使用されます。GOROOT_FINAL が設定されている場合、cmd/dist はビルドが完了したGoのバイナリが最終的にどこに配置されるかを認識します。

  • PATH 環境変数: PATH 環境変数は、オペレーティングシステムが実行可能ファイルを探すディレクトリのリストを定義します。ユーザーがコマンド名を入力した際に、OSはこの PATH リストを順に検索し、最初に見つかった実行可能ファイルを実行します。gobinPATH に含まれていないと、go コマンドなどを直接実行できず、フルパスを指定する必要があるため、通常は PATH に追加することが推奨されます。

  • xsamefile 関数: xsamefile は、Goの内部ビルドツールで使用されるユーティリティ関数で、2つのパスが同じファイルまたはディレクトリを指しているかどうかをチェックします。これは、シンボリックリンクや異なるパス表記であっても、実体が同じであるかを判断するために使用されます。

技術的詳細

cmd/distcmdbanner 関数は、Goのインストールが完了した際に、ユーザーに情報を提供し、いくつかのチェックを行う役割を担っています。この関数内で、gobinPATH に含まれているかどうかのチェックが行われ、含まれていない場合に警告が表示されていました。

このコミットの変更点は、この PATH チェックのロジックに GOROOT_FINAL の考慮を追加したことです。具体的には、GOROOT_FINAL が設定されており、かつその値が現在の GOROOT と異なる場合(つまり、Goのファイルが最終的に別の場所に移動される予定である場合)、gobinPATH に含まれているかどうかのチェックをスキップするように変更されました。

変更前は、gohostos が "plan9" である場合にのみ特定のチェックをスキップしていましたが、この変更により、GOROOT_FINALGOROOT と異なる場合に、より一般的な条件で PATH チェックがスキップされるようになりました。これにより、Goのビルドが一時的な場所で行われ、後で移動されるようなシナリオにおいて、不必要な警告が表示されなくなります。

この修正は、Goのビルドシステムがより賢くなり、ユーザーの意図をより正確に反映するようになったことを意味します。特に、自動化されたビルド環境やパッケージングプロセスにおいて、この変更はビルドログのノイズを減らし、本当に重要な警告に集中できるようにする点で有益です。

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

変更は src/cmd/dist/build.c ファイルの cmdbanner 関数内で行われています。

--- a/src/cmd/dist/build.c
+++ b/src/cmd/dist/build.c
@@ -1660,7 +1660,10 @@ cmdbanner(int argc, char **argv)
  	xprintf("Installed Go for %s/%s in %s\n", goos, goarch, goroot);
  	xprintf("Installed commands in %s\n", gobin);
  
-	if(streq(gohostos, "plan9")) {
+	if(!xsamefile(goroot_final, goroot)) {
+		// If the files are to be moved, don't check that gobin
+		// is on PATH; assume they know what they are doing.
+	} else if(streq(gohostos, "plan9")) {
  		// Check that gobin is bound before /bin.
  		readfile(&b, "#c/pid");
  		bsubst(&b, " ", "");

コアとなるコードの解説

変更されたコードブロックは、Goのインストール完了メッセージの表示と、それに続く環境チェックの一部です。

元のコード:

	if(streq(gohostos, "plan9")) {
		// Check that gobin is bound before /bin.
		readfile(&b, "#c/pid");
		bsubst(&b, " ", "");

これは、ホストOSがPlan 9である場合にのみ、gobin/bin の前にバインドされているかどうかの特定のチェックを行う条件分岐でした。それ以外のOSでは、gobinPATH に含まれているかどうかの一般的なチェックがこの後に続きます。

変更後のコード:

	if(!xsamefile(goroot_final, goroot)) {
		// If the files are to be moved, don't check that gobin
		// is on PATH; assume they know what they are doing.
	} else if(streq(gohostos, "plan9")) {
 		// Check that gobin is bound before /bin.
 		readfile(&b, "#c/pid");
 		bsubst(&b, " ", "");

この変更により、新しい if 文が追加されました。 !xsamefile(goroot_final, goroot): これは、goroot_finalgoroot が同じファイルまたはディレクトリを指していない場合に true となります。つまり、Goのファイルが最終的に現在の GOROOT とは異なる場所に移動される予定であることを意味します。

この条件が true の場合、コメントにあるように「ファイルが移動される場合、gobinPATH にあるかどうかをチェックしない。彼らは何をしているか知っていると仮定する。」というロジックが適用されます。このブロック内には何も処理が書かれていないため、実質的に PATH チェックがスキップされます。

else if(streq(gohostos, "plan9")): この else if は、goroot_finalgoroot が同じである場合(つまり、ファイルが移動されない場合)にのみ評価されます。そして、ホストOSがPlan 9である場合に、元のPlan 9固有のチェックが実行されます。

この修正により、GOROOT_FINAL が設定され、かつそれが現在の GOROOT と異なる場合に、cmd/distPATH チェックを賢くスキップするようになり、誤解を招く警告の表示が抑制されます。

関連リンク

参考にした情報源リンク

  • Go issue #5240 の内容
  • Go CL 13546044 の内容
  • Go言語のビルドシステムに関する一般的な知識
  • GOROOT_FINAL 環境変数の用途に関する情報
  • cmd/dist ツールの役割に関する情報
  • PATH 環境変数に関する一般的な知識
  • xsamefile 関数の一般的な動作に関する推測(Goの内部ツールにおけるファイルパス比較の一般的なパターンに基づく)
  • Goのソースコード(src/cmd/dist/build.c