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

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

このコミットは、Go言語のビルドシステムにおけるPlan 9オペレーティングシステム向けの特定の調整と、ビルドスクリプト(.rcファイル)の同期を目的としています。特に、Plan 9環境でのGOBIN(Goバイナリのインストールディレクトリ)の設定方法の変更と、make.bashなどの他のビルドスクリプトで行われた変更との整合性を図るための.rcファイルの更新が含まれています。

コミット

commit f08acae76e8a66a5fe245fd5c6948de8add04257
Author: Anthony Martin <ality@pbrane.org>
Date:   Tue Feb 26 09:25:46 2013 -0800

    build: do not set GOBIN on Plan 9
    
    Also, I synced the rc files with changes
    that have been made to make.bash, etc.
    
    R=seed, rminnich, r
    CC=golang-dev
    https://golang.org/cl/7389049

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

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

元コミット内容

build: do not set GOBIN on Plan 9

Also, I synced the rc files with changes
that have been made to make.bash, etc.

変更の背景

このコミットの主な背景は、Go言語のビルドプロセスにおけるPlan 9オペレーティングシステム特有の要件への対応です。

  1. Plan 9におけるGOBINの扱い: Go言語のビルドシステムは、通常、コンパイルされたバイナリをGOBIN環境変数で指定されたディレクトリにインストールします。しかし、Plan 9のような特定の環境では、ファイルシステムの構造やプログラムの実行モデルが他のUnix系システムと異なるため、GOBINの自動設定が問題を引き起こす可能性がありました。このコミットは、Plan 9環境ではGOBINを明示的に設定しないようにすることで、この問題を解決しようとしています。これは、Plan 9の慣習やファイルシステム設計に合わせた調整と考えられます。

  2. ビルドスクリプトの同期: Goプロジェクトのビルドスクリプトは、様々なプラットフォームやビルドシナリオに対応するために進化しています。make.bashのようなBashスクリプトと、Plan 9向けの.rcスクリプト(Plan 9のシェルであるrc用のスクリプト)は、機能的に同等であるべきですが、時間の経過とともに差異が生じることがあります。このコミットは、これらのスクリプト間の同期を取り、一貫したビルド動作を保証することを目的としています。これにより、異なる環境でのビルドの信頼性と予測可能性が向上します。

  3. Plan 9環境でのテストの安定性向上: GOMAXPROCSテストのタイムアウト時間の延長や、vx32(Plan 9の仮想化環境)での並列処理の制限など、Plan 9環境でのテストの安定性と信頼性を向上させるための調整も含まれています。これは、リソースの制約や特定のシステム動作に起因するテストの失敗を減らすためのものです。

前提知識の解説

このコミットを理解するためには、以下の概念に関する知識が役立ちます。

  • Go言語のビルドシステム: Go言語は、go buildgo installといったコマンドを通じて、ソースコードからバイナリを生成し、インストールする独自のビルドシステムを持っています。このシステムは、環境変数(GOROOT, GOPATH, GOBIN, GOOS, GOARCHなど)に大きく依存しています。
    • GOROOT: GoのSDKがインストールされているルートディレクトリ。
    • GOPATH: Goのワークスペースディレクトリ。Goのソースコード、パッケージ、バイナリが配置されます。
    • GOBIN: go installコマンドで生成された実行可能バイナリがインストールされるディレクトリ。通常はGOPATH/binまたはGOROOT/binに設定されます。
  • Plan 9: ベル研究所で開発された分散オペレーティングシステムです。Unixとは異なる設計思想を持ち、特に「すべてがファイルである」という原則を徹底し、リソースをファイルシステムとして表現します。
    • rcシェル: Plan 9の標準シェルです。UnixのBourne Shellとは異なる構文と機能を持っています。.rcファイルはrcシェルスクリプトです。
    • rforkシステムコール: Plan 9におけるプロセス作成の主要なメカニズムです。Unixのforkとは異なり、新しいプロセスが親プロセスのどのリソース(ファイルディスクリプタ、名前空間、環境変数など)を共有またはコピーするかを細かく制御できます。
      • rfork n: 新しい名前空間(ファイルシステムツリー)を作成します。
      • rfork e: 新しい環境変数セットを作成します。
    • vx32: Plan 9がx86アーキテクチャ上で動作するための仮想化環境、またはPlan 9のユーザーモード環境を指すことがあります。
  • CGO_ENABLED: Goのビルド時にC言語との連携(cgo)を有効にするかどうかを制御する環境変数です。1に設定するとcgoが有効になり、0に設定すると無効になります。
  • go tool dist: Goのビルドシステム内部で使用されるツールで、Goの配布(distribution)に関連する操作を行います。
  • go env: Goの環境変数を表示するコマンドです。
  • GOMAXPROCS: Goランタイムが同時に実行できるOSスレッドの最大数を制御する環境変数です。並列処理のテストでよく使用されます。

