[インデックス 14545] ファイルの概要
このコミットは、Go言語のビルドシステムがDebian GNU/kFreeBSD環境をサポートするための変更を導入しています。具体的には、cmd/dist
ツールがkFreeBSDをFreeBSDとして認識するように修正し、make.bash
スクリプトがkFreeBSD環境でCgoを自動的に無効化するよう調整されています。これにより、Debian GNU/kFreeBSD上でのGoのビルドが可能になります。
コミット
commit 3167c12eb2bea4c96ccb0308159925d5f4e8cd21
Author: Dave Cheney <dave@cheney.net>
Date: Tue Dec 4 08:27:30 2012 +1100
cmd/dist: support building on debian/kFreeBSD
The debian/kFreeBSD project uses the FreeBSD kernel and the debian userspace. From our point of view, this is freebsd not linux as GOOS talks about the kernel syscall interface, not the userspace (although cgo alters that). As debian/kFreeBSD is experimental at this time, I do not think it is worth the effort of duplicating all the freebsd specific code so this is proposal represents a reasonable workaround.
Currently cgo is not supported, make.bash will detect this and disable cgo automatically during the build.
dfc@debian:~/go/src$ uname -a
GNU/kFreeBSD debian 8.1-1-686 #0 Sat Jul 21 17:02:04 UTC 2012 i686 i386 Intel(R) Core(TM) i5-2415M CPU @ 2.30GHz GNU/kFreeBSD
dfc@debian:~/go/src$ ../bin/go version
go version devel +d05272f402ec Sat Dec 01 15:15:14 2012 -0800
Tested with GOOS=freebsd GOARCH=386
R=golang-dev
CC=golang-dev
https://golang.org/cl/6868046
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/3167c12eb2bea4c96ccb0308159925d5f4e8cd21
元コミット内容
このコミットは、Goのビルドツールであるcmd/dist
とビルドスクリプトであるmake.bash
を修正し、Debian GNU/kFreeBSD環境でのGoのビルドをサポートします。
主な変更点は以下の通りです。
src/cmd/dist/unix.c
において、__FreeBSD_kernel__
マクロが定義されている場合に、ホストOSをfreebsd
として認識するように変更。これはDebian GNU/kFreeBSDをFreeBSDカーネルとして扱うためです。src/make.bash
において、uname -s
コマンドの出力がGNU/kFreeBSD
である場合に、環境変数CGO_ENABLED
を0
に設定し、Cgoを無効化するように変更。これは、現在のところkFreeBSD環境でCgoがサポートされていないためです。
変更の背景
Go言語は、様々なオペレーティングシステムとアーキテクチャの組み合わせ(GOOS
/GOARCH
)をサポートするように設計されています。しかし、Debian GNU/kFreeBSDのような特定のニッチな環境では、Goのビルドシステムがその特性を正しく認識できない場合がありました。
Debian GNU/kFreeBSDは、DebianのユーザーランドとFreeBSDのカーネルを組み合わせたオペレーティングシステムです。Goのビルドシステムにおいて、GOOS
(Go Operating System)は主にカーネルのシステムコールインターフェースを指します。そのため、kFreeBSDはユーザーランドがDebian(Linuxライク)であっても、カーネルがFreeBSDであるため、Goの観点からはfreebsd
として扱われるべきです。
このコミットが作成された2012年当時、Debian GNU/kFreeBSDはまだ実験的な段階であり、Goのビルドシステムがこの環境をネイティブにサポートするための包括的な変更を加えることは、労力に見合わないと判断されました。そこで、既存のFreeBSD関連のコードを重複させることなく、最小限の変更でビルドを可能にする「合理的な回避策」が提案されました。
また、Cgo(GoとC言語の相互運用機能)は、kFreeBSD環境では当時サポートされていませんでした。そのため、ビルドプロセス中にCgoが自動的に無効化されるようにする必要がありました。
これらの背景から、cmd/dist
でのOS認識の修正と、make.bash
でのCgo無効化のロジックが導入されました。
前提知識の解説
Go言語のビルドシステムとクロスコンパイル
Go言語は、GOOS
とGOARCH
という環境変数を用いて、ターゲットとなるオペレーティングシステムとアーキテクチャを指定し、クロスコンパイルを容易に行うことができます。
GOOS
: Goが実行されるオペレーティングシステム(例:linux
,windows
,darwin
,freebsd
など)。Goのビルドシステムは、この値に基づいて適切なシステムコールインターフェースやライブラリを選択します。GOARCH
: Goが実行されるCPUアーキテクチャ(例:amd64
,386
,arm
など)。
Debian GNU/kFreeBSD
Debian GNU/kFreeBSDは、Debianプロジェクトによって開発されたオペレーティングシステムの一つです。通常のDebianがLinuxカーネルを使用するのに対し、Debian GNU/kFreeBSDはFreeBSDカーネルを使用し、その上にDebianのGNUユーザーランド(GNUツールチェイン、aptパッケージ管理システムなど)を構築しています。これにより、FreeBSDカーネルの安定性や機能と、Debianの豊富なソフトウェアパッケージを組み合わせたシステムが実現されています。
Cgo
Cgoは、GoプログラムからC言語のコードを呼び出したり、C言語のコードからGoの関数を呼び出したりするためのGoの機能です。Cgoを使用すると、既存のCライブラリをGoプロジェクトに統合したり、パフォーマンスが重要な部分をCで記述したりすることができます。Cgoを有効にするには、環境変数CGO_ENABLED
を1
に設定します(デフォルトは1
)。Cgoを使用するプログラムをビルドするには、Cコンパイラ(通常はGCCやClang)が必要です。
cmd/dist
cmd/dist
は、GoのソースコードからGoツールチェイン自体をビルドするために使用される内部ツールです。Goのブートストラッププロセスにおいて重要な役割を果たし、Goのコンパイラ、リンカ、その他のツールを生成します。このツールは、ビルド環境のOSやアーキテクチャを検出し、それに基づいてビルドプロセスを調整します。
make.bash
make.bash
は、Goのソースツリーのルートにあるシェルスクリプトで、Goのツールチェイン全体をビルドするための主要なスクリプトです。このスクリプトは、環境変数の設定、依存関係のチェック、cmd/dist
の呼び出し、テストの実行など、ビルドプロセスの様々な段階をオーケストレーションします。
技術的詳細
このコミットの技術的詳細は、Goのビルドシステムがどのように異なるOS環境を識別し、それに応じて動作を調整するかという点に集約されます。
-
OS識別のロジック (
src/cmd/dist/unix.c
):cmd/dist
は、C言語で書かれており、コンパイル時に利用可能なプリプロセッサマクロ(#define
)を利用して、実行されているホストOSを識別します。- 従来のGoのビルドシステムでは、
__FreeBSD__
が定義されていればfreebsd
、__linux__
が定義されていればlinux
と認識していました。 - Debian GNU/kFreeBSDの場合、カーネルはFreeBSDですが、ユーザーランドはDebianです。Cコンパイラによっては、
__FreeBSD_kernel__
というマクロが定義されることがあります。このコミットでは、このマクロを検出することで、Debian GNU/kFreeBSDをGoのGOOS
としてはfreebsd
として扱うように明示的に指定しています。これは、GoのGOOS
がカーネルのシステムコールインターフェースを指すという設計思想に合致しています。
-
Cgoの無効化 (
src/make.bash
):make.bash
スクリプトは、ビルドプロセスの初期段階で環境をセットアップします。uname -s
コマンドは、システムのカーネル名を返します。Debian GNU/kFreeBSDシステムでは、このコマンドはGNU/kFreeBSD
という文字列を返します。- スクリプトは、この文字列をチェックし、もし
GNU/kFreeBSD
であれば、export CGO_ENABLED=0
を実行します。これにより、Goのビルドシステム全体でCgoが無効化され、Cgoに依存するパッケージのビルドがスキップされるか、Cgoなしでビルドされるようになります。これは、kFreeBSD環境でのCgoの未サポートという制約に対応するためのものです。
これらの変更により、GoのビルドシステムはDebian GNU/kFreeBSD環境を正しく識別し、Cgoの制約を考慮した上で、Goのツールチェインを正常にビルドできるようになります。
コアとなるコードの変更箇所
src/cmd/dist/unix.c
--- a/src/cmd/dist/unix.c
+++ b/src/cmd/dist/unix.c
@@ -670,6 +670,10 @@ main(int argc, char **argv)
gohostos = "linux";
#elif defined(__FreeBSD__)
gohostos = "freebsd";
+#elif defined(__FreeBSD_kernel__)
+ // detect debian/kFreeBSD.
+ // http://wiki.debian.org/Debian_GNU/kFreeBSD_FAQ#Q._How_do_I_detect_kfreebsd_with_preprocessor_directives_in_a_C_program.3F
+ gohostos = "freebsd";
#elif defined(__OpenBSD__)
gohostos = "openbsd";
#elif defined(__NetBSD__)
src/make.bash
--- a/src/make.bash
+++ b/src/make.bash
@@ -77,6 +77,13 @@ do
fi
done
+# Test for debian/kFreeBSD.
+# cmd/dist will detect kFreeBSD as freebsd/$GOARCH, but we need to
+# disable cgo manually.
+if [ "$(uname -s)" == "GNU/kFreeBSD" ]; then
+ export CGO_ENABLED=0
+fi
+
# Clean old generated file that will cause problems in the build.
rm -f ./pkg/runtime/runtime_defs.go
コアとなるコードの解説
src/cmd/dist/unix.c
の変更
このC言語のコードスニペットは、cmd/dist
がホストOSを識別する部分です。
#elif defined(__FreeBSD_kernel__)
という行が追加されています。これはCプリプロセッサのディレクティブで、コンパイル時に__FreeBSD_kernel__
というマクロが定義されているかどうかをチェックします。- Debian GNU/kFreeBSD環境でコンパイルされる場合、このマクロが定義されることが期待されます。
- この条件が真であれば、
gohostos = "freebsd";
が実行され、GoのビルドシステムはホストOSをfreebsd
として扱います。 - コメントには、Debian GNU/kFreeBSDの検出方法に関するFAQへのリンクが記載されており、この変更の意図が明確に示されています。
src/make.bash
の変更
このシェルスクリプトの変更は、Goのビルドプロセス全体に影響を与えます。
if [ "$(uname -s)" == "GNU/kFreeBSD" ]; then
という条件文が追加されています。uname -s
コマンドは、システムのカーネル名を出力します。Debian GNU/kFreeBSDシステムでは、この出力は正確にGNU/kFreeBSD
となります。- この条件が真(つまり、現在のシステムがDebian GNU/kFreeBSDである)の場合、
export CGO_ENABLED=0
が実行されます。
export CGO_ENABLED=0
は、環境変数CGO_ENABLED
を0
に設定します。これにより、GoのビルドシステムはCgoを使用しないモードで動作し、Cgoに依存するすべてのGoパッケージがCgoなしでビルドされるか、Cgoが必須のパッケージはビルドがスキップされます。- コメントには、「
cmd/dist
はkFreeBSDをfreebsd/$GOARCH
として検出するが、Cgoは手動で無効にする必要がある」と明記されており、cmd/dist
の変更とmake.bash
の変更が連携して機能することが示唆されています。
これらの変更は、GoのビルドシステムがDebian GNU/kFreeBSDという特定のハイブリッド環境を適切に処理し、その環境の制約(Cgoの未サポート)に対応するための、実用的かつ効果的なアプローチを示しています。
関連リンク
- Debian GNU/kFreeBSD 公式サイト: https://www.debian.org/ports/kfreebsd-gnu/
- Go言語の環境変数 (
GOOS
,GOARCH
): Goの公式ドキュメントや関連するブログ記事を参照。 - GoのCgoに関するドキュメント: https://go.dev/cmd/cgo/ (現在のドキュメント)
参考にした情報源リンク
- Debian GNU/kFreeBSD FAQ: Q. How do I detect kfreebsd with preprocessor directives in a C program?: http://wiki.debian.org/Debian_GNU/kFreeBSD_FAQ#Q._How_do_I_detect_kfreebsd_with_preprocessor_directives_in_a_C_program.3F (コミットメッセージに記載のリンク)
- Go Gerrit Change 6868046: https://golang.org/cl/6868046 (コミットメッセージに記載のリンク)
- Go言語のビルドシステムに関する一般的な情報源(Goの公式ブログ、Goのソースコードなど)
uname
コマンドのマニュアルページ