[インデックス 13028] ファイルの概要
このコミットは、Go言語のビルドシステムにおいて、go/build
パッケージがLinux/ARMアーキテクチャ上でのcgo(C言語との連携機能)をサポートするように変更を加えるものです。具体的には、cgoEnabled
マップに"linux/arm": true
のエントリを追加し、Linux上のARM環境でcgoが有効であることを明示しています。これは、Go言語がARMベースのシステム、特に組み込みシステムやRaspberry Piのようなデバイスでより広範に利用されるための重要な一歩となります。
コミット
commit 2bed8a7e957439587ae30416183fe2300d059bb9
Author: Shenghou Ma <minux.ma@gmail.com>
Date: Fri May 4 18:34:04 2012 +0800
go/build: cgo is supported on Linux/ARM
Last Part of CL 5601044 (cgo: Linux/ARM support)
Fixes #1880.
R=golang-dev, dave, rsc
CC=golang-dev
https://golang.org/cl/5988057
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/2bed8a7e957439587ae30416183fe2300d059bb9
元コミット内容
go/build: cgo is supported on Linux/ARM
Last Part of CL 5601044 (cgo: Linux/ARM support)
Fixes #1880.
R=golang-dev, dave, rsc
CC=golang-dev
https://golang.org/cl/5988057
変更の背景
この変更は、Go言語がLinux/ARM環境でcgoをサポートするための継続的な取り組みの一環です。コミットメッセージにあるFixes #1880
は、GoのIssue 1880「cmd/cgo: Linux arm support」を指しています。このIssueは、GoのcgoツールがLinux上のARMアーキテクチャをターゲットとする際に直面していた課題、特にクロスコンパイルに関する問題を議論していました。
当時のGoは、x86およびx86-64アーキテクチャが主流であり、ARMのような異なるアーキテクチャへの対応はまだ発展途上でした。cgoはGoコードからC言語のライブラリを呼び出すための重要な機能ですが、これにはターゲットアーキテクチャに対応したCコンパイラ(クロスコンパイラ)の適切な設定が必要となります。Issue #1880では、クロスコンパイル環境でのcgoの利用が困難であることや、特定の環境でのビルドエラーが報告されていました。
このコミットは、GoのビルドシステムがLinux/ARM環境でcgoが利用可能であることを認識するようにすることで、これらの課題を解決し、GoプログラムがARMベースのシステムでCライブラリと連携できるようにするための基盤を固めるものです。これにより、Goは組み込みシステム、IoTデバイス、モバイルプラットフォームなど、ARMアーキテクチャが広く使われている分野での適用範囲を広げることができました。
前提知識の解説
- Go言語: Googleによって開発されたオープンソースのプログラミング言語。シンプルさ、効率性、並行処理のサポートが特徴。
- cgo: Go言語の機能の一つで、GoプログラムからC言語の関数を呼び出したり、C言語のコードをGoプログラムに組み込んだりするためのメカニズム。これにより、既存のCライブラリをGoプロジェクトで再利用したり、パフォーマンスが重要な部分をCで記述したりすることが可能になります。cgoを使用すると、Goのビルドプロセス中にCコンパイラが呼び出され、CコードがコンパイルされてGoの実行可能ファイルにリンクされます。
- ARMアーキテクチャ: Advanced RISC Machinesの略で、モバイルデバイス、組み込みシステム、IoTデバイス、最近ではサーバーやデスクトップPCなど、幅広い分野で利用されているCPUアーキテクチャ。低消費電力と高性能を両立できる点が特徴です。
- クロスコンパイル: あるプラットフォーム(ホスト)上で、別のプラットフォーム(ターゲット)向けの実行可能ファイルを生成するプロセス。例えば、x86_64のLinuxマシンでARMv7のLinuxデバイス向けのGoプログラムをビルドする場合などがこれに当たります。cgoを使用する場合、ターゲットアーキテクチャ用のCクロスコンパイラがホストシステムにインストールされ、適切に設定されている必要があります。
go/build
パッケージ: Go言語の標準ライブラリの一部で、Goパッケージのビルドに関する情報(ソースファイルの解析、ビルドタグの処理、環境変数に基づくビルド制約の適用など)を提供するパッケージ。このパッケージは、go build
コマンドなどのGoツールチェーンの基盤となっています。cgoEnabled
マップ:go/build
パッケージ内部で管理されているマップで、特定のオペレーティングシステムとアーキテクチャの組み合わせ(例:"darwin/amd64"
,"linux/386"
)に対してcgoが有効であるかどうかを示すブール値を格納しています。このマップにtrue
が設定されている組み合わせでのみ、cgoを利用したビルドが可能となります。
技術的詳細
Goのビルドプロセスにおいて、cgoが有効であるかどうかは、go/build
パッケージ内のcgoEnabled
という内部マップによって決定されます。このマップは、GOOS
(オペレーティングシステム)とGOARCH
(アーキテクチャ)の組み合わせをキーとして、その組み合わせでcgoがサポートされているかどうかを示すブール値を保持しています。
このコミット以前は、"linux/arm"
の組み合わせがcgoEnabled
マップに明示的にtrue
として登録されていませんでした。これは、GoツールチェーンがLinux/ARM環境でcgoを利用しようとした際に、cgoが有効ではないと判断し、ビルドエラーや予期せぬ動作を引き起こす可能性があったことを意味します。
cgoが有効であると認識されるためには、Goのビルドシステムが、ターゲット環境でCコンパイラが利用可能であり、かつGoとCの間のリンケージが正しく機能することを「知っている」必要があります。cgoEnabled
マップへのエントリ追加は、Goのビルドシステムに対して、Linux/ARM環境でのcgoのサポートが検証され、安定していることを宣言するものです。
この変更により、go build
コマンドがLinux/ARMをターゲットとする際に、cgoEnabled["linux/arm"]
がtrue
と評価され、cgoのビルドパイプラインが適切に起動されるようになります。具体的には、GoのコンパイラはCソースファイルをCコンパイラに渡し、その結果生成されたオブジェクトファイルをGoのオブジェクトファイルとリンクして最終的な実行可能ファイルを生成します。
この修正は、Goのクロスコンパイル戦略においても重要です。開発者がx86_64のワークステーションからARMベースのLinuxデバイス向けにcgoを含むGoプログラムをビルドする場合、この設定がなければcgo関連のビルドが失敗する可能性がありました。この変更により、適切なクロスコンパイラツールチェーン(例: arm-linux-gnueabihf-gcc
)が設定されていれば、GoのビルドツールはLinux/ARM向けのcgoビルドを正しく処理できるようになります。
コアとなるコードの変更箇所
--- a/src/pkg/go/build/build.go
+++ b/src/pkg/go/build/build.go
@@ -215,6 +215,7 @@ var cgoEnabled = map[string]bool{\
"darwin/amd64": true,\
"linux/386": true,\
"linux/amd64": true,\
+\t"linux/arm": true,\
"freebsd/386": true,\
"freebsd/amd64": true,\
"windows/386": true,\
コアとなるコードの解説
変更はsrc/pkg/go/build/build.go
ファイル内のcgoEnabled
というグローバル変数(マップ)に対して行われています。
cgoEnabled
マップは、Goのビルドシステムがcgoを有効にするかどうかを判断するために使用する設定です。キーは"GOOS/GOARCH"
の形式(例: "linux/amd64"
)で、値はブール型です。true
であればその環境でcgoがサポートされ、false
であればサポートされません。
このコミットでは、既存のcgoEnabled
マップの初期化リストに、以下の行が追加されています。
"linux/arm": true,
この一行の追加により、Goのビルドシステムは、オペレーティングシステムがlinux
で、アーキテクチャがarm
である場合に、cgoが有効であると認識するようになります。これにより、Linux/ARM環境でcgoを使用するGoプログラムが正しくビルドされるようになり、GoがARMベースのシステムでC言語のライブラリと連携する能力が正式にサポートされることになります。
この変更は非常に小さいですが、Go言語がサポートするプラットフォームと機能の範囲を広げる上で、非常に重要な意味を持つものです。
関連リンク
- Go Issue 1880: https://github.com/golang/go/issues/1880
- Go CL 5988057: https://golang.org/cl/5988057
参考にした情報源リンク
- Go issue 1880, titled "cmd/cgo: Linux arm support," refers to an old issue on the
golang/go
GitHub repository that was opened in 2011 - The core of the problem stemmed from the
cgo
tool's reliance on a C compiler (like GCC) that needed to be correctly configured for the ARM target. - For many scenarios, if
cgo
functionality is not strictly required, a common workaround or solution is to disable it during compilation by setting the environment variableCGO_ENABLED=0
. - If
cgo
is necessary, cross-compiling for ARM requires a properly configured C cross-compiler toolchain. - Go has significantly improved its cross-compilation capabilities since 2011.