その後のlibwcsmbs その他


X_LOCALEを捨てようでも書いているように、libwcsmbsというパッケージを愛用している。RedHat-5.2で日本語を使える環境を整えたいのですが… などという質問をfj.os.linuxやinux-users MLなどでチラホラ見かけるようになったので、ちょっとオレのわかる範囲で整理してみようと思う。

libwcsmbsの実装およびメンテナンスは、Debianの吉山さん、鵜飼さんがやっておられて、オレが書いたわけではないので、ひょっとするとなにか誤って理解しているかもしれないけど… また、libwcsmbsおよびwcsmbs-localeは開発の過程にあり、次々とバージョンアップしている最中だ。だから、一応今日の日付を書いておく。98年12月21日現在だ。

まず、libwcsmbsは今のところ、libwcsmbs-0.0.5-2.i386.rpmが最新だと思う。このパッケージの内容は

/lib/libwcsmbs.so.0
/usr/i486-linux-libc5/lib/libwcsmbs.so.0

となっている。これは、/lib/libwcsmbs.so.0 が glibc2 つまり libc6 用、/usr/i486-linux-libc5/lib/libwcsmbs.so.0 が libc5 用だ。libc5用、というのはつまり、RedHat 5.2の上で、従来のlibc5をベースとしたバイナリを実行する際に必要とされるということ、なのだが、もしもlibwcsmbs-0.0.5-1を使っている場合は、 /usr/i486-linux-libc5/libwcsmbs.so.0 となっていると思う。

RedHat-5.2(に限らず5.xでは)libc5関連のライブラリはみな/usr/i486-linux-libc5/lib に置かれるようになっており、/etc/ld.so.conf にもそのように記述されている。だから、libwcsmbs-0.0.5-1.i386.rpm (ないしはそれ以前のもの)を使っている場合はlibc5 なバイナリは軒並み core 吐いてブチ落ちるので注意だ。すぐにlibwcsmbs-0.0.5-2に差し替えるのをすすめる。

さて、libwcsmbs の相方の wcsmbs-locale だが、ソースレベルでの最新版は 0.4.9 だと思う。rpm のパッケージでは、 PJE-0.3alpha のwcsmbs-locale-0.4.8-1.i386.rpm が最新だろう。

wcsmbs-locale だが、これは中身を見ると /usr/lib/wcsmbs/ の下に ja_JP.ujis とかko_KR.euc とか、locale に対応したディレクトリが構成されており、その中にはwcsmbs.so というシェアド・ライブラリが置かれるようになっている。また同時に/usr/share/locale/ の下に、locale dataが各localeごとに置かれるようになっている。

wcsmbsって最近見かけるけど、実際のところ何なの?という疑問もあろう。

glibc-2.0.7になり、localeの整備が行われているのだが、悲しいかな日本語(のみならず韓国語、中国語も)のlocaleは依然として扱うことができないままだった。これには2点あって、1つは日本語locale での locale dataが用意されていないこと。特にLC_CTYPE、LC_COLLATEなどは文字列操作の上では必須なので、これを用意し補うことが必要だ。

2つめは、日本語の各localeで用いるエンコーディング(EUC-JPとかiso-2022-jpとか)をサポートしていないので、これをサポートする処理部を追加してglibcを補う必要がある。glibcは内部的に文字を wide char (UCS4だと思う)として扱うことで、locale独立(localeを切り替えられても不都合がない)になっている(と思う)。

が、通常はEUC-JPとかiso-2022-jpとかをファイル入出力や表示には使用するので、実際の処理においては wc(wide char) と mb(multi byte char、EUC-JP とかiso-2022-jp とかを総称して) が双方向に変換できなくては実用にならないのだ。

で、上記2点を補完してくれるのが wcsmbs-locale と言うことができる。/usr/share/locale の下の入る locale data と、/usr/lib/wcsmbs の下に入る wcsmbs.so で上記2点セットなのだ。

