Android NDK(1)

CMake是一個跨平臺的安裝(編譯)工具,可以用簡單的語句來描述所有平攤的安裝編譯過程。它能夠輸出各種各樣的makefile或者project文件,能測試編譯器所支持的C++特性,類似UNIX下的automake。
谷歌從AndroidStudio2.2以上就添加了Cmake方式來編譯NDK代碼,並從NDK例子看出,默認編譯的方式就是cmake方式。但是原來的ndk項目如何進行關聯編譯呢

在gradle腳本中cmake提供了externalNativeBuild的結構,若使用cmake腳本重新設計ndk,則採用cmake{},若已有Android.mk文件,則採用ndk-build{}進行配置。path會將Android.mk和Application.mk兩個文件自動導入。

  1. //cmake,全新定義cmake腳本  
  2. externalNativeBuild {  
  3.     cmake {  
  4.         path 'CMakeLists.txt'  
  5.     }  
  6. }  
  7.   
  8. //ndk-build,已有Android.mk  
  9. externalNativeBuild {  
  10.     ndkBuild {  
  11.         path 'src/main/jni/Android.mk'  
  12.     }  
  13.   
  14. //ndk-build,有多個項目多個Android.mk,指向總腳本Android-config.mk  
  15. externalNativeBuild {  
  16.     ndkBuild {  
  17.         path 'Android-config.mk'  
  18.     }  



* What went wrong:
Execution failed for task ':apiTest:externalNativeBuildDebug'.
> Build command failed.
…...
[mips64] Prebuilt : libsvrapi.so <= /Users/vrseen/Documents/AndroidWorkspace/QualcommSDK_cmake/apiTest/src/main/jni/../../../../libs/armeabi-v7a/
[mips64] SharedLibrary : libsvrapitest.so
/Users/vrseen/Documents/AndroidWorkspace/QualcommSDK_cmake/apiTest/build/intermediates/ndkBuild/debug/obj/local/mips64/libsvrapi.so: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
make: *** [/Users/vrseen/Documents/AndroidWorkspace/QualcommSDK_cmake/apiTest/build/intermediates/ndkBuild/debug/obj/local/mips64/libsvrapitest.so] Error 1

遇到一個問題,ndk-build的時候會先編譯mips64的庫,由於項目只支持armeabi-v7a,一直報這個錯誤,奇怪的是application.mk文件中已經設置了 APP_ABI := armeabi-v7a,分析可能是因爲ndk設置的問題。
  1. defaultConfig {  
  2.     applicationId "com.qualcomm.mtptest"  
  3.     minSdkVersion 23  
  4.     targetSdkVersion 22  
  5.     ndk {  
  6.         moduleName "mtptest"  
  7.         abiFilters "armeabi-v7a"//編譯支持的平臺  
  8.         cFlags '-std=c++11 -fexceptions -fpermissive'  
  9.         stl 'stlport_static'  
  10.     }  
  11.   
  12. }  


這個設置就解決了問題,總結一下,gradle 中的
defaultConfig{}中的ndk{} externalNdkBuild{}就是爲了設置abi、stl、platform,也就是爲了取代Application.mk,很多明明Application.mk裏面設置了的選項還是報錯,基本都是這個原因。很多人奇怪哪裏設置ABI_PLATFORM,實際上ABI_PLATFORM = minSdkVersion
本篇cmake採用如下的設置
  1. defaultConfig {  
  2.     applicationId "com.vrseen.test2"  
  3.     minSdkVersion 19  
  4.     targetSdkVersion 25  
  5.     versionCode 1  
  6.     versionName "1.0"  
  7.     testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"  
  8.     externalNativeBuild {  
  9.         cmake {  
  10.             targets 'svrplugin'  
  11.             abiFilters 'armeabi-v7a'  
  12.             cppFlags "-frtti -fexceptions -D__STDC_FORMAT_MACROS -std=c++11"  
  13.             arguments '-DANDROID_PLATFORM=android-19',  
  14.                     '-DANDROID_TOOLCHAIN=clang''-DANDROID_STL=stlport_static'  
  15.   
  16.         }  
  17.     }  
  18. }  


cmakelists.txt
  1. cmake_minimum_required(VERSION 3.4.1)  
  2.   
  3. #so庫輸出到工程目錄libs  
  4. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/libs)  
  5.   
  6. #引入log android庫  
  7. find_library(log-lib log )  
  8. find_library(android-lib android )  
  9.   
  10. #添加預編譯的庫  
  11. add_library( svrapi  
  12.              SHARED  
  13.              IMPORTED )  
  14. set_target_properties( svrapi  
  15.                        PROPERTIES IMPORTED_LOCATION  
  16.                        ${PROJECT_SOURCE_DIR}/../svrapi/libs/armeabi-v7a/libsvrapi.so )  
  17.   
  18. #主工程  
  19. add_library(svrplugin SHARED src/main/cpp/svrUnity.cpp )  
  20.   
  21. #添加頭文件  
  22. include_directories( ${PROJECT_SOURCE_DIR}/../svrapi/public )  
  23.   
  24. #鏈接預編譯和系統庫  
  25. target_link_libraries(svrplugin svrapi ${log-lib} ${android-lib})  

google android 官網上的資料介紹的是比較清楚的,不過需要翻牆,語言選擇簡體中文
https://developer.android.com/studio/projects/add-native-code.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章