LoginSignup
3
3

More than 5 years have passed since last update.

emscriptenでproj.4コンパイル

Last updated at Posted at 2014-02-08

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以下の最適化だと問題ありません。
単純な文法エラーなので、直してやります。

エラー1
p =+ W( + m, + (.9396926207859084 * q--.3420201433256687 * n))
エラー1修正
p =+ W( + m, + (.9396926207859084 * q+.3420201433256687 * n))
エラー1修正sed
sed -e s/--\.342/+.342/ js/emproj.js > js/emproj.js_1
エラー2
+(+,+2.0);+();+();+(+,+2.0);+(+,+2.0);+();+();+();

こんな表現がよく判らないところに混ざってるのでざっくり削除

エラー2修正sed
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の作り方等は、また機会がありましたら。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3