〜2013年11月上旬〜
trunkのrubyがAndroid 4.0.xだと起動すらせずになぜかSEGVる原因を調べた。
まずは古いので試したら1.8.7だと普通に動く。
というわけでとりあえずrubyをリンクしているgccのオプションを比較してみる。
怪しいのは-pieだがこれを外してみたらビンゴだった。
Android NDK, Revision 8cのこれか?
Updated build so that executables using android-16 (Jelly Bean) or higher are compiled with the -fPIE option for position-independent executables (PIE). A new APP_PIE option allows you to control this behavior. See APPLICATION-MK.html for details.
--disable-rubygemsで作ればruby自体はどこでも動くが、
ライブラリを使うときはprefix固定なので-Iで指定する必要がある。
Androidに限らないが、普通にconfigureすると/usr/localがprefixになってしまって、
インストールする場所が固定されてしまう。
Androidだと--prefix=/systemにすると都合がいいが、
ここはroot取らないと書けない。
かと言って--prefix=/data/local/tmpとするのもPATHをいじらないといけないし、
今度は/systemに置けなくなるので不自由。そこで--enable-load-relativeだ。
これはdladdr(3)を使いprefixをexpand_include_pathという関数が存在するファイル
つまりLibruby共有ライブラリか実行ファイルであるruby自身からの相対にしてくれる。
どちらの場合もその1つ上のディレクトリがprefixになる。
ライブラリがこのように配置されていればどこに移動しても問題なく動く。
shell@grouper:/data/local/tmp $ bin/ruby -e 'p $:[0]' "/data/local/tmp/lib/ruby/site_ruby/2.1.0" shell@grouper:/data/local/tmp $ mkdir foo shell@grouper:/data/local/tmp $ cp -r bin foo shell@grouper:/data/local/tmp $ foo/bin/ruby -e 'p $:[0]' "/data/local/tmp/foo/lib/ruby/site_ruby/2.1.0"
このようにrubyのある位置でprefixが
/data/local/tmp/
から
/data/local/tmp/foo
へ変化しているのがわかる。
自分がいるディレクトリがbinじゃないときは1つ上にはならない。
shell@grouper:/data/local/tmp $ ./ruby -e 'p $:[0]' "/data/local/tmp/lib/ruby/site_ruby/2.1.0" shell@grouper:/data/local/tmp $ mkdir foo shell@grouper:/data/local/tmp $ cp ruby foo shell@grouper:/data/local/tmp $ foo/ruby -e 'p $:[0]' "/data/local/tmp/foo/lib/ruby/site_ruby/2.1.0"
AndroidのdladdrはAndorid 4(API Level 8)から使える。
make-standalone-toolchain.shするときは--platform=android-8で。
configureに--enable-load-relativeつければprefixはどうでもいいが、
tarballを作るには一度installする必要がある。そのときにprefixが影響する。
--prefix=""とか--prefix=/のような感じで指定できればいいが、
これは今は想定外のようでビルドエラーになったり、
区切り位置がおかしくなったりするのでやめたほうがいい。
適当に--prefix=/xとかにしておくのが無難。
まとめると
--enable-load-relative --disable-rubygems --prefix=/x
をクロス用のオプションに追加する。
あとdocumentも不要だと思うので以下のようにしてインストールする。
--disable-install-doc --disable-install-rdocしてないのは
後で普通にmakeすれば作ることも可能なように。
% make main install-nodoc DESTDIR=/tmp
ここから不要なものを削除する。
lib/libruby-static.aとlib/pkgconfigはAndroid上でbuildするわけではないので不要。
あとちょっとでも小さくするためにstripしておく。
% rm -r /tmp/x/lib/{libruby-static.a,pkgconfig} % arm-linux-androideabi-strip --strip-unneeded /tmp/x/{bin/ruby,lib/**/*.so}
準備できたのでtarballを作る。
% tar cfvz ~/ruby-trunk-android.tar.gz bin lib -C /tmp/x
あとは~/ruby-trunk-android.tar.gzをadb pushしてadb shell上でbusybox tarして展開する。
% adb push ~/ruby-trunk-android.tar.gz /data/local/tmp % adb shell shell@grouper:/ $ cd /data/local/tmp shell@grouper:/data/local/tmp $ ./busybox tar xfv ruby-trunk-android.tar.gz shell@grouper:/data/local/tmp $ bin/ruby -ve 'p $:[0]' ruby 2.1.0dev (2013-11-03 trunk 43521) [arm-linux-android] "/data/local/tmp/lib/ruby/site_ruby/2.1.0"
ああ、libruby-static.aとか消さなくても、tarball作るときに
% tar cfvz ~/ruby-trunk-android.tar.gz bin lib/ruby -C /tmp/x
のようにlib/rubyとすればいいか。
Androidでメールアドレスとか入力するのが面倒で、
どうせだいたいUSBケーブルがつながってるのでadb shell input textするわけなんだけど、
US配列のキーボードのせいか記号が全然別の文字になってしまい困る。
いろいろ試してみたらどうもこんな対応になってるようだ。
!@#$%^&*()-_+=\|`~[{]};:,<.>/?"' !"#$%&'() -=~^]} [{]};+,<.>/d*:
?がなんでdになるかというと/dが存在するからだ。クォート処理がおかしいな。
% adb shell input text '\\?'
と実行すると]?になるので?は?なんだろう。
なんで二重にクォートする必要があるのか。しかも\が残ってしまうし。
`と~はソフトキーボードのon/offになってる模様。
今のことろ`を送る方法がわからない。まあ、あまり困らないが。
notepadとかツールチップで出てくる。押してみると本当にメモ帳が立ち上がる。
なんだこれとぐぐってみたら単に消し忘れただけらしい。
Tab Utilities :: Reviews :: Add-ons for Firefox
消したいときはabout:configで以下をfalseに。
extensions.tabutils.button.button_Notepad extensions.tabutils.button.button_TotalCommander extensions.tabutils.button.button_UltraCompare extensions.tabutils.button.button_UltraEdit extensions.tabutils.button.button_UltraSurf
Android版busyboxはuClibcが静的にリンクされてるらしく、
deviceのタイムゾーンをいじってもdateの表示はUTCのままになってしまう。
普通に環境変数TZをJST-9でもいいが、/etc/TZにJST-9と書いてもいい。
でもroot取らないとそこには書けない。
どういうわけかadb shellはonlcrになっていて、LFがCR+LFへ変換されてしまう。
% adb shell echo | od -c 0000000 \r \n 0000002たぶんWindowsのコマンドプロンプトでも、
% adb shell '/data/local/tmp/busybox stty -onlcr;echo' | od -c 0000000 \n 0000001
覚えにくいのでstty rawとかstty nlでもいい。
% adb shell '/data/local/tmp/busybox stty raw;echo' | od -c 0000000 \n 0000001 % adb shell '/data/local/tmp/busybox stty nl;echo' | od -c 0000000 \n 0000001
これでスクリーンショットもわざわざ一度device内のSDカードとかに保存しなくてもok。
% adb shell 'screencap -p' > foo.png % file foo.png foo.png: data % adb shell '/data/local/tmp/busybox stty nl;screencap -p' > foo.png % file foo.png foo.png: PNG image data, 800 x 1280, 8-bit/color RGBA, non-interlaced
delicious側でチェックするのやめて、素直にdiigo側でチェックするようにした。
signin処理が面倒だと思ったが、browserのcookieを使えばいいので、
curl -sLO -b ~/cookies.txt https://www.diigo.com/tools/save_to_others
の結果をgrepするだけでokだった。
久し振りにzopfliのページへ行ってみたら
zopflipngなるものが。
これでpngもzopfliで圧縮できるわけか。最近の
AdvanceCompでもいけるらしい。
optipngとか並列にやらせたいときに
% find *.png -print0 | xargs -r0 -P4 -n1 optipng
みたいなことしていたが、man xargsしたら0を指定すれば可能な限りがんばってくれるようだ。
--max-procs=max-procs -P max-procs Run up to max-procs processes at a time; the default is 1. If max-procs is 0, xargs will run as many processes as possible at a time. Use the -n option with -P; otherwise chances are that only one exec will be done.