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

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

このコミットは、Go言語のsyscallパッケージにおけるmkall.shスクリプトの修正に関するものです。特に、マルチアーキテクチャシステム(例:Ubuntu Precise)上でmkall.shが正しく動作するように、unistd_64.hヘッダーファイルの検索パスを改善しています。これにより、異なるアーキテクチャのライブラリが共存する環境でも、Goのシステムコール関連ファイルの生成が安定して行われるようになります。

コミット

commit fc3936380b4790cb19a17d40d5372bb65c1f70f0
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date:   Tue Dec 11 12:03:18 2012 -0500

    syscall: let mkall.sh work on multiarch systems (like Precise)
    
    R=golang-dev, rsc
    CC=golang-dev
    https://golang.org/cl/6912063

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

https://github.com/golang/go/commit/fc3936380b4790cb19a17d40d5372bb65c1f70f0

元コミット内容

syscall: let mkall.sh work on multiarch systems (like Precise)

変更の背景

この変更の背景には、Linuxディストリビューションにおける「マルチアーキテクチャ(Multiarch)」サポートの進化があります。特にUbuntu 12.04 (Precise Pangolin)のようなシステムでは、32ビットと64ビットのライブラリが同じファイルシステム上に共存できるようになりました。これにより、例えば64ビットシステム上で32ビットアプリケーションを実行するといったことが容易になります。

Go言語のsyscallパッケージは、オペレーティングシステムの低レベルな機能(システムコール)にアクセスするためのインターフェースを提供します。このパッケージのビルドプロセスでは、mkall.shというスクリプトが、各OSとアーキテクチャに特化したGoのソースファイル(例: zsyscall_GOOS_GOARCH.go)を生成します。この生成プロセスの一部として、システムコール番号を定義するCヘッダーファイル(Linuxの場合、unistd_64.hなど)を読み込む必要があります。

従来のmkall.shスクリプトは、unistd_64.h/usr/include/asm/unistd_64.hという固定パスにあることを前提としていました。しかし、マルチアーキテクチャシステムでは、このヘッダーファイルのパスが/usr/include/x86_64-linux-gnu/asm/unistd_64.hのように変更されることがあります。このパスの変更により、mkall.shunistd_64.hを見つけられず、Goのsyscallパッケージのビルドが失敗するという問題が発生していました。

このコミットは、このようなマルチアーキテクチャ環境でのビルド問題を解決し、Goがより広範なLinuxシステムで安定して動作するようにするために行われました。

前提知識の解説

1. mkall.shスクリプト

mkall.shは、Go言語のsrc/pkg/syscallディレクトリに存在するシェルスクリプトです。Goのsyscallパッケージは、オペレーティングシステムのシステムコールをGoプログラムから呼び出すための低レベルなインターフェースを提供します。しかし、システムコールの定義や番号はOSやCPUアーキテクチャによって異なるため、Goのビルドプロセスではこれらを動的に生成する必要があります。

mkall.shの主な役割は以下の通りです。

  • プラットフォーム固有のGoソースファイルの生成: zsyscall_GOOS_GOARCH.gozerrors_GOOS_GOARCH.goといった、特定のOS (GOOS) とアーキテクチャ (GOARCH) に対応するGoのソースファイルを自動生成します。
  • システムコール番号の抽出: mksysnum_linux.plなどの補助スクリプトを呼び出し、Cヘッダーファイルからシステムコール番号を抽出し、Goの定数として定義します。
  • Cgo定義の生成: go tool cgo -godefsコマンドを使用して、C言語の構造体や定数をGoの型定義に変換します。

2. マルチアーキテクチャシステム (Multiarch)

マルチアーキテクチャは、Linuxシステムが複数の異なるCPUアーキテクチャ用のバイナリとライブラリを同時にサポートできるようにする機能です。例えば、64ビットのUbuntuシステム上で、32ビットのアプリケーションとその依存ライブラリをインストールして実行することが可能になります。

この機能は、特にライブラリのパスに影響を与えます。従来のシステムでは、32ビットライブラリは/usr/libに、64ビットライブラリは/usr/lib64に配置されることが多かったですが、マルチアーキテクチャシステムでは、/usr/lib/x86_64-linux-gnu/usr/lib/i386-linux-gnuのように、アーキテクチャ固有のパスが/usr/libの下に導入されます。これに伴い、システムヘッダーファイルのパスも変更されることがあります。

3. unistd_64.h

unistd_64.hは、Linuxシステムにおける64ビットアーキテクチャ用のシステムコール番号を定義するCヘッダーファイルです。システムコールは、ユーザー空間のプログラムがカーネルの機能(ファイルI/O、プロセス管理、メモリ管理など)にアクセスするためのインターフェースであり、それぞれに固有の番号が割り当てられています。

マルチアーキテクチャ環境では、このファイルのパスが従来の/usr/include/asm/unistd_64.hから/usr/include/x86_64-linux-gnu/asm/unistd_64.hに変更されることがあります。Goのsyscallパッケージが正しくビルドされるためには、このヘッダーファイルを正確に特定できる必要があります。

4. mksysnum_linux.pl

mksysnum_linux.plは、Goのsyscallパッケージ内で使用されるPerlスクリプトです。このスクリプトは、LinuxのCヘッダーファイル(例: unistd_64.h)を解析し、システムコール名とその対応する数値(システムコール番号)を抽出し、Goのソースコードとして出力します。これにより、Goプログラムが特定のシステムコールをその番号で呼び出すことが可能になります。

