Proj.4をemscriptenでコンパイルしようとして、こちらのページに
./configure
make
を
emconfigure ./configure
emmake make
emcc [-Ox] project.bc -o project.js
に変えればOKよ、と書いてあるのに、全然できひんやん…jsファイルはできるのに中身がない…で絶望の中1ヶ月止まってましたが、先週末はっと気付いてコンパイルできるようになりました。
emconfigureとか挟んでたりバイトコードからのコンパイルなのでうっかりしてましたが、よく考えればemccでのコンパイルなので、EXPORTED_FUNCTIONSで吐き出す関数指定してやらないと、そら最適化で全部消えるわ…。
で、とりあえずできるようになったので手順。
proj4ソースを落としてくる
こちらからどうぞ。
configure, make
展開したフォルダ内で、
emconfigure ./configure
emmake make
残したい関数を選んで、make
Proj.4の提供しているAPIは、こちらに一覧があります。
何でも出せると思いますが、まあpj_transformとpj_init_plusは出さないとどうしようもなりませんな。
あと、以前の紹介でも書きましたが、emscriptenはjavascriptの型で返す関数を提供してくれるわけではないので、入出力のデータ加工のために、cの関数も一緒に出しておいた方がいいでしょう。
サンプルではstrlen, free, strncpy, memset, malloc, memcpy, strcpy, pj_init_plus, pj_transformあたりを残しておくものとします。
また、Macの場合、makeするとコンパイル結果は[展開フォルダ]/src/.libs/libproj.dylib に展開されます。
libproj.aからもjsは作られますが、共有ライブラリから作った方がいいとどこかにあったのでdylib使います。
他の環境では、.aや.so、*.bc等違うかもしれません。
そもそも展開先も違うかも。
emcc -O2 [展開フォルダ]src/.libs/libproj.dylib --pre-js js/pre.js --post-js js/post.js -o js/emproj.js -s EXPORTED_FUNCTIONS="['_strlen','_free','_strncpy','_pj_init_plus','_memset','_malloc','_pj_transform','_memcpy', '_strcpy']"
pre.js、post.jsというのは、emscriptenの生成したjavascriptコードの前後につけて、コロッとしたjavascriptモジュールにするためのファイルです。
自分で作んないとダメです。
emscriptenのコードはグローバル汚染しまくりますし、そもそもjavascript的インタフェース持ってないのでそのままだと使い難くてしょうがありません。
pre.jsとpost.jsでくるんで、使い易くしてやりましょう…が、とりあえずは空ファイルでもいいです。
なんかエラー出るので対処
どうもバグっぽいのでまたレポートしないとですが、EXPORTED_FUNCTIONSにpj_init_plusを含めて-O2でjavascript化してやると、エラー吐きます。
pj_init_plusを含めないか(proj.4的には非常に意味がない)、-O1以下の最適化だと問題ありません。
単純な文法エラーなので、直してやります。
p =+ W( + m, + (.9396926207859084 * q--.3420201433256687 * n))
p =+ W( + m, + (.9396926207859084 * q+.3420201433256687 * n))
sed -e s/--\.342/+.342/ js/emproj.js > js/emproj.js_1
+(+,+2.0);+();+();+(+,+2.0);+(+,+2.0);+();+();+();
こんな表現がよく判らないところに混ざってるのでざっくり削除
sed -e s/\+\(\+,\+2\.0\)\;\+\(\)\;\+\(\)\;\+\(\+,\+2\.0\)\;\+\(\+,\+2\.0\)\;\+\(\)\;\+\(\)\;\+\(\)\;// js/emproj.js_1 > js/emproj.js_2
とりあえずこれで、読み込んでもエラー出なくなりました。
個人的案件用のpre.js、post.jsつけて、裏の案件で試してみましたが、mercとlatlong扱う限りでは、単純WGS84/Googleメルカトルだけじゃなく色々試してみましたが動いてます。
ただなんか、別の方のコンパイルされたのより遅くなってるかも…なんでだろ?
メモリ空間の確保を小さくしちゃったかな?
一応今回はコンパイルまで。
コンパイルした関数の叩き方、pre.js、post.jsの作り方等は、また機会がありましたら。