[インデックス 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.sh
がunistd_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.go
やzerrors_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
コマンドで検索し、最初に見つかったパスを使用するようにしています。
/usr/include/asm/unistd_64.h
(従来のパス)/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)
セクションに集中しています。
-
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
変数に格納します。これにより、どちらかのパスにファイルが存在すれば、そのパスが使用されます。
-
unistd_64.h
が見つからない場合のエラーハンドリング:if [ "$unistd_h" = "" ]; then echo >&2 cannot find unistd_64.h exit 1 fi
unistd_h
変数が空の場合(つまり、上記のls
コマンドでどちらのパスにもunistd_64.h
が見つからなかった場合)、標準エラー出力にエラーメッセージを表示し、スクリプトを終了します。これにより、ビルドプロセスが途中で停止し、ユーザーに問題が明確に通知されます。 -
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
パッケージのビルドに必要なヘッダーファイルをより堅牢に特定できるようになりました。
関連リンク
- Go CL 6912063: https://golang.org/cl/6912063
参考にした情報源リンク
- Multiarch - Ubuntu Wiki
- What is the purpose of mkall.sh in Go's syscall package? - GitHub
- What is the purpose of mksysnum_linux.pl in Go's syscall package? - Go.dev
- Where is unistd.h located in Linux? - Stack Overflow
- What is the purpose of unistd_64.h? - Stack Overflow
- Ubuntu 12.04 LTS (Precise Pangolin) - Ubuntu.com