NDK(23) 使用CMake 構建 c/c++代碼庫

1.官網

  https://developer.android.com/studio/projects/add-native-code.htmlhtml

2.android studio 安裝相關工具

  1. 在打開的項目中,從菜單欄選擇 Tools > Android > SDK Manager
  2. 點擊 SDK Tools 標籤。
  3. 選中 LLDBCMake 和 NDK 旁的複選框,如圖所示.

    

3.新建支持c/c++的項目

  1. 在android studio 3.4.1 新建嚮導裏選 Native C++ 模板.

2.選擇想要使用的c++標準,如C++14.android

3.最後 生成的項目以下:c++

其中:架構

    • CMakeLists.txt 是cmake構建工程要用的項目配置文件,相似android.mk.
    • native-lib.cpp是源文件

4.編輯代碼,使用本地程序....app

4.在現有項目中添加 c/c++庫

4.1 建立 jni目錄

  項目名(或者File) ---> 右鍵 --->  New ---> Folder ---> JNI Folderide

4.2 建立 CMakeLists.txt文件 

  在上一步上建立的jni目錄(當前版本目錄名是cpp) 右鍵 ---> New ---> File 輸入CMakeLists.txt函數

4.3 配置CMakeLists.txt 文件

 1 # Sets the minimum version of CMake required to build your native library.
 2 # This ensures that a certain set of CMake features is available to
 3 # your build.
 4 
 5 cmake_minimum_required(VERSION 3.4.1)
 6 
 7 # Specifies a library name, specifies whether the library is STATIC or
 8 # SHARED, and provides relative paths to the source code. You can
 9 # define multiple libraries by adding multiple add.library() commands,
10 # and CMake builds them for you. When you build your app, Gradle
11 # automatically packages shared libraries with your APK.
12 
13 add_library( # Specifies the name of the library.
14              # 本地庫名
15              student-lib
16 
17              # Sets the library as a shared library.
18              # 本地庫的類型
19              SHARED
20 
21              # Provides a relative path to your source file(s).
22              # 要編譯的源文件 ,多個之間用空格.
23              student.cpp school.cpp)
24 
25 # Specifies a path to native header files.
26 include_directories(inc)
27 
28 
29 #添加本地代碼依賴的其它系統庫.
30 find_library( # Defines the name of the path variable that stores the
31               # location of the NDK library.
32               log-lib
33 
34               # Specifies the name of the NDK library that
35               # CMake needs to locate.
36               log )
37 
38 # Links your native library against one or more other native libraries.
39 target_link_libraries( # Specifies the target library.
40                        student-lib
41 
42                        # Links the log library to the target library.
43                        ${log-lib} )
  • 注意CMakeLists.txt中源文件和include的路徑引用問題,這裏是和源文件同級.
  • CMakeLists.txt 經常使用函數含義
  • 下面是經常使用的cmake命令.

    cmake命令官網 : https://cmake.org/cmake/help/latest/manual/cmake-commands.7.html 工具

add_library()gradle

向您的 CMake 構建腳本添加源文件或庫ui

1 add_library( # Specifies the name of the library.
2              native-lib
3 
4              # Sets the library as a shared library.
5              SHARED
6 
7              # Provides a relative path to your source file(s).
8              src/main/cpp/native-lib.cpp )
 

include_directories

指定頭文件的路徑

1 add_library(...)
2 
3 # Specifies a path to native header files.
4 include_directories(src/main/cpp/include/)
find_library()

添加引用的NDK 庫

1 find_library( # Defines the name of the path variable that stores the
2               # location of the NDK library.
3               log-lib
4 
5               # Specifies the name of the NDK library that
6               # CMake needs to locate.
7               log )
target_link_libraries()

連接多個庫

1 target_link_libraries( native-lib imported-lib app-glue ${log-lib} )
 add_library()

將其它源代碼編譯到本地庫中.

1 add_library( app-glue
2              STATIC
3              ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c )
4 
5 # You need to link static libraries against your shared native library.
6 target_link_libraries( native-lib app-glue ${log-lib} )
 

