tsutsuiの作業記録置き場

NetBSDとかPC-6001とかの作業記録のうち、Twitterの140字では収まらない内容や記事としてまとめるべき内容をとりあえず置いてみる予定

NetBSD + pkgsrc で P6エミュレータ PC6001VX

Windows 環境用 PC-6001 エミュレータ

PC-6001エミュレータといえば Windows 用の PC-6001V および PC-6001VW が有名ですが、 PC6001V をベースに Linux等へ移植したものとして eighttails さん による PC-6001VX が存在します。

README に「PC6001VXの末尾のXはクロスプラットフォームのXです」とあるとおり、Linux移植版であるにもかかわらずあえて Windows 版バイナリもリリースされているところにも、「移植性」に対するこだわりが感じられます。

もともと Windows (MSYS2) でも Linux でも同じソースツリーでビルドできるくらいなので、 pkgsrc の枠組みを使えば NetBSD で動かすのもそんなに難しくはないだろうな、とは思っていました。

が、自分自身が Qt に縁がなくクロスプラットフォーム環境対応のビルド方法を知らなかったということと、 README に書かれているビルド方法の説明が

PC6001VX.proをQtCreatorで開いてビルドしてください。
IDEが嫌な人はQtCreatorの代わりにqmakeとqtライブラリを揃えればビルドできるでしょう。

という「わかる人向け」という感じだったこともあり、長いことほったらかしにしていました。

ここに来て「冬休みの課題」ということでいろいろやってみたところ、わりとあっさり動いたのでまとめてみました。

まとめ

WIP pkgsrc ファイル一式

とりあえずで github に投棄してあります。

Qt アプリのビルド

  • "Foo.pro" のプロジェクト記述ファイルのあるところで qmake を実行すると Makefile が作られる
  • Makefile ができたら make する

基本はこれだけっぽいです。

pkgsrc 記述

  • 以下のパッケージを先に入れる (依存パッケージとして記述する)
    • x11/qt5-qtbase
    • x11/qt5-qtmultimedia
    • x11/qt5-qtx11extras
    • devel/SDL2
    • multimedia/ffmpeg3
  • pkgsrc ビルド前の do-configure で qmake を実行
  • do-install で手動でバイナリと README をインストール
    (qmake で作られる Makefile には make install のターゲット記載がないようなので)

パッチによる修正箇所

PC6001VX.pro の記述について以下を修正

  • Linux用の X11 関連ライブラリ記述を追加
  • libavformat, libavcodec, libswscale の指定について ffmpeg3 付属のものを使用できるように pkg-config を使った記載に修正

以下は詳細というか作業メモ

依存パッケージ

README にある debian での説明では

apt-get install build-essential libx11-dev mesa-common-dev libsdl2-dev qtcreator qt5-default qtmultimedia5-dev libqt5x11extras5-dev libqt5multimedia5-plugins libavformat-dev libavcodec-dev libswscale-dev を実行。

とありました。pkgsrc でどうすべきかを適当に考えると

  • X11NetBSD だと標準で入るし pkgsrc でも良きに計らってくれるはず
  • mesa もたぶん X11 とセット
  • libsdl2 は pkgsrc/devel/SDL2
  • qtcreator は開発環境っぽいので無くてもいいはず?
  • qt5 関連はとりあえず pkgsrc/x11 の下に qt5-qtbase と qt5-qttools というのがあるからとりあえずそのへんを入れてみよう
  • libavformat, libavcodec, libswscale はそれっぽいパッケージがないけれど、同名のライブラリは ffmpeg3 の PLIST の中にある

という感じで、とりあえずそんな具合で Makefile その他のファイルを用意しました。

pkgsrc Makefile

pkgsrcをいじるのは「自分が使いたいアプリを楽にビルドしたい」という理由なので、 pkgsrc そのものを調べずに設定を書いては怒られるという感じなのですが、今回もとりあえず見よう見まねというか行きあたりばったり方式でした。

DISTNAME

ftp で配布ファイルを取得する時の名前なので、配布ファイルの PC6001VX_2.30.0_src.tar.gz に基づいてそのまま記述

PKGNAME

pkgsrc的には [アプリ名]-[バージョン番号] というスキームが必要っぽいので適当に他のパッケージの Makefile を真似して文字列を置き換え

MASTER_SITES

ftp その他でバイナリを持ってくるためのURLとして使われるはずなので、ダウンロードページのソース tar.gz のリンクのファイル名を除いた部分を記載

do-configure

適当に既存パッケージの Makefile を "qmake" で grep して
${WRKSRC} ディレクトリに入って ${QTDIR} の suffix を使って qmake を呼び出し」
で記述

do-install

事前にインストール必要な設定ファイルは特になく "PC6001VX" のバイナリを実行するだけで動くようだったので ${INSTALL_PROGRAM}/usr/pkg/bin に入れるだけ

USE_TOOLS

PC6001VX.pro の設定ファイルを見ると pkg-config を呼んでいるようなのでそれを記載

USE_LANGUAGES

基本 C++ ですが とりあえず c と c++ を記載

その他

上記以外は適当でもとりあえずビルドには困らないので後回し

とりあえずビルド

まずは pkgsrc 以前に「バイナリとしてビルドできるのか」「ビルドできたとしてまともに動くのか」という問題があるので、依存パッケージ(と思われるもの)を入れた後にいわゆる野良ビルドから始めました。これが昨日の深夜。

