LoginSignup
0
0

More than 1 year has passed since last update.

ZRouterでのバイナリ追加方法

Last updated at Posted at 2017-02-03

FreeBSDをmipsなルータのFlashに焼くためにZRouterでカーネルとrootfsを作っているが、rootfsにバイナリを追加する方法を考えてみる。

現状

ZRouterではprofileという仕組みで追加のバイナリなどを管理している。これの実体はtargetかportsというディレクトリにあり、targetはFreeBSDのソースツリーの一般のプログラムと同じようにコンパイルしてコピーする仕組みで、portsはFreeBSDのportsを使った仕組みになっている。targetは同じディレクトリにファイルを置く事もできるが、ほとんどがcontribといディレクトリに実際のファイルを置いている。元々のZRouterのportsは/usr/local/binではなく、/usr/binにファイルを置いていた。ZRouterにはpackagesというディレクトリがあるが中身が空だ。

問題点

  • targetは新たにFreeBSD風のMakefileを作る必要がある
  • portsはFreeBSDのportsのMakefileがそのまま流用できない
  • configureを使うportsの場合、hostの設定を使ってしまいうまく動かない事がある
  • ZRouterは旧pkgの頃に作られていて、現在のpkgでインストールする方法が動かない
  • ZRouterのportsのワークディレクトリはアーキテクチャを区別してない
  • 本体のportsも同じだがgithubにあるファイルだけでリリースアーカイブを作らないプロジェクトのビルドができない
  • 本来のportsはStageありとなし(古いもの)がありインストール方法が違う
  • オブジェクトパスの変更が行われてtargetがZRouterのツリーでビルドされるようになってしまった。これにより誤って違うアーキテクチャのバイナリが入ってしまうことがある。(追加)

考察

新たに仕組みを作るのはあまり現実的ではない
FreeBSD/mipsはビッグとリトルのエンディアンがある
/usr/includeを使ってしまいクロスビルドしてもホストとターゲットに差がなければ問題にはならないかも
リソースの制限やなんらかの要因でamd64では動いてFreeBSD/mipsでは動かない事もある
qemuな環境でビルドすれば完全なパッケージが作れるが、環境を作るのが大変で、コンパイルコストも大きい。またビルドに利用するツールまで用意する事になるので、とっても大変
embedな環境はpkgの追加はできないのでpkgにする必要性がないかも
portsは元々pkgを作成するための仕組みであり、pkgを使わないZRouterでは位置づけが違う
manのファイルなどいらないものも多い
追加の対象は限定的
portsと同じコードベースだと脆弱性なの問題の対応がしやすい
複数の依存があるようなものは、頑張らないで、ほかの選択肢を考えた方がのかも

当面の方針

  • 本家portsをできるだけ再利用する
  • 出来るだけバージョンは本家portsを追従する
  • hostシステムを壊さないようにroot権限は使わない
  • configureを使っている場合はクロスコンパイルのため以下を追加する(ARCHはビルドホストのamd64が入り、実はこれは間違えでhostはターゲットのアーキテクチャを指定するのが正しいが、soが作られないなどの問題があるので、こうしている。)
CONFIGURE_ARGS+=--host=${ARCH}-portbld-freebsd
  • openvpnはプログラム中でもhostの値を使っていたので、ZARCHで設定するようにしました。
# ./openvpn 
OpenVPN 2.5.3 mips-portbld-freebsd [SSL (OpenSSL)] [LZO] [MH/RECVDA] [AEAD] built on Mar 11 2022
  • ファイルのコピー(インストール)はMakefileのdo-install:に書く
  • do-installをマクロで実行している場合はstageにコピーされたファイルをpost-installでターゲットのrootfsにコピーするようにします。
  • do-installを自前で処理している場合は、それを書き換えてターゲットのrootfsにコピーする。
  • ライブラリファイルは必要な物だけコピーする。
  • ライブラリの場合はヘッダーもコピーして、依存するものはこれを参照するようにする。
  • pkgconfのpcファイルもコピーする。
  • ZRouterの標準のビルドはpkgに依存しないが、ほとんどのportsは依存する。また/usr/portsへの依存も発生する。
  • OPTIONはdbへの登録のためのroot権限が必要になるので全部外す。 DBは独自の持つようにしたので、OPTIONは使えるが、原則は外す。
  • 本家のportsと区別するために「portsもどき」と呼ぶことにする。
post-install:
        ${INSTALL_LIB} ${STAGEDIR}${PREFIX}/lib/libexpat.so.1.6.2 ${ZPREFIX}/lib/libexpat.so.1
        cp ${STAGEDIR}${PREFIX}/include/*.h ${ZPREFIX}/include/
        cd ${ZPREFIX}/lib;ln -s libexpat.so.1 libexpat.so

  • pkgは使わない
    -L/usr/libをconfigureがMakefileに入れてしまう場合はpost-configure:で削除する(例:security/racoon2)
post-configure:
        @${REINPLACE_CMD} -e 's|-L/usr/lib||g' ${WRKSRC}/iked/Makefile
  • ビルド用にコマンドをビルドして利用する場合は/usr/bin/ccでコンパイルする(例:www/lighttpd,lang/mruby)
# for lemon cross-compiling
CONFIGURE_ENV+= "CC_FOR_BUILD=/usr/bin/cc"
  • ライブラリなど依存が発生する場合はtargetでも良いかも(例:mrubyとtarget/lib/libuv)
  • gmake, autoconfなどはpkgでインストールする。この時/usr/portsのファイルとバージョンが違う場合に問題が起きることがあるのでportsをupdateしておく。
  • 設定などは環境変数で引き渡す方法もある(例:lang/mrubyのMRUBY_CONFIG)
  • configureが何をチェックしているかはそれぞれなので、臨機応変に考える
  • 追加のファイルは/usr/local以下にコピーする
  • 完全を狙ってコストをかけすぎない

configure

configureがチェックは以下のような事が考えられる

  • 使用するライブラリの有無
  • コンパイラーの種類
  • OSの種類
  • CPUのビット数
  • などなど

ZRouterのportsでのconfigureの実行は、半端な状態で/usr/local/を参照するのだが、実際は別のディレクトリにライブラリがあったりする。またコンパイラのチェックも正しく行われない。自分の必要なものしか追加しないのだが、ぼちぼち整理したい。

当初configureがhostのccを使って動いてしまっていたので、直しました。

いろいろ

ZRouterの連絡網がircなので、ircクライアントのビルドを試してみました。最初にirssiを試したのですがあまり依存は多くなかったのですがglibや他のライブラリがクロスビルドが大変だったので、あきらめました。次にweechatを試してみたのですが、こちらはlibcurlとgnutlsの依存があり、これがいろいろな依存を作ってしまっていたので、あきらめました。bitchxという古くからあるソースはどうにかビルドできました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0