技術的詳細

このコミットは、GoのビルドプロセスにおけるPlan 9固有の挙動を調整し、ビルドスクリプトの整合性を高めるための複数の変更を含んでいます。

  1. GOBINの自動設定の無効化 (src/cmd/dist/plan9.c):

    • 以前のコードでは、plan9.c内のmain関数で、GOBIN環境変数が設定されていない場合に、/$objtype/bin(例: /amd64/bin)というパスをGOBINとして自動的に設定していました。
    • このコミットでは、このGOBINの自動設定ロジックが完全に削除されています。これは、Plan 9のファイルシステム階層や、バイナリの配置に関する慣習が他のOSと異なるため、GoのビルドシステムがGOBINを自動的に設定するのではなく、ユーザーやシステムが明示的に管理することを意図していると考えられます。Plan 9では、通常、実行可能ファイルは/bin/rc/binのような標準的な場所に配置され、PATHを通じてアクセスされることが多いため、Goが独自のGOBINを設定する必要がない、あるいは望ましくないという判断があった可能性があります。
  2. rcスクリプトの同期と改善:

    • src/all.rc: rfork nが追加されました。これは、all.rcが実行される際に新しい名前空間を作成することを意味します。これにより、スクリプトの実行が既存のファイルシステムツリーに影響を与えにくくなり、よりクリーンな環境でビルドプロセスを開始できるようになります。
    • src/make.rc:
      • CGO_ENABLEDに関するコメントが更新され、その機能がより明確に説明されています。これは、cgoがビルドに含まれる.cファイルや"cgo"ビルドディレクティブを持つ.goファイルをどのように扱うかを説明しています。
      • rm -rf ./pkg/runtime/runtime_defs.gorm -f ./pkg/runtime/runtime_defs.goに変更されました。-rfはディレクトリを再帰的に削除するオプションですが、runtime_defs.goはファイルであるため、-f(強制削除)で十分であり、より安全な変更です。
      • if(! test -f run.bash)if(! test -f run.rc)に変更されました。これは、Plan 9環境でmake.rcが実行される際に、run.rcファイルの存在を確認するように修正されたもので、ビルドスクリプト間の整合性を保つための変更です。
      • if(~ $sysname vx32)ブロックが追加され、vx32環境(Plan 9 on x86)ではpflag = (-p 1)が設定されるようになりました。これは、go installコマンドに-p 1フラグを渡すことを意味し、並列ビルドを1に制限します。vx32のようなリソースが限られた環境や、特定の同期問題がある環境では、並列処理を制限することでビルドの安定性を向上させることができます。
      • GO_CCFLAGSgo_bootstrap installコマンドに追加されました。これにより、Cコンパイラ(5c/6c/8cなど)に追加のフラグを渡すことができるようになり、ビルドの柔軟性が向上します。
    • src/run.rc:
      • rfork eが追加されました。これは、run.rcが実行される際に新しい環境変数セットを作成することを意味します。これにより、スクリプトの実行が既存の環境変数に影響を与えにくくなり、より予測可能な環境でテストや実行が行えるようになります。
      • eval {go tool dist env -9}eval {go env}に変更されました。これは、Goの環境変数を取得する際に、古いgo tool dist env -9コマンドではなく、より標準的で新しいgo envコマンドを使用するように更新されたものです。
      • GOPATH = ()が設定されました。これは、ローカルパッケージ以外のローカルインポートを禁止するための措置です。GOROOTGOPATHの下にある場合に一部のテストが失敗するのを防ぐ目的があります。
      • vx32環境でのpflag = (-p 1)の設定がgo installコマンドにも適用されました。
      • GOROOT_FINAL = ()がテストの前にアンセットされるようになりました。これは、runtime/debugパッケージがソースコードへの正しいアクセスを必要とするため、GOROOT_FINALが有効になっているとテストが失敗する可能性があるためです。GOROOT_FINALは、Goの最終的なインストールパスを示すことがあり、これが設定されていると、ソースコードのパス解決に影響を与える可能性があります。
      • GOMAXPROCS=2 go test runtime -short -timeout 120s -cpu 1,2,4のタイムアウトが240sに延長されました。これは、runtimeパッケージのテスト、特にGOMAXPROCSを操作するテストが、Plan 9環境で完了するのに時間がかかる場合があるため、タイムアウトによる失敗を防ぐための調整です。