qmake を実行しても無言のままなので Makefile が作られていることに気づかなかったとか、qt5-qttools の依存パッケージを含めたビルドにやたら時間がかかって待たされたとか、しょうもないハマりはありましたが、わかってしまえばわりとあっさりとビルドが始まりました。

ビルドにおける最初のエラーは
<libavcodec/avcodec.h> のヘッダが見つからない」
というものでした。先ほど書いたように libavcodec は ffmpeg3 に付属していて /usr/pkg/include/ffmpeg3 以下に入っているのですが、とりあえず pkgsrc 的作法の前にバイナリの動作確認のほうが先ということで Makefile に直接 -I/usr/pkg/include/ffmpeg3 の記載を足して誤魔化しました。

ヘッダだけではなくライブラリのリンクでも文句を言われるので、リンカの引数として適当に
-L/usr/X11R7/lib -Wl,-rpath,/usr/X11R7/lib -L/usr/pkg/lib/ffmpeg3 -Wl,-rpath,/usr/pkg/lib/ffmpeg3
といった記述も先に足してやります。すると、わりとあっさりとリンクまで通りました。

できあがった PC6001VX のバイナリをおもむろに実行してみると
~/.pc6001vx/rom 以下に ROM がない」
と怒られたもの、 ROMファイルをコピーしてやるとこれまたあっさりと Windows では見慣れているウインドウが出てきました。

ざっとデバッガで見てみると OpenGL 関連のライブラリから X11 ライブラリ内の関数の memcpy() で落ちていましたが、とりあえずわりと行けそうか? という感触でした。

pkgsrc 化

ffmpeg3 関連

事前野良ビルドでは Makefile 手編集で ffmpeg3 関連のパスの記載を追加しましたが、 pkgsrc ではそのあたりをちゃんと(?)する必要があります。

いろいろ知らなすぎて遠回りしましたが、 ffmpeg2 および ffmpeg3 等を共存させるために以下のような仕組みになっていると判断しました。

  • ffmpeg のバージョンごとに別の場所にインストールする
  • ビルドの際に、そのパッケージで選択されたバージョンを BUILDLINK_FNAME_TRANSFORM.ffmpeg3 等の定義で選択し、ビルド作業ディレクトリの ${WRKDIR}/.buildlink の中にシンボリックリンクを作成する

問題の本質は PC6001VX 配布中の PC6001VX.pro の中で libavcodec その他の定義に pkg-config を使っていないこと なので、ここは pkgsrc の枠組みでパッチを当ててやることにします。

X11ライブラリ

Makefile${INSTALL_DIRS} 等々を設定してバイナリを入れようとすると今度は X11 関連で怒られました。


libavcodec と同様、 PC6001VX.pro の X11 関連の定義にも pkg-config が使われていない のでそこを修正してみたものの、なぜかエラーが消えません。というかリンク時にもそれっぽい定義が出てきません。

と、よく見ると上記の定義は「linux」の条件文っぽいところの内側だったので、その外側に else 節を足してそこに同様の定義で pkg-config を使うようにすることで解決しました。

SIGSEGV問題

次に、できあがったバイナリを実行すると昨晩の野良ビルド同様、「起動して少し時間が経つと core を吐いて落ちる」という問題がありました。

落ちているのが OpenGL 関連だったので、とりあえず PC6001VX.pro 中の "NOOPENGL" の定義を有効にしてやると落ちずに動くようだったので当初はそれでパッチを作成しました。これでとりあえず動くようになったというのが以下のツイートです。

ちなみに作者の eighttails さんにも早速捕捉されてしまいました(^^;)


NOOPENGL について改めて調べたところ、前項に書いた PC6001VX.proX11 関連の定義の「linux以外」の部分で記載するところに「QT += x11extras」を書き忘れていたのが原因ということがわかりました。

QT += x11extras」の記載を追加して、さらに pkgsrc/x11/qt5-qt5tools では入らない pkgsrc/x11/qt5-qtx11extras をインストールしてやることで NOOPENGL を定義しなくても正常に動くバイナリが作成されるようになりました。

pkgsrc的整備

一応 pkgsrc の枠組みでも動くものができたので、後は細々と記載を整備して一応完了です。

  • 依存バイナリの精査
    → qmake は qtbase にあって qttools は不要。 qtbase, qtmultimedia, qtx11extra のみでOK
  • README.html のインストール (man がないので)
  • pkglint 実行と修正
  • パッチのコメント追加

とりあえずこのままコミットしてしまってもいいとは思うのですが、 pkgsrc は担当外なのもあって新規パッケージ追加にはそれなりに気合いが必要なのと、書いた当日にコミットすると速攻でミスを指摘されるという経験則があるので、しばらく置いてからなんとかします。

pkgsrc 化してみて

自分の慣れた環境で「思いついたらすぐにソースから修正していろいろ試せるようになった」というのは大きいですね。

当然かもしれませんが、Tiny野郎さんのイース2デモもエンディングは動きました。

ただし、 PC-6001用互換BASIC だとイース2オープニングは何かしらおかしいようです。エミュレータの問題ではないと思いますが、これもせっかくなので調べてみたいところです。
※2017/2/17追記: 互換BASIC 0.6.1 の更新で動くようになりました


テープのヘッダ音時間やストップビット長の設定については、タイニーあぴミクさんデモやテグザーエンディングデモの実行にも影響する(ロードして即VRAM転送、つまりロードにかかる実時間がそのまま描画時間になるので、それでBGMとタイミングを合わせている)ので、こちらもそのうちなんとかしたいですね……。