ncurses 5.9をAndroid NDKでクロスコンパイルする

http://ftp.gnu.org/pub/gnu/ncurses/ から ncurses-5.9.tar.gz をダウンロードします。

Androidでビルドするため、locale.hが存在しないかのようにconfigureに対して環境変数をセットする必要があります(理由は後述)。

それ以外は特に気をつける点はありません。下記の実行例の場合、C++バインディングを外す指示と*.soを作る指示を追加しています。

$ tar xvzf ncurses-5.9.tar.gz
$ cd ncurses-5.9
$ CFLAGS=-O2 LDFLAGS=-s ac_cv_header_locale_h=no ./configure --host=arm-linux-androideabi --prefix=$ANDROID_APP_ROOT/ncurses-5.9 --with-shared --without-cxx-binding
$ make
$ make install

Android NDKのロケールについて

Android NDK r9時点ではロケールの実装はスタブ実装になっています。ロケールが必要ならSDK使ってねという発想でしょうから、今後もNDKレベルで実装されることは無いでしょう。

それはそれでいいのですが、ロケール周りが下記のように中途半端なスタブ実装になっているため各種OSSのconfigureが混乱しがちです。

  • locale.h:ある
  • setloacle(3):ある、特に仕事はしない
  • LC_CTYPEなどのenum定数:ある
  • localeconv(3):ヘッダファイルでは定義されてるけど実体がないのでリンクに失敗する
  • lconv構造体:定義されてるけどメンバ数がゼロ

実際、ncursesはlocale.hが存在したらロケール周りがフル実装されていると判断するものの、localeconvが無いのでビルドが通りません。

Androidでのビルドということを考えると、一般論としては「configure --disable-locale」するのが正解だと言えます。ただし、ncursesのconfigureでは--disable-localeが提供されていないため、今回はlocale.hが存在しないかのようにautoconfのcache variableを環境変数として渡したというわけです。

installed files

bin/captoinfo
bin/clear
bin/infocmp
bin/infotocap
bin/ncurses5-config
bin/reset
bin/tabs
bin/tic
bin/toe
bin/tput
bin/tset
include/ncurses/*.h
lib/libform.a
lib/libform.so
lib/libform.so.5
lib/libform.so.5.9
lib/libform_g.a
lib/libmenu.a
lib/libmenu.so
lib/libmenu.so.5
lib/libmenu.so.5.9
lib/libmenu_g.a
lib/libncurses.a
lib/libncurses.so
lib/libncurses.so.5
lib/libncurses.so.5.9
lib/libncurses_g.a
lib/libpanel.a
lib/libpanel.so
lib/libpanel.so.5
lib/libpanel.so.5.9
lib/libpanel_g.a
lib/terminfo/
man/man?/*.?
share/tabset/*
share/terminfo/??/*

インストール時の注意

ロスコンパイル環境でもterminfoディレクトリは作られるんですが、なぜかMacOSX上でmake install.dataするとterminfoディレクトリの下に「31」のように2文字のディレクトリができてしまい、これをAndroidに持っていっても期待通りには動きません。

正しく動かすには、Android上でticコマンドを動かす必要があります。