これらの変更は、Go言語がPlan 9のような多様なオペレーティングシステムで安定して動作し、ビルドおよびテストプロセスが堅牢であることを保証するための継続的な努力の一環です。

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

このコミットにおける主要なコード変更は以下のファイルに集中しています。

  • src/all.rc
  • src/cmd/dist/plan9.c
  • src/make.rc
  • src/run.rc

src/cmd/dist/plan9.c の変更

--- a/src/cmd/dist/plan9.c
+++ b/src/cmd/dist/plan9.c
@@ -700,12 +700,6 @@ main(int argc, char **argv)
 	tfatal("$objtype is unset");
 	gohostarch = btake(&b);
 
-	txgetenv(&b, "GOBIN");
-	if(b.len == 0){
-		bpathf(&b, "/%s/bin", gohostarch);
-		txsetenv("GOBIN", bstr(&b));
-	}
-
 	srand(time(0)+getpid());
 	init();
 	xmain(argc, argv);

src/make.rc の変更

--- a/src/make.rc
+++ b/src/make.rc
@@ -23,17 +23,21 @@
 # GO_LDFLAGS: Additional 5l/6l/8l arguments to use when
 # building the commands.
 #
-# CGO_ENABLED: Setting this to 0 disables the use of cgo
-# in the built and installed packages and tools.
+# GO_CCFLAGS: Additional 5c/6c/8c arguments to use when
+# building.
+#
+# CGO_ENABLED: Controls cgo usage during the build. Set it to 1
+# to include all cgo related files, .c and .go file with "cgo"
+# build directive, in the build. Set it to 0 to ignore them.
 
 rfork e