set_target_properties

和 IMPORTED

IMPORTED不是個函數,只是add_library的參數,添加其餘預構建的本地庫 

而後,您須要使用 set_target_properties() 命令指定庫的路徑.

4.4 關聯Gradle與 CMakeLists.txt  

  右鍵點擊您想要關聯的模塊(例如 app 模塊),並從菜單中選擇 Link C++ Project with Gradle。關聯到以前建立的CMakeLists.txt,點OK.

  

4.5 完成本地的c/c++代碼工做

   略...

5.在 Gradle 中使用 CMake 變量

  https://developer.android.com/ndk/guides/cmake.html#variables

 1 android {
 2   ...
 3   defaultConfig {
 4     ...
 5     // This block is different from the one you use to link Gradle
 6     // to your CMake or ndk-build script.
 7     externalNativeBuild {
 8 
 9       // For ndk-build, instead use ndkBuild {}
10       cmake {
11 
12         // Passes optional arguments to CMake.
13         arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang"
14 
15         // Sets optional flags for the C compiler.
16         cFlags "-D_EXAMPLE_C_FLAG1", "-D_EXAMPLE_C_FLAG2"
17 
18         // Sets a flag to enable format macro constants for the C++ compiler.
19         cppFlags "-D__STDC_FORMAT_MACROS"
20       }
21     }
22   }
23 
24   buildTypes {...}
25 
26     ...
27 }

6.指定本地庫的cpu架構

  默認狀況下,Gradle 會針對 NDK 支持的 ABI 將您的原生庫構建到單獨的 .so 文件中,並將其所有打包到您的 APK 中。若是您但願 Gradle 僅構建和打包原生庫的特定 ABI 配置,您能夠在模塊級 build.gradle 文件中使用 ndk.abiFilters 標誌指定這些配置.

 1 apply plugin: 'com.android.application'
 2 
 3 android {
 4     compileSdkVersion 28
 5     defaultConfig {
 6         applicationId "com.example.tocpp5"
 7         minSdkVersion 15
 8         targetSdkVersion 28
 9         versionCode 1
10         versionName "1.0"
11         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
12         // This block is different from the one you use to link Gradle
13         // to your CMake or ndk-build script.
14         externalNativeBuild {
15             // For ndk-build, instead use ndkBuild {}
16             cmake {
17                 // Passes optional arguments to CMake.
18                 arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang"
19 
20                 // Sets optional flags for the C compiler.
21                 cFlags "-D_EXAMPLE_C_FLAG1", "-D_EXAMPLE_C_FLAG2"
22 
23                 // Sets a flag to enable format macro constants for the C++ compiler.
24                 cppFlags "-D__STDC_FORMAT_MACROS"
25 
26                 abiFilters 'armeabi-v7a','arm64-v8a'
27 
28             }
29         }
30         ndk {
31             // Specifies the ABI configurations of your native
32             // libraries Gradle should build and package with your APK.
33             abiFilters 'x86', 'x86_64', 'armeabi-v7a','arm64-v8a'
34         }
35     }
36     buildTypes {
37         release {
38             minifyEnabled false
39             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
40         }
41     }
42     externalNativeBuild {
43         cmake {
44             path file('src/main/jni/CMakeLists.txt')
45         }
46     }
47 }
48 
49 dependencies {
50     implementation fileTree(dir: 'libs', include: ['*.jar'])
51     implementation 'androidx.appcompat:appcompat:1.0.2'
52     implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
53     testImplementation 'junit:junit:4.12'
54     androidTestImplementation 'androidx.test:runner:1.2.0'
55     androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
56 }

  在 defaultConfig.externalNativeBuild.cmake {} 

  或 

  defaultConfig.externalNativeBuild.ndkBuild {} 塊

  中配置另外一個 abiFilters 標誌。Gradle 會構建defaultConfig.ndk中的 ABI 配置,不過僅會打包在 defaultConfig.cmake或者ndkBuild{} 塊中指定的配置。

相關文章
相關標籤/搜索