彷徨えるフジワラ

年がら年中さまよってます

OpenSolaris ソースビルドに関する覚え書き

モジュールの個別ビルドをやりたくなったので、久々に OpenSolaris をソースからビルドしてみることに。

ソースツリーを丸々ビルドする場合は、「やっぱり Sun がスキ!」の「OpenSolaris をビルドしてみよう」エントリや、「Building and Installing OpenSolaris (Part 1)」(日本語訳)とかを参照すれば多分十分なのだけれど、今回はモジュールの個別ビルドを行うので、まぁ、色々と試行錯誤が。

ソースの入手

ソースの入手先は、Operating System/Networking (ON) Download Center の "Where can I get the source and other tar files?" から選択。まぁ、当然と言うか Mercurial 経由で入手。

ちなみに、opensolaris.org に ssh で繋ぐと実行優先度をガンガン落とされるらしく、継続的な更新は兎も角、最初の clone に関しては bitbucket のミラーに http で繋ぐ方が心持ち早い気がする。

更に予断だけど、768MB を割り当てたゲストマシン上の OpenSolaris で hg clone しようとしたら、memory 不足で abort された。1024MB 割り当てで起動し直したら成功したので、この辺が最低必須メモリラインの模様。

closed バイナリの入手

完全なディストリビューションを作成するわけでもないなら、closed バイナリなんて不要だろ?とか思ったのだけど、あちこちでチェックコードが仕込まれているみたいなので、おとなしく導入することに。

ビルド手順の解説ページ等からは、最新版向けのページにしかリンクされていないけど、一階層上に移動すれば、旧版に応じた closed バイナリを入手することも可能。

ちなみに、debug 版を入手した場合は、後述する bldenv 起動時に "-d" オプションを指定しないと "make setup" で怒られるので要注意。

ツールの入手

必要なツールとしては、SunStudio 以外にも:

  • GCC: SUNWgcc パッケージを導入
  • ON build tool: SUNWonbld パッケージを導入

が必要。

トラブルシューティングは "-m serial" 付きで

dmake コマンドを使って問題が発生した場合、デフォルトのモードである並列実行が有効なままだと何かと原因の特定が面倒なので、"-m serial" オプション付で dmake を実行することで、逐次処理モードにしてやるのが吉。

っつーか、通常の make コマンドを使えばいいじゃん!という話も。

でも MP 構成の場合は dmake の方がガンガン CPU を回すので、早いのも確かなんだよねぇ。

とりあえず、以下は全て make で統一。

onbld ツールの参照先設定

ビルドに必要なユーティリティは SUNWonbld パッケージのものを使用するのだけれど、ビルド作業中のデフォルト設定は、ソースツリー中にビルドの一環で新規作成されたユーティリティの方が優先されるようになっている。

そのため、折角 SUNWonbld が導入済みなのに、まだ作成されていないソースツリー中のユーティリティを使用しようとして、command not found で failed になるケースがチラホラ。

試行錯誤の過程での話なので、ちゃんとした手順だと大丈夫なのかもしれないけどね。

で、bldenv コマンドに "+t" というオプションを指定すると、SUNWonbld の方を優先的に使用するように環境設定をするらしいことを発見。早速 "+t" 付で実行してみるも、やっぱり SUNWonbld が蔑ろにされる。

ksh で書かれている bldenv コマンドの実行過程を、"ksh -x" で表示させて確認してみたところ、nightly コマンドに渡すオプションを指定する NIGHTLY_OPTIONS 環境変数の設定に "-t" (ソースツリー中のユーティリティを優先)が書かれていることで、そちらが優先されている模様。

NIGHTLY_OPTIONS="-FNnaCDlmrt";

つまり:

  • 環境変数設定ファイル中の NIGHTLY_OPTIONS 指定から "t" を抜く
  • bldenv コマンドに "+t" を指定する

の両方を実施しないと、SUNWonbld の方が優先されないことに。

そういえば、前回ビルドした時は、nightly コマンド使ってたなぁ。ってことは、手順を踏めば "-t" 指定でも大丈夫、ってことか。

ソース取得先に応じたビルド設定

ふと思い立って、Mercurial リポジトリから "hg archive" で別途ビルド用領域を作成して、そこでビルドをやろうと目論んだ所、usr/src 直下での "make setup" の段階で、usr/src/tools/findunref において:

make: Fatal error: Don't know how to make target `exception_list.unknown'

というエラーが。

どうも、入手経路(tarball/Mercurial/Subversion)に応じて、無視するファイル(シンボル?)パターンの生成ルールが異なる設定になっているらしく、Mercurial 経由で入手したソースなのに、Mercurial リポジトリとは別にビルド用の環境を用意したことが裏目に出たらしい。

Mercurial の作業領域でビルドを実施することで、この問題は解決。

bldenv へのコマンド指定

ビルド例では、対話的に bldenv コマンド実行 〜 make によるビルド、という流れになっているけど、bldenv コマンドは言わば env コマンドの目的特化版なので、bldenv コマンド経由で make コマンドを起動してやれば良いじゃないか!

ということで、usr/src 配下で "bldenv opensolaris.sh make setup" とやってみたところ、なにやら延々と処理をやっている模様。

しかも途中経過を見ていると、あきらかにカーネルモジュールのコンパイル作業が含まれている。

bldenv コマンドの(ksh)ソースをよくよく調べてみると、例えば:

$ bldenv opensolaris.sh make setup

と指定すると、内部的には:

exec bash -c make setup

となってしまい、実際に実行されるのは「ビルドターゲット無しの make」、いわゆる "make all" な状態に。なので:

$ bldenv opensolaris.sh 'make setup'

という具合にコマンドを丸々クォートしてやる必要がある。

ちょっとこの実装ってアレじゃねぇ? > bldenv

モジュールのビルドはアーキテクチャ固有ディレクトリ配下で

dtrace モジュールをビルドしようとして、usr/src/uts/common/dtrace 配下に移動したら、Makefile が無い。

しょうがないので、一段上の階層である usr/src/uts/common でゴニョゴニョやろうとしたが、全然上手く行かない。

結局、アーキテクチャ固有ディレクトリである usr/src/uts/intel/dtrace 配下(x86の場合)で "make" することで、ビルドが実施されることが判明。

うーむ、環境変数なり設定ファイルを見てアーキテクチャを特定するのではなく、ビルドが開始された起点ディレクトリがアーキテクチャを特定する、というアプローチなのね。

usr/src 配下での "make setup" では不十分

usr/src 配下での "make setup" が完了したなら、後は個別モジュール毎のビルドが可能、ということだけど、例えばここで dtrace モジュールをビルドしようとすると:

Don't know how to make target "../../i86pc/genassym/debug64/assym.h"

どうも、"make setup" だけでは不十分らしく、usr/src/uts/i86pc/ 配下(x86 の場合)で:

$ /opt/onbld/bin/bldenv +t -d opensolaris.sh 'make genassym'

とやってやる必要がある。

うーん、微妙に中途半端だなぁ > make setup