OS2/emx/cross_build_under_Windows

OS2/emx/cross_build_under_Windows

emx の開発環境を使って、OS/2 アプリを Win32 上でビルドしてみる

要は emx の開発環境を Win32 上で動かして OS/2 用のバイナリをクロスビルドしちゃおうかー、的な。

いわゆる a.out 版の emx バイナリ(-Zomf を指定しないで作ったもの)は、emx カーネルがサポートしているシステムコールのみを呼び出しているもの(OS/2 の API や外部 DLL の関数を使っていないもの)であれば、純正 DOS 環境でも動かすことができる。(実際、一部のアプリが今でもこの環境を使って DOS と OS/2 を同時にサポートしている。rar の DOS 版とか)

ただし、emx 純正の DOS 版ランタイムカーネルは Windows のコマンドプロンプトに対応していない(DPMI 未サポート)ため、DPMI 対応の互換カーネルである RSX を使う。

開発環境の入手とインスコ

基本的に OS/2 版をそのまま使う。

とりあえず emx のランタイムと(C, C++ の)開発環境を入手する。 http://hobbes.nmsu.edu//pub/dev/emx/0.9d あたりから zip ファイルを取ってくる。

あと修正アーカイブも取ってくる。

まず emxfix04 以外のファイルを unzip する(任意のディスクのルートフォルダに unzip すると、\emx 以下のフォルダに展開される)。 それから同じ場所で emxfix04.zip を unzip し、アップデートファイルを上書きインストールする。

そのほか、Windows のコマンドプロンプトから使うには rsx のランタイムカーネル(rsx.exe)が必要。 rsx のオフィシャルサイト(http://www.mathematik.uni-bielefeld.de/~rainer/)はすでに消滅しているが、正式リリースの最終版はバージョン 5.21 は割といろんなところに置いてあるのでそれほど入手には困らない。日本だと ring あたりにもミラーされている。

ただ、バージョン 5.21 の rsx は emx の最終版(v0.9d fix04)よりも古いため、emx バイナリ実行時に警告が出る。無視してもたぶん大丈夫だと思うけど、archive.org 経由でオフィシャルサイトから rsxnt 1.51 のランタイムを取ってきて、この中にある rsx.exe(バージョン 5.24)を使ったほうがいいかもしれない。

RSX のランタイム中で必要なのはとりあえず rsx.exe だけ。emx.exe などと同じところ(\emx\bin)にコピーするのがたぶん無難。

あとは PATH その他の環境変数をてきとうに設定する。個人的にはこんな感じのバッチファイルを作っている。(C ドライブに emx 開発環境がインストールされていることを想定)

@echo off
echo type EXIT to leave.
path C:\emx\bin;%PATH%
set C_INCLUDE_PATH=C:/emx/include
set LIBRARY_PATH=C:/emx/lib
set CPLUS_INCLUDE_PATH=C:/emx/include/cpp;%C_INCLUDE_PATH%
set RSX=C:\emx\bin\rsx.exe
set RSXOPT=-h40 -Rs4096 -Rm4096 -Rz -Re0 -Rx
set GCCOPT=-pipe
set MAKESHELL=cmd.exe
prompt [OS2-EMX(RSX)] $p$g

emx 環境を使いたいときはコマンドプロンプトから cmd /K rsxenv.cmd とかやっている。 使い終わったら exit で emx 環境を外したコマンドプロンプトに戻るので簡単。

念のため rsx のオプションに関する説明を(環境変数 RSXOPT でデフォルトオプション設定)。

-h(数字) 利用可能なファイルハンドル数の設定
-Rs(数字) スタックサイズ設定(KB)。デフォルトだと 64 しかない
-Rm(数字) ヒープメモリを事前に確保。-Rx を使うときには指定が必要だったので適当につけた
-Rz メモリ確保時にゼロクリア。いや…念のためだ…
-Re0 FPUエミュレーション指定(エミュレーションなし)
-Rx "gcc -pipe" 用のスケジューラ有効

あと MAKESHELL は GNU Make 用のデフォルトシェル指定。というか Windows 用の make だとコマンドラインの受け渡しとかでいろいろ不自由だったので、emx 用の a.out バイナリを作った(djgpp 用なら使えるんじゃないかと思ってたんだけどなあ…)。

make-3.81-r3-vpathfix-emxaout-binonly.zip

(make.exe を \emx\bin あたりに入れておけばよいかと思われます)

ためしに何かビルドしてみる

ということで NYAOS 3000 の OS/2 版をビルドしてみました。 まず lua-5.1.4 のコンパイル。

[OS2-EMX(RSX)] C:\HOME>cd lua-5.1.4
[OS2-EMX(RSX)] C:\HOME\lua-5.1.4>make -C src generic "MYLDFLAGS=-Zexe"
  • Makefile 中の "cd src && ..." 的なところがなんかうまく動かなかったので -C オプションでごまかした。(make 側で何か対策が必要だろうか…)
  • -Zexe は実行ファイルの拡張子を exe にする的なオプション。今回はライブラリが欲しかっただけなのでほんとはいらない。
    デフォルトの cmd.exe 上から指定するときは前後を引用符でくくる。
  • ranlib がないので、Makefile 中の ranlib を適当に修正する。もしくは ranlib のダミーコマンドを作ってごまかす。ぶっちゃけ中身が "echo ranlib %1" 程度のバッチファイル(ranlib.cmd)でかまわない

次は NYAOS 本体。

[OS2-EMX(RSX)] C:\HOME\lua-5.1.4>cd ..\nyaos3k-2.91_1-src
[OS2-EMX(RSX)] C:\home\nyaos3k-2.91_1-src>make "OS=OS2"

nyaos.exe できあがり。あとは OS/2 環境にコピーして起動するだけ(emx ランタイム必須)。ちなみに RSX ランタイムに OS/2 API エミュレーション機能は存在しないため、そのまま Windows 上から実行してもちゃんと動きません(SIGSEGV で落ちる)。