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

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

このコミットは、src/cmd/cgo/gcc.go ファイルに影響を与えています。具体的には、このファイルはGo言語のcgoツールチェーンの一部であり、C言語のコードをGoプログラムにリンクする際にGCCコンパイラとの連携を管理する役割を担っています。

コミット

commit 9602dd5e87b0d5cccae8ca84fcc088c065f9cae3
Author: Shenghou Ma <minux.ma@gmail.com>
Date:   Fri May 4 18:26:16 2012 +0800

    cmd/cgo: support Linux/ARM
            Part 3 of CL 5601044 (cgo: Linux/ARM support)
    
    R=golang-dev, dave, rsc
    CC=golang-dev
    https://golang.org/cl/5991066

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

https://github.com/golang/go/commit/9602dd5e87b0d5cccae8ca84fcc088c065f9cae3

元コミット内容

cmd/cgo: support Linux/ARM
        Part 3 of CL 5601044 (cgo: Linux/ARM support)

R=golang-dev, dave, rsc
CC=golang-dev
https://golang.org/cl/5991066

変更の背景

このコミットの主な目的は、Go言語のcgoツールがLinux上のARMアーキテクチャをサポートするようにすることです。コミットメッセージに「Part 3 of CL 5601044 (cgo: Linux/ARM support)」とあるように、これはcgoにおけるLinux/ARMサポートを導入するための複数パートにわたる変更セットの一部です。

Go言語は、その設計当初からクロスプラットフォーム対応を重視していましたが、特定のアーキテクチャやOSの組み合わせ(この場合はLinux/ARM)に対するcgoの完全なサポートは段階的に追加されていました。cgoはGoプログラムからC言語のコードを呼び出すための重要な機能であり、組み込みシステムや特定のハードウェアと連携するアプリケーションにおいてARMサポートは不可欠です。

この変更は、Go言語がARMベースのデバイス(Raspberry Piなどのシングルボードコンピュータや、一部のサーバー、組み込みデバイスなど)でより広範に利用されるための基盤を強化するものです。

前提知識の解説

Go言語とcgo

Go言語は、Googleによって開発された静的型付けのコンパイル型言語です。並行処理のサポート、ガベージコレクション、高速なコンパイルなどが特徴です。

cgoは、Go言語のツールの一つで、GoプログラムからC言語の関数を呼び出したり、C言語のコード内でGoの関数を呼び出したりするためのメカニズムを提供します。これにより、既存のCライブラリをGoプロジェクトで再利用したり、パフォーマンスが重要な部分をCで記述したりすることが可能になります。cgoを使用すると、GoコンパイラはCコードをコンパイルするためにシステムにインストールされているCコンパイラ(通常はGCC)を呼び出します。

ARMアーキテクチャ

ARM(Advanced RISC Machine)は、モバイルデバイス、組み込みシステム、IoTデバイス、さらには一部のサーバーやデスクトップコンピュータで広く使用されているRISC(Reduced Instruction Set Computer)ベースのプロセッサアーキテクチャです。低消費電力と高い性能効率が特徴です。

GCCと-mフラグ

GCC(GNU Compiler Collection)は、C、C++、Goなど、多くのプログラミング言語をサポートするフリーのコンパイラシステムです。GCCは、コンパイル時に様々なオプション(フラグ)を受け取ります。

-mフラグは、ターゲットアーキテクチャに特有のオプションを指定するために使用されます。例えば:

  • -m32: 32ビットコードを生成します。x86アーキテクチャの場合、Intel 386互換のコードを生成します。
  • -m64: 64ビットコードを生成します。x86-64(amd64)アーキテクチャの場合、64ビットコードを生成します。
  • -marm: ARMアーキテクチャの場合、ARM命令セット(32ビット)のコードを生成します。これは、ARMプロセッサがサポートするThumb命令セット(よりコンパクトな16ビット命令セット)とは異なります。cgoがCコードをコンパイルする際に、GoのランタイムとCコードが同じABI(Application Binary Interface)を使用するように、適切な命令セットを指定することが重要です。

技術的詳細

このコミットは、cgoツールがGCCを呼び出す際に、ターゲットアーキテクチャがARMである場合に適切な-mフラグ(-marm)を渡すように変更しています。

src/cmd/cgo/gcc.goファイル内のgccMachine()関数は、Goのターゲットアーキテクチャ(goarch)に基づいて、GCCに渡すべき-mフラグを決定します。

変更前は、この関数はamd64(64ビット)と386(32ビット)のアーキテクチャのみを考慮していました。

  • amd64の場合、-m64を返します。
  • 386の場合、-m32を返します。

このコミットでは、goarcharmである場合の新しいケースが追加されています。この場合、gccMachine()関数は"-marm"を返すように修正されました。これにより、cgoがARMターゲット向けにCコードをコンパイルする際に、GCCが正しい命令セット(ARM命令セット、Thumbではない)を使用するようになります。これは、GoのランタイムがARM命令セットを使用しているため、Cコードもそれに合わせる必要があるためです。ABIの互換性を保つ上でこの指定は非常に重要です。

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

--- a/src/cmd/cgo/gcc.go
+++ b/src/cmd/cgo/gcc.go
@@ -730,13 +730,15 @@ func (p *Package) gccName() (ret string) {
 	return
 }
 
-// gccMachine returns the gcc -m flag to use, either "-m32" or "-m64".
+// gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
 func (p *Package) gccMachine() []string {
 	switch goarch {\n 	case "amd64":
 		return []string{"-m64"}
 	case "386":
 		return []string{"-m32"}
+\tcase "arm":
+\t\treturn []string{"-marm"} // not thumb
 	}
 	return nil
 }

コアとなるコードの解説

変更はsrc/cmd/cgo/gcc.goファイルのgccMachine()関数に集中しています。

  • 変更前のコメント: // gccMachine returns the gcc -m flag to use, either "-m32" or "-m64". このコメントは、以前はgccMachine関数が-m32または-m64フラグのみを返すことを示していました。

  • 変更後のコメント: // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm". 新しいコメントは、この関数が-marmフラグも返すようになったことを明確に示しています。

  • 追加されたcase "arm":ブロック:

    case "arm":
        return []string{"-marm"} // not thumb
    

    この新しいcase文は、Goのターゲットアーキテクチャ(goarch変数で表される)が"arm"である場合に実行されます。

    • return []string{"-marm"}: GCCに渡すフラグとして"-marm"を含む文字列スライスを返します。これにより、GCCはARM命令セット(32ビット)でCコードをコンパイルするよう指示されます。
    • // not thumb: このコメントは、特にThumb命令セット(ARMプロセッサで利用可能な、よりコンパクトな16ビット命令セット)ではなく、標準のARM命令セットが使用されることを強調しています。GoのランタイムがARM命令セットを使用しているため、Cコードも同じ命令セットでコンパイルされることで、GoとC間の関数呼び出しにおけるABIの互換性が保証されます。

この変更により、Goのcgoツールは、Linux上のARMアーキテクチャ向けにCコードを正しくコンパイルできるようになり、GoプログラムがARMベースのシステムでCライブラリと連携する能力が向上しました。

関連リンク

参考にした情報源リンク