/usr/lib以下に入っているlibicucore.dylibを自分のコードから使う方法
libicucore.dylib。どう見てもICUのダイナミックライブラリ。存在は知りつつも、どういうわけかヘッダファイルが添付されていないため、自分のコードから使うことができず、歯がゆい思いをしている人も多いんじゃないだろうか。
-rw-r--r-- 1 root wheel 6941856 7 31 14:16 /usr/lib/libicucore.A.dylib lrwxr-xr-x 1 root wheel 18 12 23 2007 /usr/lib/libicucore.dylib -> libicucore.A.dylib
ここなどを参考にこれを使う方法を考えてみたので書いてみます。
追記:make install DESTDIR=...がmake DESTDIR=...になっていたのを修正。
手順
1. OSに添付されているICUのバージョンを調べる
次のコードをコンパイル、リンクして実行するとバージョンを調べることができる。
check_icu_version.cpp
#include <iostream> extern "C" void u_getVersion(char[4]); main() { char v[4]; u_getVersion(v); std::cout << static_cast<int>(v[0]) << '.' << static_cast<int>(v[1]) << '.' << static_cast<int>(v[2]) << '.' << static_cast<int>(v[3]) << std::endl; }
コンパイルとリンク:
$ g++ -o check_icu_version -licucore check_icu_version.cpp
実行例:
$ ./check_icu_version 3.6.0.0
2. 同じバージョンのICUをダウンロードし、ビルドする
ビルドオプションなどは以下。
$ tar xfz icu4c-3_6-src.tgz $ cd icu/source $ ./configure --prefix=/usr \ --mandir=/usr/share/man \ --disable-renaming \ --disable-draft \ --disable-icuio \ --disable-layout \ --disable-extra $ make
ビルドが終わったら、DESTDIR=を使って、適当なステージングディレクトリにインストールする。
$ make install DESTDIR=/tmp/staging
3. ライブラリを除くファイルを/usrにコピーする。
$ sudo -s -H # cp -R /tmp/staging/usr/share /usr # cp -R /tmp/staging/usr/include /usr # exit $
ためしてみる
あんまいけてないコードだけど。
#include <memory> #include <stdexcept> #include <clocale> #include <iostream> #include <unicode/datefmt.h> #include <unicode/calendar.h> #include <unicode/ucnv.h> #include <langinfo.h> main() { std::setlocale(LC_ALL, ""); const char* codeset = nl_langinfo(CODESET); UDate date = Calendar::getNow(); std::auto_ptr<DateFormat> dfmt(DateFormat::createInstance()); UnicodeString str; dfmt->format(date, str); { char buf[1024]; UErrorCode err; UConverter* cnv = NULL; try { cnv = ucnv_open(codeset, &err); if (!cnv) throw std::exception(); int32_t len = str.extract(buf, sizeof(buf) - 1, cnv, err); if (U_FAILURE(err)) throw std::exception(); buf[len] = '\0'; std::cout << buf << std::endl; } catch (std::exception const&) { std::cerr << "error" << std::endl; } if (cnv) ucnv_close(cnv); } }
ビルドと実行結果は次のような感じ:
$ g++ -o /tmp/test /tmp/test.cpp -licucore $ ./test 08/10/24 17:51