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