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两个文件自动导入。
- //cmake,全新定义cmake脚本
- externalNativeBuild {
- cmake {
- path 'CMakeLists.txt'
- }
- }
-
- //ndk-build,已有Android.mk
- externalNativeBuild {
- ndkBuild {
- path 'src/main/jni/Android.mk'
- }
-
- //ndk-build,有多个项目多个Android.mk,指向总脚本Android-config.mk
- externalNativeBuild {
- ndkBuild {
- path 'Android-config.mk'
- }
* 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设置的问题。
- defaultConfig {
- applicationId "com.qualcomm.mtptest"
- minSdkVersion 23
- targetSdkVersion 22
- ndk {
- moduleName "mtptest"
- abiFilters "armeabi-v7a"//编译支持的平台
- cFlags '-std=c++11 -fexceptions -fpermissive'
- stl 'stlport_static'
- }
-
- }
这个设置就解决了问题,总结一下,gradle 中的
defaultConfig{}中的ndk{} externalNdkBuild{}就是为了设置abi、stl、platform,也就是为了取代Application.mk,很多明明Application.mk里面设置了的选项还是报错,基本都是这个原因。很多人奇怪哪里设置ABI_PLATFORM,实际上ABI_PLATFORM = minSdkVersion。
本篇cmake采用如下的设置
- defaultConfig {
- applicationId "com.vrseen.test2"
- minSdkVersion 19
- targetSdkVersion 25
- versionCode 1
- versionName "1.0"
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- externalNativeBuild {
- cmake {
- targets 'svrplugin'
- abiFilters 'armeabi-v7a'
- cppFlags "-frtti -fexceptions -D__STDC_FORMAT_MACROS -std=c++11"
- arguments '-DANDROID_PLATFORM=android-19',
- '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=stlport_static'
-
- }
- }
- }
cmakelists.txt
- cmake_minimum_required(VERSION 3.4.1)
-
-
- set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/libs)
-
-
- find_library(log-lib log )
- find_library(android-lib android )
-
-
- add_library( svrapi
- SHARED
- IMPORTED )
- set_target_properties( svrapi
- PROPERTIES IMPORTED_LOCATION
- ${PROJECT_SOURCE_DIR}/../svrapi/libs/armeabi-v7a/libsvrapi.so )
-
-
- add_library(svrplugin SHARED src/main/cpp/svrUnity.cpp )
-
-
- include_directories( ${PROJECT_SOURCE_DIR}/../svrapi/public )
-
-
- target_link_libraries(svrplugin svrapi ${log-lib} ${android-lib})
google android 官网上的资料介绍的是比较清楚的,不过需要翻墙,语言选择简体中文
https://developer.android.com/studio/projects/add-native-code.html