[インデックス 19163] ファイルの概要
このコミットは、Goプロジェクトのビルドスクリプトである src/run.bash
におけるNetBSD環境でのビルド問題を修正するものです。具体的には、環境変数の参照方法のtypoを修正し、NetBSD上でのテスト実行が正しく行われるようにします。
コミット
commit 560471fbabc3a493e0271a27eb1b16dee6546c7b
Author: Shenghou Ma <minux.ma@gmail.com>
Date: Tue Apr 15 23:54:04 2014 -0400
run.bash: fix build on netbsd builders.
LGTM=bradfitz
R=golang-codereviews, bradfitz, dave
CC=golang-codereviews
https://golang.org/cl/88000044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/560471fbabc3a493e0271a27eb1b16dee6546c7b
元コミット内容
run.bash: fix build on netbsd builders.
このコミットは、run.bash
スクリプトがNetBSD環境のビルドボットで正しく動作しない問題を修正します。
変更の背景
Goプロジェクトは、様々なオペレーティングシステムとアーキテクチャの組み合わせ(OS/ARCH)で動作するように設計されており、継続的インテグレーション(CI)システムを通じてこれらの環境でのビルドとテストを自動的に行っています。run.bash
は、Goのソースコードをビルドし、テストを実行するための主要なスクリプトの一つです。
このコミットが行われた当時、NetBSD環境のビルドボット(CIシステムの一部)でビルドまたはテストが失敗する問題が発生していました。問題の原因は、run.bash
スクリプト内でGoのホストOSとアーキテクチャを組み合わせた文字列を評価する際に、環境変数の参照方法に誤りがあったためです。具体的には、$GOHOSTOS-GOARCH
という記述が意図せず GOHOSTOS
変数の値とリテラル文字列 -GOARCH
を連結してしまい、期待される GOHOSTOS-GOHOSTARCH
の組み合わせ(例: netbsd-386
)を正しく生成できていませんでした。これにより、case
文のパターンマッチングが失敗し、NetBSD固有のビルドロジックが適用されず、結果としてビルドエラーやテスト失敗につながっていました。
この修正は、GoのCIシステムがNetBSD環境で安定して動作し、GoがNetBSDプラットフォームを適切にサポートし続けるために不可欠でした。
前提知識の解説
run.bash
スクリプト
run.bash
は、Goプロジェクトのルートディレクトリにあるシェルスクリプトで、Goのツールチェインのビルド、テストの実行、および様々なプラットフォームでの動作確認を行うための主要なエントリポイントです。これは、開発者がローカルでGoをビルド・テストする際や、GoのCIシステム(ビルドボット)が自動的にビルド・テストを実行する際に利用されます。
GOHOSTOS
と GOARCH
環境変数
GOHOSTOS
: Goのツールチェインが動作しているホストオペレーティングシステムを示します。例えば、linux
、darwin
(macOS)、windows
、freebsd
、netbsd
などがあります。GOARCH
: Goのツールチェインが動作しているホストアーキテクチャを示します。例えば、amd64
、386
、arm
などがあります。
これらの環境変数は、Goのビルドプロセスにおいて、特定のOSやアーキテクチャに依存するコードパスを選択したり、クロスコンパイルのターゲットを決定したりするために広く利用されます。
シェルスクリプトにおける変数展開
Bashなどのシェルスクリプトでは、変数を参照する際に $変数名
の形式を使用します。複雑な変数名や、変数とリテラル文字列を連結する場合には、{}
を使用して変数の範囲を明示することが推奨されます。例えば、$VAR_NAME_SUFFIX
と書くと VAR_NAME_SUFFIX
という単一の変数を参照しようとしますが、${VAR_NAME}_SUFFIX
と書くと VAR_NAME
の値に _SUFFIX
という文字列を連結したものを生成します。
このコミットの文脈では、$GOHOSTOS-GOARCH
は GOHOSTOS
の値とリテラル文字列 -GOARCH
を連結してしまいます。期待されるのは GOHOSTOS
の値と GOARCH
の値をハイフンで連結した文字列(例: netbsd-amd64
)です。これを実現するには、$GOHOSTOS-$GOARCH
のように、それぞれの変数を個別に展開する必要があります。
静的リンクと動的リンク
- 静的リンク (Static Linking): プログラムが必要とするすべてのライブラリコードを、コンパイル時に実行可能ファイルに直接組み込む方式です。これにより、実行可能ファイルは自己完結型となり、外部ライブラリに依存せずに実行できます。しかし、ファイルサイズが大きくなる傾向があります。
- 動的リンク (Dynamic Linking): プログラムが必要とするライブラリコードを、実行時に外部の共有ライブラリ(例:
.so
、.dll
)からロードする方式です。これにより、実行可能ファイルのサイズを小さく保ち、複数のプログラムで同じライブラリを共有できます。しかし、実行環境に適切な共有ライブラリが存在しないとプログラムが実行できません。
Goのビルドシステムでは、go test -ldflags
オプションを使用してリンカーのフラグを渡すことができます。-linkmode=external
は外部リンカーを使用することを示し、-extldflags
はその外部リンカーに渡す追加のフラグを指定します。-static
は静的リンクを指示するリンカーフラグです。
NetBSDのような一部のシステムでは、特定の条件下(特にGoのテストスイートのような複雑なケース)で静的リンクがサポートされていない、または問題を引き起こすことがあります。そのため、run.bash
スクリプトにはNetBSD環境では静的リンクを試みないという特別なロジックが含まれていました。
技術的詳細
このコミットの技術的詳細は、シェルスクリプトにおける変数展開の正確性に集約されます。
src/run.bash
スクリプトの該当箇所では、Goのテストスイートを実行する際に、特定のOS/ARCHの組み合わせに対して特別なリンキングオプションを適用するかどうかを判断していました。
元のコード:
case "$GOHOSTOS-GOARCH" in
netbsd-386 | netbsd-amd64) ;; # no static linking
*)
go test -ldflags '-linkmode=external -extldflags "-static -pthread"' ../testtls || exit 1
この case
文は、$GOHOSTOS-GOARCH
という文字列を評価しています。ここで問題となるのは、$GOHOSTOS-GOARCH
が GOHOSTOS
環境変数の値と、リテラル文字列 -GOARCH
を連結した結果になることです。例えば、GOHOSTOS
が netbsd
で GOARCH
が amd64
の場合、この式は netbsd-GOARCH
という文字列を生成してしまいます。
これにより、netbsd-386 | netbsd-amd64
というパターンには決してマッチせず、NetBSD環境であっても常に *)
のブロック(静的リンクを試みるロジック)が実行されていました。NetBSDでは静的リンクがサポートされていない、または問題があるため、これがビルド失敗の原因となっていました。
修正後のコード:
case "$GOHOSTOS-$GOARCH" in
netbsd-386 | netbsd-amd64) ;; # no static linking
*)
go test -ldflags '-linkmode=external -extldflags "-static -pthread"' ../testtls || exit 1
修正では、$GOHOSTOS-GOARCH
を $GOHOSTOS-$GOARCH
に変更しています。これにより、GOHOSTOS
と GOARCH
の両方の環境変数が正しく展開され、それらがハイフンで連結された文字列(例: netbsd-amd64
)が生成されます。この正しい文字列が case
文のパターン netbsd-386 | netbsd-amd64
と正確にマッチするようになり、NetBSD環境では静的リンクを回避するロジックが正しく適用されるようになりました。
この修正は、Goのビルドシステムが様々なプラットフォームで堅牢に動作するための、細かではあるが重要な改善です。
コアとなるコードの変更箇所
変更は src/run.bash
ファイルの1箇所のみです。
--- a/src/run.bash
+++ b/src/run.bash
@@ -132,7 +132,7 @@ dragonfly-386 | dragonfly-amd64 | freebsd-386 | freebsd-amd64 | linux-386 | linu
go test -ldflags \'-linkmode=auto\' ../testtls || exit 1
go test -ldflags \'-linkmode=external\' ../testtls || exit 1
- case \"$GOHOSTOS-GOARCH\" in
+ case \"$GOHOSTOS-$GOARCH\" in
netbsd-386 | netbsd-amd64) ;; # no static linking
*)
go test -ldflags \'-linkmode=external -extldflags \"-static -pthread\"\' ../testtls || exit 1
コアとなるコードの解説
変更された行は、case
文の条件式です。
- 変更前:
case "$GOHOSTOS-GOARCH"
- これは
$GOHOSTOS
の値とリテラル文字列-GOARCH
を連結します。例えば、GOHOSTOS=netbsd
の場合、この式はnetbsd-GOARCH
と評価されます。
- これは
- 変更後:
case "$GOHOSTOS-$GOARCH"
- これは
$GOHOSTOS
の値と$GOARCH
の値をそれぞれ展開し、それらをハイフンで連結します。例えば、GOHOSTOS=netbsd
、GOARCH=amd64
の場合、この式はnetbsd-amd64
と評価されます。
- これは
この修正により、case
文はNetBSDの特定のアーキテクチャ(386またはamd64)に対して正しくパターンマッチングを行い、静的リンクを回避するロジックが適用されるようになりました。これにより、NetBSDビルドボットでのビルド失敗が解消されました。
関連リンク
- Go issue tracker (golang/go): https://github.com/golang/go/issues
- Go Code Review (Gerrit): https://go.dev/cl/ (このコミットのCLは
https://golang.org/cl/88000044
ですが、現在はgo.dev/cl/
にリダイレクトされます)
参考にした情報源リンク
- Goの公式ドキュメント (特にビルドと環境変数に関するセクション)
- Bashのシェルスクリプトに関するドキュメント (変数展開について)
- GoプロジェクトのGitHubリポジトリ (特に
src/run.bash
の履歴と関連するコミット) - GoのGerritコードレビューシステム (CL 88000044)
- NetBSDの静的リンクに関する一般的な情報 (必要に応じて)
- GoのCIシステムに関する情報 (Go Dashboardなど)