Windows+VS2017+dlib+OpenCV編譯安卓so文件

程序員的生活在於折騰。。。

博文內容如題,爲了方便搜索,我特意把關鍵詞都加上,自己折騰的時候確實不好找,本來VS編譯跨平臺就不多見,但對於用慣VS的我來說,實在不想裝個Android Studio,是的,決不妥協。

 

項目背景:最近在做一個圖像質量檢測工具,用到dlib和opencv兩個開源庫,需要打包.so接口給安卓端機使用

opencv+VS2017編譯Android項目這裏有一個opencv官網的英文教程How to build OpenCV for Android using Visual Studio?

本人親測有效,按照教程一步步來即可(小貼士:mingw32-make的時候耗時較久,編譯的時候記得清理本機內存,本人就不幸中了一招out of memory,果斷重啓機器,別的不幹就等它編譯,內存大把的主可以忽略,還有關於Android SDK 和 NDK,安裝了VS跨平臺的朋友可以直接使用,不用另外安裝,路徑尋找方法:工具-選項-跨平臺-c++-Android,就可以看到安卓SDK和NDK的路徑)。

問題是我需要同時使用dlib和opencv,我嘗試用同樣的方法編譯dlib,一開始用的是opencv裏面的toolchain.cmake,結果報錯了,具體裏面的cmake內容我沒細究,大概是配置的問題,然後我又在VS安裝的NDK下,路徑大概是C:\ProgramData\Microsoft\AndroidNDK64\android-ndk-r15c\build\cmake,當然這是我的本機路徑,路徑尋找在上面tips提到。cmake-gui裏是生成成功了,但是在mingw32-make的時候報錯了,大概就是stl的問題,dlib不支持gnustl,但是支持LLVM的libc++,也就是說沒法和opencv保持一致,so,我放棄這種做法。

在找到上面提到的教程之前,我曾找到一個dlib for Android的油管視頻(大家懂的,能看的點進去看下,不能看就只能聽我嘮叨了Compiling dlib so for android using ndk build

接着我又從github上下了一個dlib for android的代碼tzutalin/dlib-android(其實我就只需要裏面的兩個mk文件)

最後還需要OpenCV-android-sdk,這個github上面也有

需要的東西基本都齊了,我再整理一下:1. VS 2017 (跨平臺);2. dlib(版本我用的是19.16,這個應該問題不大,不要使用太低版本即可);3. NDK(使用VS自帶的即可)4. dlib for android;5. OpenCV-android-sdk

好了,接下來就是編譯和配置VS2017的整個過程了

1. 解壓dlib for android,找到jni文件夾,裏面除了Android.mk和Application.mk文件還有其他幾個文件夾,我嫌礙事直接刪了,這個不影響編譯;

2. 解壓OpenCV-android-sdk,把整個文件夾放到third_party下

3. 回到dlib for android的jni下,打開Android.mk,OPENCV_INCLUDE_DIR修改爲步驟2解壓後的路徑(OpenCV-android-sdk/sdk/native/jni/include),把MINIGLOG相關的都註釋掉

4. 打開Application.mk文件,基本上不用修改,APP_PLATFORM根據自己需要修改一下,APP_STL爲c++_static,如果需要支持dlib的其他功能,也可以自己加上去

5. cmd到jni的同級目錄下,即dlib for android目錄下,執行ndk-build(使用VS自帶的需要設置環境變量)

編譯完,dlib for android下會多出一個obj文件夾,obj下有一個local文件夾,不同安卓平臺下的庫文件會生成在local下,最終生成的文件爲libdlib.a,這裏稍微提一下,如果4中c++_static改爲c++_shared,則會在jni的同級目錄下生成libs文件夾,不同安卓架構的.so會在這裏生成,注意沒有local文件夾,我在編譯的時候並沒有生成類似libdlib.so的文件,倒是生成了libc++_shared.so文件,這個沒有去深究原因,後面VS編譯也只需要.a文件而已。(OpenCV-android-sdk的.a文件已經是編譯好的了)

接下來是VS配置的部分

新建一個跨平臺項目

選擇Rlease,ARM平臺,配置屬性

常規配置,注意STL的使用,前面有提到的

配置包含目錄dlib:dlib for android下的dlib並沒有頭文件,直接用原dlib的即可,OpenCV:third_party\OpenCV-android-sdk\sdk\native\jni\include,注意,庫目錄不是在這裏配置

C/C++的屬性配置,劃紅線的三個地方

接下來就是鏈接器,有幾個地方很關鍵

第一個是附加庫目錄:把之前生成的.a的目錄路徑寫上,再加上OpenCV-android-sdk\sdk\native\3rdparty\libs\armeabi-v7a和OpenCV-android-sdk\sdk\native\staticlibs\armeabi-v7a(我這裏用的是armeabi-v7a,可以根據需要修改)

第二個是配置庫依賴項,注意,不是附加依賴項!!!敲重點,是庫依賴項,上文的教程也有提到

第三個是庫依賴項的順序,這個,真的讓我很無語,平時用opencv_world用習慣了,imgcodecs,imgproc,core這三個都沒太關注其各自依賴,沒錯,順序就是這樣,一定要從上到下排列下來,同時,我們還需要cpufeatures,tegra_hal,tbb,libtiff這些,順序也必須按照這樣,而且要在opencv之後

最後說一個附加選項,之前寫了一個算法需要用到math頭文件,打包.so的時候就碰到一些函數用不了的錯誤,加了附加選項就可以了,大概就是NDK對c++的一些支持的東西,這裏有api:NDK API

然後,Build,完成

總結下來,坑雖然踩了很多,但是難度其實沒那麼大,什麼時候微軟大法可以把編譯.a那部分也集成進來,那就更加方便了,或者其實已經有,希望能有大神來指點迷津。

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章