【Android NDK 开发】Android Studio 使用 CMake 导入静态库 ( CMake 简介 | 构建脚本路径配置 | 引入静态库 | 指定静态库路径 | 链接动态库 )
文章目錄
- I . CMake 簡介
- II . Android Studio 中 CMake 引入靜態(tài)庫流程
- III . 指定 CMake 最小版本號(hào)
- IV . 導(dǎo)入函數(shù)庫 ( 靜態(tài)庫 / 動(dòng)態(tài)庫 ) 編譯配置
- V . 導(dǎo)入第三方函數(shù)庫路徑配置
- VI . 輸出日志信息
- VII . 鏈接函數(shù)庫
- VIII . Module 級(jí)別的 build.gradle 完整配置代碼
- IX . CMakeList.txt 完整配置代碼
- X . 博客資源
I . CMake 簡介
1 . CMake 簡介 :
① 構(gòu)建工具 : CMake 是 Android 中使用 C/C++ 構(gòu)建原生庫的默認(rèn)工具 ;
② 跨平臺(tái) : CMake 是跨平臺(tái)的構(gòu)建工具 , 其可以根據(jù)不同類型的平臺(tái) , 不同類型的編譯器 , 生成對(duì)應(yīng)的 Makefile ;
③ 本質(zhì) : CMake 不是直接編譯項(xiàng)目的 , 而是生成 make 對(duì)應(yīng)的構(gòu)建腳本 Makefile 文件 , 還是使用 make 進(jìn)行構(gòu)建項(xiàng)目 ;
③ Android 中生成的腳本 : Android Studio 中 , CMake 生成 ninja 腳本 , ninja 是一種輕量級(jí)快速構(gòu)建工具 ; ( 僅做參考 )
2 . CMake 與 Android.mk : Google 逐漸放棄了對(duì) Android.mk 的支持 , 目前新項(xiàng)目推薦使用 CMake 構(gòu)建本地庫 , 舊的項(xiàng)目建議將 Android.mk 轉(zhuǎn)為 CMake 構(gòu)建 , 以獲取更好的代碼維護(hù) ;
II . Android Studio 中 CMake 引入靜態(tài)庫流程
Android Studio 中 CMake 引入靜態(tài)庫流程 :
1 . build.gradle 配置 CMake 編譯選項(xiàng) : 在 Module 級(jí)別的 build.gradle 腳本中配置 CMake 編譯選項(xiàng) ;
// I . NDK 配置 1 : 配置 AS 工程中的 C/C++ 源文件的編譯// defaultConfig 內(nèi)部的 externalNativeBuild 配置的是配置 AS 工程的 C/C++ 源文件編譯參數(shù)// defaultConfig 外部的 externalNativeBuild 配置的是 CMakeList.txt 或 Android1.mk 構(gòu)建腳本的路徑externalNativeBuild {cmake {cppFlags ""//配置編譯 C/C++ 源文件為哪幾個(gè) CPU 指令集的函數(shù)庫 (arm , x86 等)abiFilters "armeabi-v7a"}/*ndkBuild{abiFilters "armeabi-v7a" *//*, "arm64-v8a", "x86", "x86_64"*//*}*/}2 . build.gradle 配置 NDK 打包選項(xiàng) : 在 Module 級(jí)別的 build.gradle 腳本中配置 NDK 打包選項(xiàng) ;
// II . NDK 配置 2 : 配置 AS 工程中的 C/C++ 源文件的編譯//配置 APK 打包 哪些動(dòng)態(tài)庫// 示例 : 如在工程中集成了第三方庫 , 其提供了 arm, x86, mips 等指令集的動(dòng)態(tài)庫// 那么為了控制打包后的應(yīng)用大小, 可以選擇性打包一些庫 , 此處就是進(jìn)行該配置ndk{// 打包生成的 APK 文件指揮包含 ARM 指令集的動(dòng)態(tài)庫abiFilters "armeabi-v7a" /*, "arm64-v8a", "x86", "x86_64"*/}3 . build.gradle 配置 CMake 構(gòu)建腳本 CMakeList.txt 路徑 : 在 Module 級(jí)別的 build.gradle 腳本中配置 Android.mk 構(gòu)建腳本的路徑 ;
// III . NDK 配置 : 配置 AS 工程中的 C/C++ 源文件的編譯構(gòu)建腳本// 配置 NDK 的編譯腳本路徑// 編譯腳本有兩種 ① CMakeList.txt ② Android1.mk// defaultConfig 內(nèi)部的 externalNativeBuild 配置的是配置 AS 工程的 C/C++ 源文件編譯參數(shù)// defaultConfig 外部的 externalNativeBuild 配置的是 CMakeList.txt 或 Android1.mk 構(gòu)建腳本的路徑externalNativeBuild {// 配置 CMake 構(gòu)建腳本 CMakeLists.txt 腳本路徑cmake {path "src/main/cpp/CMakeLists.txt"version "3.10.2"}// 配置 Android1.mk 構(gòu)建腳本路徑/*ndkBuild{//path "src/main/ndkBuild_Shared/Android.mk"path "src/main/ndkBuild_Static/Android.mk"}*/}4 . CMake 構(gòu)建腳本 CMakeList.txt 引入靜態(tài)庫 :
# 引入靜態(tài)庫 # ① 參數(shù) 1 ( add ) : 設(shè)置引入的靜態(tài)庫名稱 # ② 參數(shù) 2 ( SHARED ) : 設(shè)置引入的函數(shù)庫類型 : ① 靜態(tài)庫 STATIC ② 動(dòng)態(tài)庫 SHARED # ③ 參數(shù) 3 ( IMPORTED ) : 表示引入第三方靜態(tài)庫 , 導(dǎo)入靜態(tài)庫 , 相當(dāng)于預(yù)編譯靜態(tài)庫 # 后續(xù)還需要設(shè)置導(dǎo)入路徑 , 配合該配置使用 add_library(# 設(shè)置引入的靜態(tài)庫名稱add# 設(shè)置引入的函數(shù)庫類型為靜態(tài)庫STATIC# 表示引入第三方靜態(tài)庫IMPORTED)5 . CMake 構(gòu)建腳本 CMakeList.txt 設(shè)置靜態(tài)庫路徑 :
# 設(shè)置上述靜態(tài)庫的導(dǎo)入路徑 # 設(shè)置目標(biāo)屬性參數(shù) : # ① 參數(shù) 1 ( add ) : 要設(shè)置哪個(gè)函數(shù)庫的屬性 # ② 參數(shù) 2 ( PROPERTIES ) : 設(shè)置目標(biāo)屬性 # ③ 參數(shù) 3 ( IMPORTED_LOCATION ) : 設(shè)置導(dǎo)入路徑 # ④ 參數(shù) 4 : 配置靜態(tài)庫的文件路徑 set_target_properties(# 設(shè)置目標(biāo)add# 設(shè)置屬性PROPERTIES# 導(dǎo)入路徑IMPORTED_LOCATION# ${CMAKE_SOURCE_DIR} 是本 CMakeList.txt 構(gòu)建腳本的路徑 , 是 CMake 工具內(nèi)置的變量# Android CMake 也內(nèi)置了一些變量 , 如 ANDROID_ABI${CMAKE_SOURCE_DIR}/../jniLibs/armeabi-v7a/libadd.a)6 . CMake 構(gòu)建腳本 CMakeList.txt 鏈接靜態(tài)庫 :
# 鏈接函數(shù)庫 # 參數(shù) 1 : 本構(gòu)建腳本要生成的動(dòng)態(tài)庫目 標(biāo) # 參數(shù) 2 ~ ... : 后面是之前預(yù)編譯的動(dòng)態(tài)庫或靜態(tài)庫 , 或引入的動(dòng)態(tài)庫 target_link_libraries(native-lib# 表示 編譯 native-lib 模塊, 要鏈接 add 模塊add${log-lib})III . 指定 CMake 最小版本號(hào)
指定 CMake 最低版本 : 在 CMake 構(gòu)建腳本 CMakeList.txt 文件中 , 第一行一定要先指定 CMake 最小版本號(hào) ;
cmake_minimum_required(VERSION 3.4.1)IV . 導(dǎo)入函數(shù)庫 ( 靜態(tài)庫 / 動(dòng)態(tài)庫 ) 編譯配置
函數(shù)庫 ( 靜態(tài)庫 / 動(dòng)態(tài)庫 ) 編譯配置 : 函數(shù)庫編譯需要傳入 3 個(gè)參數(shù) ;
① 參數(shù) 1 : 設(shè)置生成的動(dòng)態(tài)庫名稱 ;
② 參數(shù) 2 : 設(shè)置生成的函數(shù)庫類型 : a . 靜態(tài)庫 STATIC , b . 動(dòng)態(tài)庫 SHARED ;
③ 參數(shù) 3 : 配置要編譯的源文件 ;
# 引入靜態(tài)庫 # ① 參數(shù) 1 ( add ) : 設(shè)置引入的靜態(tài)庫名稱 # ② 參數(shù) 2 ( SHARED ) : 設(shè)置引入的函數(shù)庫類型 : ① 靜態(tài)庫 STATIC ② 動(dòng)態(tài)庫 SHARED # ③ 參數(shù) 3 ( IMPORTED ) : 表示引入第三方靜態(tài)庫 , 導(dǎo)入靜態(tài)庫 , 相當(dāng)于預(yù)編譯靜態(tài)庫 # 后續(xù)還需要設(shè)置導(dǎo)入路徑 , 配合該配置使用 add_library(# 設(shè)置引入的靜態(tài)庫名稱add# 設(shè)置引入的函數(shù)庫類型為靜態(tài)庫STATIC# 表示引入第三方靜態(tài)庫IMPORTED)2 . 特別注意 : 使用這種方法引入動(dòng)態(tài)庫 , 在 6.0 以上的系統(tǒng)是無法使用的 , 推薦使用 set() 設(shè)置 -L 參數(shù)的方式引入動(dòng)態(tài)庫 ;
# 設(shè)置變量 # CMAKE_CXX_FLAGS 表示會(huì)將 C++ 的參數(shù)傳給編譯器 # CMAKE_C_FLAGS 表示會(huì)將 C 參數(shù)傳給編譯器# 參數(shù)設(shè)置 : 傳遞 CMAKE_CXX_FLAGS C+= 參數(shù)給編譯器時(shí) , 在 該參數(shù)后面指定庫的路徑 # CMAKE_SOURCE_DIR 指的是當(dāng)前的文件地址 # -L 參數(shù)指定動(dòng)態(tài)庫的查找路徑 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/../jniLibs/armeabi-v7a")V . 導(dǎo)入第三方函數(shù)庫路徑配置
導(dǎo)入第三方函數(shù)庫路徑配置 : 通過調(diào)用 set_target_properties () 設(shè)置第三方庫路徑 ;
① 參數(shù) 1 ( add ) : 要設(shè)置哪個(gè)函數(shù)庫的屬性 ;
② 參數(shù) 2 ( PROPERTIES ) : 設(shè)置目標(biāo)屬性 ;
③ 參數(shù) 3 ( IMPORTED_LOCATION ) : 設(shè)置導(dǎo)入路徑 ;
④ 參數(shù) 4 : 配置靜態(tài)庫的文件路徑 ;
# 設(shè)置上述靜態(tài)庫的導(dǎo)入路徑 # 設(shè)置目標(biāo)屬性參數(shù) : # ① 參數(shù) 1 ( add ) : 要設(shè)置哪個(gè)函數(shù)庫的屬性 # ② 參數(shù) 2 ( PROPERTIES ) : 設(shè)置目標(biāo)屬性 # ③ 參數(shù) 3 ( IMPORTED_LOCATION ) : 設(shè)置導(dǎo)入路徑 # ④ 參數(shù) 4 : 配置靜態(tài)庫的文件路徑 set_target_properties(# 設(shè)置目標(biāo)add# 設(shè)置屬性PROPERTIES# 導(dǎo)入路徑IMPORTED_LOCATION# ${CMAKE_SOURCE_DIR} 是本 CMakeList.txt 構(gòu)建腳本的路徑 , 是 CMake 工具內(nèi)置的變量# Android CMake 也內(nèi)置了一些變量 , 如 ANDROID_ABI${CMAKE_SOURCE_DIR}/../jniLibs/armeabi-v7a/libadd.a)VI . 輸出日志信息
調(diào)用 message() 方法可以輸出日志信息 :
# 打印日志信息 # ${ANDROID_ABI} 的作用是獲取當(dāng)前的 CPU 指令集架構(gòu) # 當(dāng)本次編譯 armeabi-v7a CPU 架構(gòu)時(shí) , ${ANDROID_ABI} 值為 armeabi-v7a # 當(dāng)本次編譯 x86 CPU 架構(gòu)時(shí) , ${ANDROID_ABI} 值為 x86 message("CMAKE_SOURCE_DIR : ${CMAKE_SOURCE_DIR}, ANDROID_ABI : ${ANDROID_ABI}")VII . 鏈接函數(shù)庫
鏈接函數(shù)庫 : 這里注意第一個(gè)參數(shù)必須是要生成的動(dòng)態(tài)庫模塊 ;
# 鏈接函數(shù)庫 # 參數(shù) 1 : 本構(gòu)建腳本要生成的動(dòng)態(tài)庫目標(biāo) # 參數(shù) 2 ~ ... : 后面是之前預(yù)編譯的動(dòng)態(tài)庫或靜態(tài)庫 , 或引入的動(dòng)態(tài)庫 target_link_libraries(native-lib# 表示 編譯 native-lib 模塊, 要鏈接 add 模塊add${log-lib})VIII . Module 級(jí)別的 build.gradle 完整配置代碼
apply plugin: 'com.android.application'android {compileSdkVersion 29buildToolsVersion "29.0.0"defaultConfig {applicationId "kim.hsl.cmake"minSdkVersion 15targetSdkVersion 29versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"// I . NDK 配置 1 : 配置 AS 工程中的 C/C++ 源文件的編譯// defaultConfig 內(nèi)部的 externalNativeBuild 配置的是配置 AS 工程的 C/C++ 源文件編譯參數(shù)// defaultConfig 外部的 externalNativeBuild 配置的是 CMakeList.txt 或 Android1.mk 構(gòu)建腳本的路徑externalNativeBuild {cmake {cppFlags ""//配置編譯 C/C++ 源文件為哪幾個(gè) CPU 指令集的函數(shù)庫 (arm , x86 等)abiFilters "armeabi-v7a"}/*ndkBuild{abiFilters "armeabi-v7a" *//*, "arm64-v8a", "x86", "x86_64"*//*}*/}// II . NDK 配置 2 : 配置 AS 工程中的 C/C++ 源文件的編譯//配置 APK 打包 哪些動(dòng)態(tài)庫// 示例 : 如在工程中集成了第三方庫 , 其提供了 arm, x86, mips 等指令集的動(dòng)態(tài)庫// 那么為了控制打包后的應(yīng)用大小, 可以選擇性打包一些庫 , 此處就是進(jìn)行該配置ndk{// 打包生成的 APK 文件指揮包含 ARM 指令集的動(dòng)態(tài)庫abiFilters "armeabi-v7a" /*, "arm64-v8a", "x86", "x86_64"*/}}// III . NDK 配置 : 配置 AS 工程中的 C/C++ 源文件的編譯構(gòu)建腳本// 配置 NDK 的編譯腳本路徑// 編譯腳本有兩種 ① CMakeList.txt ② Android1.mk// defaultConfig 內(nèi)部的 externalNativeBuild 配置的是配置 AS 工程的 C/C++ 源文件編譯參數(shù)// defaultConfig 外部的 externalNativeBuild 配置的是 CMakeList.txt 或 Android1.mk 構(gòu)建腳本的路徑externalNativeBuild {// 配置 CMake 構(gòu)建腳本 CMakeLists.txt 腳本路徑cmake {path "src/main/cpp/CMakeLists.txt"version "3.10.2"}// 配置 Android1.mk 構(gòu)建腳本路徑/*ndkBuild{//path "src/main/ndkBuild_Shared/Android.mk"path "src/main/ndkBuild_Static/Android.mk"}*/}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}} }dependencies {implementation fileTree(dir: 'libs', include: ['*.jar'])implementation 'androidx.appcompat:appcompat:1.1.0'implementation 'androidx.constraintlayout:constraintlayout:1.1.3'testImplementation 'junit:junit:4.12'androidTestImplementation 'androidx.test:runner:1.2.0'androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' }
IX . CMakeList.txt 完整配置代碼
# 指定 CMake 最低版本 cmake_minimum_required(VERSION 3.4.1)# 設(shè)置函數(shù)庫編譯 add_library( # 參數(shù) 1 : 設(shè)置生成的動(dòng)態(tài)庫名稱native-lib# 參數(shù) 2 : 設(shè)置生成的函數(shù)庫類型 : ① 靜態(tài)庫 STATIC ② 動(dòng)態(tài)庫 SHAREDSHARED# 參數(shù) 3 : 配置要編譯的源文件native-lib.cpp)# 引入靜態(tài)庫 # ① 參數(shù) 1 ( add ) : 設(shè)置引入的靜態(tài)庫名稱 # ② 參數(shù) 2 ( SHARED ) : 設(shè)置引入的函數(shù)庫類型 : ① 靜態(tài)庫 STATIC ② 動(dòng)態(tài)庫 SHARED # ③ 參數(shù) 3 ( IMPORTED ) : 表示引入第三方靜態(tài)庫 , 導(dǎo)入靜態(tài)庫 , 相當(dāng)于預(yù)編譯靜態(tài)庫 # 后續(xù)還需要設(shè)置導(dǎo)入路徑 , 配合該配置使用 add_library(# 設(shè)置引入的靜態(tài)庫名稱add# 設(shè)置引入的函數(shù)庫類型為靜態(tài)庫STATIC# 表示引入第三方靜態(tài)庫IMPORTED)# 設(shè)置上述靜態(tài)庫的導(dǎo)入路徑 # 設(shè)置目標(biāo)屬性參數(shù) : # ① 參數(shù) 1 ( add ) : 要設(shè)置哪個(gè)函數(shù)庫的屬性 # ② 參數(shù) 2 ( PROPERTIES ) : 設(shè)置目標(biāo)屬性 # ③ 參數(shù) 3 ( IMPORTED_LOCATION ) : 設(shè)置導(dǎo)入路徑 # ④ 參數(shù) 4 : 配置靜態(tài)庫的文件路徑 set_target_properties(# 設(shè)置目標(biāo)add# 設(shè)置屬性PROPERTIES# 導(dǎo)入路徑IMPORTED_LOCATION# ${CMAKE_SOURCE_DIR} 是本 CMakeList.txt 構(gòu)建腳本的路徑 , 是 CMake 工具內(nèi)置的變量# Android CMake 也內(nèi)置了一些變量 , 如 ANDROID_ABI${CMAKE_SOURCE_DIR}/../jniLibs/armeabi-v7a/libadd.a)# 打印日志信息 # ${ANDROID_ABI} 的作用是獲取當(dāng)前的 CPU 指令集架構(gòu) # 當(dāng)本次編譯 armeabi-v7a CPU 架構(gòu)時(shí) , ${ANDROID_ABI} 值為 armeabi-v7a # 當(dāng)本次編譯 x86 CPU 架構(gòu)時(shí) , ${ANDROID_ABI} 值為 x86 message("CMAKE_SOURCE_DIR : ${CMAKE_SOURCE_DIR}, ANDROID_ABI : ${ANDROID_ABI}")# 到預(yù)設(shè)的目錄查找 log 庫 , 將找到的路徑賦值給 log-lib # 這個(gè)路徑是 NDK 的 ndk-bundle\platforms\android-29\arch-arm\usr\lib\liblog.so # 不同的 Android 版本號(hào) 和 CPU 架構(gòu) 需要到對(duì)應(yīng)的目錄中查找 , 此處是 29 版本 32 位 ARM 架構(gòu)的日志庫 find_library(log-liblog)# 設(shè)置變量 # CMAKE_CXX_FLAGS 表示會(huì)將 C++ 的參數(shù)傳給編譯器 # CMAKE_C_FLAGS 表示會(huì)將 C 參數(shù)傳給編譯器# 參數(shù)設(shè)置 : 傳遞 CMAKE_CXX_FLAGS C+= 參數(shù)給編譯器時(shí) , 在 該參數(shù)后面指定庫的路徑 # CMAKE_SOURCE_DIR 指的是當(dāng)前的文件地址 # -L 參數(shù)指定動(dòng)態(tài)庫的查找路徑 #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/../jniLibs/armeabi-v7a")# 鏈接函數(shù)庫 # 參數(shù) 1 : 本構(gòu)建腳本要生成的動(dòng)態(tài)庫目 標(biāo) # 參數(shù) 2 ~ ... : 后面是之前預(yù)編譯的動(dòng)態(tài)庫或靜態(tài)庫 , 或引入的動(dòng)態(tài)庫 target_link_libraries(native-lib# 表示 編譯 native-lib 模塊, 要鏈接 add 模塊add${log-lib})
X . 博客資源
CSDN 博客地址 : 【Android NDK 開發(fā)】Android Studio 使用 CMake 導(dǎo)入靜態(tài)庫 ( CMake 簡介 | 構(gòu)建腳本路徑配置 | 引入靜態(tài)庫 | 指定靜態(tài)庫路徑 | 鏈接動(dòng)態(tài)庫 )
博客資源下載地址 : https://download.csdn.net/download/han1202012/12162132
示例代碼 GitHub 地址 : https://github.com/han1202012/008_NDK_CMake_Static
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的【Android NDK 开发】Android Studio 使用 CMake 导入静态库 ( CMake 简介 | 构建脚本路径配置 | 引入静态库 | 指定静态库路径 | 链接动态库 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android NDK 开发】Andr
- 下一篇: 【Android NDK 开发】Andr