NetBSD Advent Calendar 2021 3日目の記事です。
今日はFreeBSD Advent Calendar 2021の2日目の記事で紹介したLibXoをNetBSDでも動かしてみようと思います。
LibXoとは?
FreeBSD Advent Calendar 2021の2日目の記事でも解説していますが、LibXoはFreeBSD-11以降でサポートされた、任意のデータをテキスト、XML、JSON、HTMLの各フォーマットで出力するライブラリです。
LibXoの出力例
LibXoを組み込んだコマンドは出力をJSON/XMLで行うことが可能となり、実際、FreeBSDのベースコマンドのいくつかはLibXoを使用して出力できる状態になっています。
$ # FreeBSDでの出力例。
$ freebsd-version -ku
13.0-RELEASE
13.0-RELEASE
$
$ ldd `which ps`
/bin/ps:
libm.so.5 => /lib/libm.so.5 (0x80024d000)
libkvm.so.7 => /lib/libkvm.so.7 (0x800280000)
libjail.so.1 => /lib/libjail.so.1 (0x800295000)
libxo.so.0 => /lib/libxo.so.0 (0x80029d000) ★★★ LibXoを参照している ★★★
libc.so.7 => /lib/libc.so.7 (0x8002be000)
libelf.so.2 => /lib/libelf.so.2 (0x8006cf000)
libutil.so.9 => /lib/libutil.so.9 (0x8006eb000)
単に ps
と実行すると、通常の出力になります。
$ # 通常のpsコマンドの出力。
PID TT STAT TIME COMMAND
40356 10 I+J 0:04.92 vim hello_libxo.c
84320 10 IsJ 0:00.21 -bash (bash)
41790 11 I+J 0:00.01 /bin/sh /usr/bin/man xo_emit
41801 11 I+J 0:00.00 less
84440 11 IsJ 0:00.09 -bash (bash)
22328 9 IsJ 0:00.01 -bash (bash)
22368 9 I+J 0:00.00 less
22362 15 IsJ 0:00.01 -bash (bash)
22365 15 I+J 0:00.00 less
20087 19 SsJ 0:00.02 -bash (bash)
20131 19 R+J 0:00.00 ps
ps --libxo json,pretty
とすると、JSON形式で結果が出力されます。
$ # JSON形式で出力させる。
$ ps --libxo json,pretty
{
"process-information": {
"process": [
{
"pid": "40356",
"terminal-name": "10 ",
"state": "I+J",
"cpu-time": "0:04.92",
"command": "vim hello_libxo.c"
},
...
{
"pid": "20129",
"terminal-name": "19 ",
"state": "D+J",
"cpu-time": "0:00.00",
"command": "-bash (bash)"
}
]
}
}
また、 ps --libxo xml,pretty
とすると、XML形式で結果が出力されます。
$ ps --libxo xml,pretty
<process-information>
<process>
<pid>40356</pid>
<terminal-name>10 </terminal-name>
<state>I+J</state>
<cpu-time>0:04.92</cpu-time>
<command>vim hello_libxo.c</command>
</process>
...
<process>
<pid>20143</pid>
<terminal-name>19 </terminal-name>
<state>R+J</state>
<cpu-time>0:00.00</cpu-time>
<command>less</command>
</process>
</process-information>
これはなかなか便利そうです。例えばJSON形式で出力させて、 jq
コマンドとJSONPathで項目を抽出するといった応用も可能です。
NetBSDでもLibXoを使ってみる
さて、この便利なLibXoをNetBSDでも使ってみたいというのが人情(?)です。さっそくNetBSDでLibXoをビルドする所から試してみます。
NetBSDでのLibXoビルド手順
まずはビルドに必要なツールやライブラリをパッケージ経由でインストールします。
$ sudo -i pkg_add -v \
git \
ca-certificates \
autoconf \
automake \
autogen \
libtool
次にLibXoのソースコードを入手します。LibXoはGitHubで公開されており、そこから git clone
します。
$ git clone https://github.com/Juniper/libxo.git -b develop
$ cd libxo
$ sh ./bin/setup.sh
...
Creating build directory ...
Setup is complete. To build libslax:
1) Type 'cd build ; ../configure' to configure libslax gmake
2) Type 'make' to build libslax
3) Type 'make install' to install libslax
sh ./bin/setup.sh
を実行後、表示された一連のビルド手順にそって作業を進めます。
ただし、一点注意が必要な個所として、LibXoは GNU Make
を想定しているため、NetBSD上でビルドする場合は、 MAKE=gmake ../configure
と指定する必要があります。
$ # BSD系でのビルドは"MAKE=gmake"指定が必要。
$ cd build ; MAKE=gmake ../configure --prefix=/opt/libxo
...
configure: summary of build options:
libxo version: 1.6.0 -git-develop
host type: x86_64-unknown-netbsd9.1 / netbsd9.1
install prefix: /usr/local
srcdir: ..
libdir: ${exec_prefix}/lib
bindir: ${exec_prefix}/bin
includedir: ${prefix}/include
share dir: /usr/local/share/libxo
extensions dir: ${exec_prefix}/lib/libxo/encoder
oxtradoc dir:
compiler: gcc (yes)
compiler flags: -g -O2
library types: Shared=yes, Static=yes
warnings: no
debug: no
printf-like: no
libxo-options: yes
text-only: no
gettext: no (none)
isthreaded: no
thread-local: before
local wcwidth: yes
retain size: default
$
$ # GNU Make(gmake)でビルドする。
$ gmake
$ gmake test
$ sudo gmake install
これでLibXoのビルドは完了です。思いのほかサクッとビルドできました。
LibXoを用いたサンプルプログラム
さっそく簡単なサンプルプログラムを試してみます。先にFreeBSDの ps
コマンドの出力を示していたので、NetBSDでも ps
コマンドの出力をJSON/XMLで行ってみます。サンプルはGistに置いてあります。
コンパイルは以下の手順で行います。
$ gcc \
-Wall \
-g \
-o sample sample.c \
-I/opt/libxo/include \
-L/opt/libxo/lib -lxo
実行ファイルに --libxo json,pretty
オプションを指定することで、 ps
コマンドの結果がJSONで出力されます。
(FreeBSDでの ps --libxo json,pretty
と同等の出力になります)
$ LD_LIBRARY_PATH=/opt/libxo/lib ./sample --libxo json,pretty
{
"process-information": {
"process": [
{
"pid": "0",
"terminal-name": "?",
"state": "DKl",
"cpu-time": "4:10.49",
"command": "[system]"
},
...
{
"pid": "644",
"terminal-name": "ttyE3",
"state": "Is+",
"cpu-time": "0:00.00",
"command": "/usr/libexec/getty Pc ttyE3 "
}
]
}
}
まとめ
NetBSDでのLibXoビルドとサンプルプログラムを動かすところまで試してみました。LibXoをアプリケーションに組み込んでおくことで、通常のテキスト出力だけでなく、JSON/XMLでの出力が可能になるため、積極的に利用して行きたいところです。