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

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

このコミットは、Go言語のビルドシステムにおけるcmd/distツールのコンパイル方法を修正するものです。具体的には、ホストアーキテクチャ(GOHOSTARCH)に応じてgccに適切なフラグ(-m32または-m64)を渡すように変更し、cmd/distが正しくビルドされるようにします。

コミット

commit 72801291d6cb2109cc6578b4d1fb508cd4ae4f43
Author: Shenghou Ma <minux.ma@gmail.com>
Date:   Tue Mar 13 03:34:22 2012 +0800

    build: build correct cmd/dist matching GOHOSTARCH
            Fix for issue 3210 comment #1.
    
    R=adg, rsc
    CC=golang-dev
    https://golang.org/cl/5794057

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

https://github.com/golang/go/commit/72801291d6cb2109cc6578b4d1fb508cd4ae4f43

元コミット内容

build: build correct cmd/dist matching GOHOSTARCH
        Fix for issue 3210 comment #1.

R=adg, rsc
CC=golang-dev
https://golang.org/cl/5794057

変更の背景

この変更は、Go言語のビルドプロセスにおいて、cmd/distという重要なツールが、ビルドを実行するホストシステムのアーキテクチャ(GOHOSTARCH)と一致しない形でコンパイルされる可能性があった問題に対処するために行われました。

Go言語のビルドシステムは、クロスコンパイルを強力にサポートしていますが、その過程でビルドツール自体がホスト環境で正しく動作することが不可欠です。cmd/distはGoのビルドプロセスの中核をなすツールの一つであり、Goのソースコードからバイナリを生成する際に様々なビルドステップを調整します。

以前のビルドスクリプトでは、cmd/distをコンパイルする際に、ホストアーキテクチャに応じた適切なコンパイラフラグ(例えば32ビットシステム用の-m32や64ビットシステム用の-m64)がgccに明示的に渡されていませんでした。これにより、特定の環境、特に32ビットと64ビットの混在するシステムや、デフォルトのgccの挙動が期待と異なる場合に、cmd/distが正しく動作しない、あるいは予期せぬエラーを引き起こす可能性がありました。

コミットメッセージにある「Fix for issue 3210 comment #1」は、この問題が特定のバグトラッキングシステム(おそらくGoのIssue Tracker)で報告され、そのコメントで議論された解決策に基づいていることを示唆しています。ただし、現在のGoのIssue 3210はジェネリクスに関するものであり、このコミットの時期とは内容が異なるため、当時のIssue番号が現在とは異なるか、内部的な参照であった可能性があります。重要なのは、この変更がビルドの堅牢性を高めるための修正であるという点です。

前提知識の解説

このコミットを理解するためには、以下の概念を把握しておく必要があります。

  • Go言語のビルドシステム: Go言語は、自身のコンパイラやツールチェインをGo自身で記述しており、そのビルドプロセスは非常に洗練されています。make.bashのようなシェルスクリプトが、このビルドプロセスの初期段階を担い、Goのツールチェインをブートストラップします。
  • GOHOSTARCH: これはGoの環境変数の一つで、Goのツールチェインが動作するホストシステムのCPUアーキテクチャを示します。例えば、amd64(64ビットIntel/AMD)、386(32ビットIntel/AMD)、armなどがあります。Goのビルドシステムは、この変数を利用して、ホスト環境に合わせたツールをビルドします。
  • cmd/dist: Goのソースツリー内のsrc/cmd/distディレクトリにあるツールです。これはGoのビルドプロセスにおいて非常に重要な役割を果たします。具体的には、Goのソースコードからコンパイラ、リンカ、アセンブラなどのツールチェインをビルドし、Goの標準ライブラリをコンパイルし、最終的なGoのバイナリを生成する一連のステップを管理します。これはGoのビルドの「司令塔」のような存在です。
  • make.bash: Goのソースツリーのルートにあるシェルスクリプトです。これはGoのツールチェインをゼロからビルドする(ブートストラップする)ための主要なスクリプトです。cmd/distのような初期のビルドツールをコンパイルする役割も担っています。
  • gcc: GNU Compiler Collectionの略で、C言語、C++、Objective-C、Fortran、Ada、Goなどのプログラミング言語をコンパイルできるコンパイラ群です。Goの初期のビルドプロセスでは、cmd/distのようなC言語で書かれた部分をコンパイルするためにgccが使用されます。
  • コンパイラフラグ -m32-m64: gccにおいて、これらのフラグは生成するバイナリのターゲットアーキテクチャを指定します。
    • -m32: 32ビットのバイナリを生成するよう指示します。これは、32ビットシステムで実行されるプログラムや、64ビットシステム上で32ビット互換モードで実行されるプログラムをビルドする際に使用されます。
    • -m64: 64ビットのバイナリを生成するよう指示します。これは、64ビットシステムで実行されるプログラムをビルドする際に使用されます。 これらのフラグは、特にマルチアーキテクチャをサポートするシステム(例えば、64ビットLinux上で32ビットライブラリも利用できる環境)で重要になります。

技術的詳細

