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