-if(! test -f run.bash){
+if(! test -f run.rc){
 	echo 'make.rc must be run from $GOROOT/src' >[1=2]
 	exit wrongdir
 }
 
 # Clean old generated file that will cause problems in the build.
-rm -rf ./pkg/runtime/runtime_defs.go
+rm -f ./pkg/runtime/runtime_defs.go
 
 # Determine the host compiler toolchain.
 eval `{grep '^(CC|LD|O)=' /$objtype/mkfile}
@@ -72,17 +76,19 @@ mv cmd/dist/dist $GOTOOLDIR/dist
 $GOTOOLDIR/go_bootstrap clean -i std
 echo
 
-# TODO(ality): remove the -p flag once the exec/await/RFNOTEG race is fixed.
+# Run only one process at a time on 9vx.
+if(~ $sysname vx32)
+\tpflag = (-p 1)
 
 if(! ~ $GOHOSTARCH $GOARCH || ! ~ $GOHOSTOS $GOOS){
 	echo '# Building packages and commands for host,' $GOHOSTOS/$GOHOSTARCH^.
 	GOOS=$GOHOSTOS GOARCH=$GOARCH \
-		$GOTOOLDIR/go_bootstrap install -gcflags $"GO_GCFLAGS -ldflags $"GO_LDFLAGS -v -p 1 std
+		$GOTOOLDIR/go_bootstrap install -ccflags $"GO_CCFLAGS -gcflags $"GO_GCFLAGS -ldflags $"GO_LDFLAGS -v $pflag std
 	echo
 }
 
 echo '# Building packages and commands for' $GOOS/$GOARCH^.
-$GOTOOLDIR/go_bootstrap install -gcflags $"GO_GCFLAGS -ldflags $"GO_LDFLAGS -v -p 1 std
+$GOTOOLDIR/go_bootstrap install -ccflags $"GO_CCFLAGS -gcflags $"GO_GCFLAGS -ldflags $"GO_LDFLAGS -v $pflag std
 echo
 
 rm -f $GOTOOLDIR/go_bootstrap

src/run.rc の変更

--- a/src/run.rc
+++ b/src/run.rc
@@ -3,24 +3,37 @@
 # Use of this source code is governed by a BSD-style
 # license that can be found in the LICENSE file.
 
-eval `{go tool dist env -9}
+rfork e
+
+eval `{go env}
+
+GOPATH = () # we disallow local import for non-local packges, if $GOROOT happens
+            # to be under $GOPATH, then some tests below will fail
 
 # allow all.rc to avoid double-build of everything
 rebuild = true
 if(~ $1 --no-rebuild)
 	shift
 if not {
+\t# Run only one process at a time on 9vx.
+\tif(~ $sysname vx32)
+\t\tpflag = (-p 1)
 \techo '# Building packages and commands.'
-\ttime go install -a -v -p 1 std
+\ttime go install -a -v $pflag std
 \techo
 }
 
+# we must unset GOROOT_FINAL before tests, because runtime/debug requires
+# correct access to source code, so if we have GOROOT_FINAL in effect,
+# at least runtime/debug test will fail.
+GOROOT_FINAL = ()
+
 echo '# Testing packages.'
 time go test std -short -timeout 120s
 echo
 
 echo '# GOMAXPROCS=2 runtime -cpu=1,2,4'
-GOMAXPROCS=2 go test runtime -short -timeout 120s -cpu 1,2,4
+GOMAXPROCS=2 go test runtime -short -timeout 240s -cpu 1,2,4
 echo
 
 echo '# sync -cpu=10'

コアとなるコードの解説

src/cmd/dist/plan9.c の変更点

このファイルは、Goのビルドツールチェーンの一部であり、特にPlan 9環境でのGoの配布(dist)ツールに関連するC言語のコードを含んでいます。

削除されたコードブロックは、GOBIN環境変数が設定されていない場合に、gohostarch(例: amd64)に基づいてGOBINのパスを自動的に構築し、設定していました。

txgetenv(&b, "GOBIN");
if(b.len == 0){
    bpathf(&b, "/%s/bin", gohostarch);
    txsetenv("GOBIN", bstr(&b));
}

このコードが削除されたことにより、Plan 9環境ではGoのビルドプロセスがGOBINを自動的に設定しなくなります。これは、Plan 9のファイルシステム構造や、バイナリの配置に関する慣習が他のOSと異なるため、Goが独自のGOBINを設定するのではなく、ユーザーやシステムが明示的に管理することを意図していると考えられます。Plan 9では、通常、実行可能ファイルは/bin/rc/binのような標準的な場所に配置され、PATHを通じてアクセスされることが多いため、Goが独自のGOBINを設定する必要がない、あるいは望ましくないという判断があった可能性があります。

src/make.rc の変更点

このファイルは、Goのビルドプロセスを制御するPlan 9のrcシェルスクリプトです。

  1. CGO_ENABLEDコメントの更新: 以前のコメントはCGO_ENABLED0の場合にcgoを無効にするとだけ述べていましたが、新しいコメントはCGO_ENABLED1の場合にcgo関連ファイル(.cファイルや"cgo"ビルドディレクティブを持つ.goファイル)をビルドに含めることを明確にしています。これにより、CGO_ENABLEDの動作がより正確に伝わります。

  2. rm -rf から rm -f への変更: rm -rf ./pkg/runtime/runtime_defs.gorm -f ./pkg/runtime/runtime_defs.goに変更されました。runtime_defs.goはファイルでありディレクトリではないため、再帰的な削除オプション-rは不要です。-f(強制削除)で十分であり、より意図が明確で安全な変更です。

  3. run.bash から run.rc への変更: if(! test -f run.bash)if(! test -f run.rc)に変更されました。これは、Plan 9環境でmake.rcが実行される際に、run.rcファイルの存在を確認するように修正されたもので、ビルドスクリプト間の整合性を保つための変更です。

  4. vx32 環境での並列ビルド制限:

    if(~ $sysname vx32)
    \tpflag = (-p 1)
    

    このコードブロックは、システム名がvx32(Plan 9の仮想化環境またはユーザーモード環境)である場合に、pflag変数を(-p 1)に設定します。このpflagは、後続のgo_bootstrap installコマンドに渡され、並列ビルドの数を1に制限します。vx32のようなリソースが限られた環境や、特定の同期問題がある環境では、並列処理を制限することでビルドの安定性を向上させることができます。

  5. GO_CCFLAGS の追加: go_bootstrap installコマンドに-ccflags $"GO_CCFLAGS"が追加されました。これにより、Cコンパイラ(5c/6c/8cなど)に追加のフラグを渡すことができるようになり、ビルドの柔軟性が向上します。これは、特定のコンパイラオプションが必要な場合や、デバッグ情報を追加する場合などに有用です。

src/run.rc の変更点

このファイルは、Goのテスト実行を制御するPlan 9のrcシェルスクリプトです。

  1. rfork e の追加: rfork eがスクリプトの冒頭に追加されました。これは、run.rcが実行される際に新しい環境変数セットを作成することを意味します。これにより、スクリプトの実行が既存の環境変数に影響を与えにくくなり、より予測可能な環境でテストや実行が行えるようになります。

  2. go tool dist env -9 から go env への変更: eval {go tool dist env -9}eval {go env}に変更されました。これは、Goの環境変数を取得する際に、古いgo tool dist env -9コマンドではなく、より標準的で新しいgo envコマンドを使用するように更新されたものです。これにより、スクリプトが最新のGoツールチェーンと互換性を持つようになります。

  3. GOPATH = () の設定: GOPATH = ()が設定されました。これは、ローカルパッケージ以外のローカルインポートを禁止するための措置です。コメントにもあるように、GOROOTGOPATHの下にある場合に一部のテストが失敗するのを防ぐ目的があります。Goのモジュールシステムが導入される前の時代では、GOPATHの管理は重要でした。

  4. vx32 環境での並列テスト制限: make.rcと同様に、vx32環境ではpflag = (-p 1)が設定され、go installコマンドに渡されます。これにより、テストのビルドステップも並列処理が1に制限され、安定性が向上します。

  5. GOROOT_FINAL のアンセット:

    # we must unset GOROOT_FINAL before tests, because runtime/debug requires
    # correct access to source code, so if we have GOROOT_FINAL in effect,
    # at least runtime/debug test will fail.
    GOROOT_FINAL = ()
    

    テストの前にGOROOT_FINAL環境変数がアンセットされるようになりました。GOROOT_FINALは、Goの最終的なインストールパスを示すことがあり、これが設定されていると、runtime/debugパッケージがソースコードへの正しいアクセスを必要とする際に問題を引き起こす可能性があります。この変更により、テストがソースコードを正しく参照できるようになり、テストの信頼性が向上します。

  6. GOMAXPROCS テストのタイムアウト延長: GOMAXPROCS=2 go test runtime -short -timeout 120s -cpu 1,2,4のタイムアウトが240sに延長されました。これは、runtimeパッケージのテスト、特にGOMAXPROCSを操作するテストが、Plan 9環境で完了するのに時間がかかる場合があるため、タイムアウトによる失敗を防ぐための調整です。

これらの変更は、Go言語がPlan 9のような多様なオペレーティングシステムで安定して動作し、ビルドおよびテストプロセスが堅牢であることを保証するための継続的な努力の一環です。特に、Plan 9の独特なシステムコールや環境変数の扱いに合わせた調整が顕著です。

関連リンク

参考にした情報源リンク