技術的詳細

このコミットの技術的詳細は、mkall.shスクリプトがunistd_64.hヘッダーファイルを検索する方法を改善した点にあります。

変更前は、linux_amd64アーキテクチャの場合、mksysnum変数の定義でunistd_64.hのパスが/usr/include/asm/unistd_64.hにハードコードされていました。

mksysnum="./mksysnum_linux.pl /usr/include/asm/unistd_64.h"

しかし、マルチアーキテクチャシステムでは、このファイルが/usr/include/x86_64-linux-gnu/asm/unistd_64.hに配置されることが一般的です。このパスの不一致が、ビルドエラーの原因となっていました。

コミット後の変更では、unistd_64.hのパスを動的に検出するように修正されました。具体的には、以下の2つのパスをls -1コマンドで検索し、最初に見つかったパスを使用するようにしています。

  1. /usr/include/asm/unistd_64.h (従来のパス)
  2. /usr/include/x86_64-linux-gnu/asm/unistd_64.h (マルチアーキテクチャ環境での一般的なパス)
unistd_h=$(ls -1 /usr/include/asm/unistd_64.h /usr/include/x86_64-linux-gnu/asm/unistd_64.h 2>/dev/null | head -1)

2>/dev/nullはエラー出力を抑制し、| head -1は最初に見つかったパスのみを取得します。

さらに、unistd_h変数が空(つまり、どちらのパスでもファイルが見つからなかった場合)であれば、エラーメッセージを出力してスクリプトを終了するようにしています。

if [ "$unistd_h" = "" ]; then
    echo >&2 cannot find unistd_64.h
    exit 1
fi

そして、mksysnum変数の定義で、ハードコードされたパスの代わりに、この動的に検出された$unistd_h変数を使用するように変更されています。

mksysnum="./mksysnum_linux.pl $unistd_h"

この変更により、mkall.shは従来のシステムとマルチアーキテクチャシステムの両方でunistd_64.hを正しく見つけられるようになり、Goのsyscallパッケージのビルドが安定しました。

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

--- a/src/pkg/syscall/mkall.sh
+++ b/src/pkg/syscall/mkall.sh
@@ -145,8 +145,13 @@ linux_386)
  mktypes="GOARCH=$GOARCH go tool cgo -godefs"
  ;;
 linux_amd64)
+ unistd_h=$(ls -1 /usr/include/asm/unistd_64.h /usr/include/x86_64-linux-gnu/asm/unistd_64.h 2>/dev/null | head -1)
+ if [ "$unistd_h" = "" ]; then
+  echo >&2 cannot find unistd_64.h
+  exit 1
+ fi
  mkerrors="$mkerrors -m64"
- mksysnum="./mksysnum_linux.pl /usr/include/asm/unistd_64.h"
+ mksysnum="./mksysnum_linux.pl $unistd_h"
  mktypes="GOARCH=$GOARCH go tool cgo -godefs"
  ;;
 linux_arm)

コアとなるコードの解説

変更はsrc/pkg/syscall/mkall.shスクリプトのlinux_amd64)セクションに集中しています。

  1. unistd_h変数の導入とパスの動的検出:

    unistd_h=$(ls -1 /usr/include/asm/unistd_64.h /usr/include/x86_64-linux-gnu/asm/unistd_64.h 2>/dev/null | head -1)
    

    この行が最も重要な変更点です。

    • ls -1: 指定されたファイルを1行に1つずつリストします。
    • /usr/include/asm/unistd_64.h: 従来のLinuxシステムでunistd_64.hが配置されていたパスです。
    • /usr/include/x86_64-linux-gnu/asm/unistd_64.h: Ubuntu Preciseのようなマルチアーキテクチャシステムでunistd_64.hが配置される可能性のあるパスです。
    • 2>/dev/null: lsコマンドがファイルを見つけられなかった場合のエラーメッセージを抑制します。
    • | head -1: lsが複数のパスで見つけた場合でも、最初に見つかったパス(つまり、存在したパス)のみをunistd_h変数に格納します。これにより、どちらかのパスにファイルが存在すれば、そのパスが使用されます。
  2. unistd_64.hが見つからない場合のエラーハンドリング:

    if [ "$unistd_h" = "" ]; then
        echo >&2 cannot find unistd_64.h
        exit 1
    fi
    

    unistd_h変数が空の場合(つまり、上記のlsコマンドでどちらのパスにもunistd_64.hが見つからなかった場合)、標準エラー出力にエラーメッセージを表示し、スクリプトを終了します。これにより、ビルドプロセスが途中で停止し、ユーザーに問題が明確に通知されます。

  3. mksysnumコマンドの修正:

    - mksysnum="./mksysnum_linux.pl /usr/include/asm/unistd_64.h"
    + mksysnum="./mksysnum_linux.pl $unistd_h"
    

    mksysnum_linux.plスクリプトに渡すunistd_64.hのパスが、ハードコードされたパスから、動的に検出された$unistd_h変数に置き換えられました。これにより、mksysnum_linux.plはシステム上の正しいunistd_64.hファイルを参照できるようになります。

これらの変更により、mkall.shは異なるLinux環境(特にマルチアーキテクチャシステム)において、syscallパッケージのビルドに必要なヘッダーファイルをより堅牢に特定できるようになりました。

関連リンク

参考にした情報源リンク