このコミットの技術的な核心は、src/make.bashスクリプト内でcmd/distをコンパイルするgccコマンドに、ホストアーキテクチャに応じた適切なビット幅指定フラグ(-m32または-m64)を追加することです。

変更前のmake.bashでは、cmd/distのコンパイルは以下の行で行われていました。

gcc -O2 -Wall -Werror -ggdb -o cmd/dist/dist -Icmd/dist "$DEFGOROOT" cmd/dist/*.c

このコマンドでは、最適化レベル(-O2)、警告の有効化(-Wall)、警告をエラーとして扱う(-Werror)、デバッグ情報の生成(-ggdb)、出力ファイル名(-o cmd/dist/dist)、インクルードパス(-Icmd/dist)、およびGoのルートパス定義("$DEFGOROOT")が指定されていますが、ターゲットアーキテクチャのビット幅を明示的に指定するフラグがありませんでした。

変更後、以下のロジックが追加されました。

mflag=""
case "$GOHOSTARCH" in
386) mflag=-m32;;
amd64) mflag=-m64;;
esac
gcc $mflag -O2 -Wall -Werror -ggdb -o cmd/dist/dist -Icmd/dist "$DEFGOROOT" cmd/dist/*.c
  1. mflag="": まず、mflagという変数を空文字列で初期化します。
  2. case "$GOHOSTARCH" in ... esac: GOHOSTARCH環境変数の値に基づいて条件分岐を行います。
    • 386): GOHOSTARCH386(32ビットIntel/AMDアーキテクチャ)の場合、mflag-m32を設定します。
    • amd64): GOHOSTARCHamd64(64ビットIntel/AMDアーキテクチャ)の場合、mflag-m64を設定します。
    • このcase文は、現在のGoがサポートする主要なIntel/AMDアーキテクチャに対応しています。他のアーキテクチャ(例: arm)の場合、mflagは空のままとなり、gccはデフォルトの挙動(通常はホストのネイティブアーキテクチャ)でコンパイルします。
  3. gcc $mflag ...: 最後に、gccコマンドの引数リストに$mflag変数を挿入します。これにより、GOHOSTARCH386であれば-m32が、amd64であれば-m64gccに渡され、cmd/distがホストアーキテクチャに合ったビット幅でコンパイルされるようになります。

この修正により、cmd/distが常にホストアーキテクチャに適合したバイナリとしてビルドされることが保証され、Goのビルドプロセスの安定性と信頼性が向上しました。特に、64ビットシステム上で32ビットのGoツールチェインをビルドするようなシナリオ(クロスコンパイルの準備段階など)において、この修正は重要です。

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

変更はsrc/make.bashファイルに集中しています。

--- a/src/make.bash
+++ b/src/make.bash
@@ -86,7 +86,14 @@ echo cmd/dist
 export GOROOT="$(cd .. && pwd)"
 GOROOT_FINAL="${GOROOT_FINAL:-$GOROOT}"
 DEFGOROOT='-DGOROOT_FINAL="'"$GOROOT_FINAL"'"'
-gcc -O2 -Wall -Werror -ggdb -o cmd/dist/dist -Icmd/dist "$DEFGOROOT" cmd/dist/*.c
+
+mflag=""
+case "$GOHOSTARCH" in
+386) mflag=-m32;;
+amd64) mflag=-m64;;
+esac
+gcc $mflag -O2 -Wall -Werror -ggdb -o cmd/dist/dist -Icmd/dist "$DEFGOROOT" cmd/dist/*.c
+
 eval $(./cmd/dist/dist env -p)
 echo

コアとなるコードの解説

上記の差分が示すように、src/make.bashの89行目付近で、cmd/distをコンパイルするためのgccコマンドが変更されています。

  • 削除された行:

    gcc -O2 -Wall -Werror -ggdb -o cmd/dist/dist -Icmd/dist "$DEFGOROOT" cmd/dist/*.c
    

    これは、以前のcmd/distコンパイルコマンドです。ここでは、gccにアーキテクチャ指定のフラグが渡されていませんでした。

  • 追加された行:

    mflag=""
    case "$GOHOSTARCH" in
    386) mflag=-m32;;
    amd64) mflag=-m64;;
    esac
    gcc $mflag -O2 -Wall -Werror -ggdb -o cmd/dist/dist -Icmd/dist "$DEFGOROOT" cmd/dist/*.c
    

    この新しいコードブロックは、GOHOSTARCHの値に基づいてmflag変数を設定し、そのmflaggccコマンドに挿入しています。これにより、cmd/distがホストアーキテクチャに合わせたビット幅でコンパイルされることが保証されます。

この変更は、Goのビルドシステムの初期ブートストラップ段階における重要な修正であり、Goツールチェイン全体の安定性と互換性を向上させるものです。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント(ビルドプロセスに関するもの)
  • GCCのドキュメント(特に-m32-m64フラグに関するもの)
  • Goのソースコード(src/make.bashおよびsrc/cmd/dist
  • 当時のGoコミュニティの議論(Goのメーリングリストや古いIssue Trackerなど、コミットメッセージに示唆されている情報源)
    • ただし、Issue 3210の現在の内容はコミット当時のものと異なるため、当時の正確な議論を特定することは困難でした。