levmar是一個強大的和高效率的C/C++庫,採用Levenberg - 馬奎德(LM)優化算法,
由於項目過久遠,仍是採用 eclipse IDE來開發的,我嘗試搬到 Android Studio 來編譯,仍是編譯不成功,最後只有從新配置eclipse 環境。最重要是,還得使用比較舊版本的NDK來編譯,我選用的NDK版本是 12b。過程當中有些小錯誤,我就稍微調整了一下,而後按eclipse NDK的步驟編譯了一遍。
項目中 的 application.mk 裏有一項配置:
APP_ABI := armeab
這個是CPU 的指令集配置。通常咱們在編譯的時候,都會兼容多種CPU,因而改成:
APP_ABI := all
編譯中,沒有什麼大問題,有部分警告而已,編譯成功。
編譯成功後,在libs目錄下出現了 arm64-v8a、armeabi、armeabi-v7a、mips、mips6四、x8六、x86_64 指令集目錄。因而,我就用真機測試一下,有部分手機經過了,有部分手機運行出錯。
各類調試以後,我發現多是不一樣手機的CPU 支持的指令集不同,因而我經過如下代碼輸出每臺手機的指令集:
String[] abis = new String[]{};
abis = Build.SUPPORTED_ABIS;
獲得結果以下:
魅族 note2:
oppo r9s:
arm64-v8a,
armeabi-v7a,
armeabi,
當時vivo Y51A 能運行經過,而其餘兩臺手機運行時會崩潰。而後我猜可能 是arm64-v8a 庫出錯了。因而我把這個文件以及裏面的文件給刪了, 果真,所有手機都運行經過了。
從這裏大概知道:APP在獲取動態庫時,首先會根據CPU支持的指令集獲取第一個目錄下的動態庫,若是獲取不到,就會到下一個支持的指令集目錄獲取,以此類推。
固然這個項目算是編譯成功了,由於目前多數手機的CPU都會支持 armeabi-v7a 和 armeabi。但咱們也知道不少第三方的庫都會兼容 arm64-v8a 這種指令集,這個64位的指令集應該會跑得更快。
我也嘗試去從新編譯 levmar 庫,讓它兼容 arm64-v8a 指令集。 我下載了其它版本的 NDK來嘗試,由於 ndk-build 命令在 r13 中默認使用 Clang,他們將在後續版本中移除 GCC。levmar 庫其實也使用到了一些 matlab 等其它語言庫,我擔憂是這方面編譯出錯了。當我使用了其它版本的NDK編譯後,編譯是成功了,可是在 JNI 調用的時候就會報這樣的錯誤:
06-22 16:32:40.741: A/libc(5024): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 5024 (hvrl.levmar)
查了一下,這個錯誤的緣由是,查不到相應 JNI 的實現方法,或者是 native 的代碼執行時出錯了。由於獲取不到C/C++ 的錯誤日誌,我也只能暫時放棄兼容 arm64-v8a 指令集。
levmar庫是編譯成功了,是一個 levmar.a 靜態庫, 這裏 levmar 也使用到了 clapack,也編譯成了 .a靜態庫。
歡迎你們關注我,或一塊兒討論。