このグッドな wcsmbs-locale を、ぢゃあどうやって glibc と一緒に働かせるの?というと、現状では2通りの方法があり、1つは glibc そのものに手を入れ(パッチをあて)、各localeごとの wcsmbs.so を必要に応じて動的にロードしてやる方法。これがいわゆる glibc+wcsmbs と言われるヤツで、glibcそのものを全て差し替えてやる必要がある。

今の最新は、PJE-0.3alpha の glibc-2.0.7_wcsmbs041-25.src.rpm が一番手堅いだろうか。RedHat-5.2 の glibc は glibc-2.0.7-29.src.rpm だから、微妙にリリースが古くなってしまうのは、パッチあての必要がある以上仕方のないところだろう。もちろん自分でビルドして人柱してみるコンダラな人なら、PJEからwcsmbs対応glibc のソースをもらってきてspecを読み、redhat-5.2の最新glibcに同じ様にパッチをあてても行けると思う。

で、もう1つのwcsmbs使用法だが、これがlibwcsmbsだ。本体となるglibcには手を付けず、libwcsmbsを追加することで、各localeごとの wcsmbs.so を必要に応じて動的にロードするのを libwcsmbs に任せるという方法だ。この方法のメリットは、もちろんglibcをリビルドしたり差し替えたりする必要がないこと、これに尽きる。RedHatからglibcのセキュリティ・リリースなどがもしも出た場合でも、単にそれを入れさえすれば良いのだ。

整理すると、

上記のどちらか、ということになろうか。つまり、wcsmbs-locale は常に必要なのだ。たまに libwcsmbs を入れたのですが、日本語が使えません、などといって困っている人がいるが、肝心の wcsmbs-locale を入れてなかったりするので忘れずに入れるようにしよう。

また、逆のパターンとして、生の glibc と wcsmbs-locale を入れたが、libwcsmbs を入れない人もいたりすると思う。生 glibc でも、wcsmbs-locale を入れれば少なくとも locale data は入るので、setlocale() などでエラーにはならなくなる。アプリによっては一見日本語が使えたりするのだが、実際には厳密に wide char を意識した I18n を施されたプログラムでは日本語が使えないので注意が必要だ。

生glibcとwcsmbs-localeを入れても、それだけでは、肝心の wcsmbs.so が動的にロードされることはない。つまり、wc <-> mb 間の変換ができないままだから期待通りには動かないのだ。

と、わかる範囲で整理してみたつもりだが、ここでちょっと気になることが。

wcsmbs-locale なのだが、現在の最新版はソースレベルでは 0.4.9 で、パッケージとしては 0.4.8-1 がある。が、どうもこの 0.4.8 も 0.4.9 も、ja-JP.ujis でしか確認していないのだが、wcsmbs.so がうまく動いていないようだ。

Mozilla や GTK+ ベースのアプリで日本語が正常に入力できなかったり、改行コードが入力できなかったりする人はいったん 0.4.6 に戻してみよう。正常に動くようになったんじゃないかな?

ちょっとゴタゴタして忙しく、まだソースは見比べてないんだけど、0.4.10(がもし出たなら)では直っていることを期待している。本当なら詳しく調べて貢献したいのだが… 使うばかりでごめんなさい m(__)m

あ、そうそう、開発版の glibc なのだが、glibc-2.0.107 から花高さんのパッチが取り込まれ、iconv() で日本語な locale が正しく扱えるようになっている。ただ、locale data そのものにはまだ不備があるようだ。

もちろんゴリゴリ locale data を用意してもよいのだが、問題の根っこは locale data を定義する localedef コマンドが multi byte なデータを食わせるとcore吐いてブチ落ちてしまい、locale dataを簡単に整備できないところにある。逆にいうと、localedef を hack して multi byte を解するようにしてしまえば、locale dataの微調整も容易になり、一気にケリがつく気配が濃厚だ。素晴らしいね。

あ、glibc-2.0.107のrpmは glibc-2.0.107-0.981217.src.rpm がrawhideのサイトから取れる。同時に kernel-2.1.131-5.src.rpm も持ってこよう。kernel 2.1系のヘッダ・ファイルがないとコンパイルできないから注意だ。


メール 戻る