zoukankan      html  css  js  c++  java
  • NDK(23) 使用CMake 构建 c/c++代码库

    1.官网

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

    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.

    3.最后 生成的项目如下:

    其中:

      • CMakeLists.txt 是cmake构建工程要用的项目配置文件.
      • native-lib.cpp是源文件

    4.编辑代码,使用本地程序....

    4.在现有项目中添加 c/c++库

    4.1 创建 jni目录

      项目名(或者File) ---> 右键 --->  New ---> Folder ---> JNI Folder

    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()

    向您的 CMake 构建脚本添加源文件或库

    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++代码工作

    MainActivity.java 

     1 public class MainActivity extends AppCompatActivity {
     2 
     3     // Used to load the 'native-lib' library on application startup.
     4     static {
     5         System.loadLibrary("native-lib");
     6     }
     7 
     8     @Override
     9     protected void onCreate(Bundle savedInstanceState) {
    10         super.onCreate(savedInstanceState);
    11         setContentView(R.layout.activity_main);
    12 
    13         // Example of a call to a native method
    14         TextView tv = findViewById(R.id.sample_text);
    15         tv.setText(stringFromJNI());
    16     }
    17 
    18     /**
    19      * A native method that is implemented by the 'native-lib' native library,
    20      * which is packaged with this application.
    21      */
    22     public native String stringFromJNI();
    23 }

    native-lib.cpp

     1 #include <jni.h>
     2 #include <string>
     3 
     4 extern "C" JNIEXPORT jstring JNICALL
     5 Java_com_example_cpp14_MainActivity_stringFromJNI(
     6         JNIEnv* env,
     7         jobject /* this */) {
     8     std::string hello = "Hello from C++";
     9     return env->NewStringUTF(hello.c_str());
    10 }

      

    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{} 块中指定的配置。

       注: 非特殊情况下,只保留  'arm64-v8a' 就够用了。 参考微信的apk。

  • 相关阅读:
    [置顶] .net技术类面试、笔试题汇总1
    [置顶] Linux协议栈代码阅读笔记(一)
    JS 获取浏览器窗口大小
    huapin
    display:table-cell几种应用
    flex布局大讲解
    chrome的source工具
    linux配置yum源
    oracle Can't connect to X11 window server using ':0.0' /Checking monitor: must be configured to display at least 256 colors解决方法
    oracle Recyclebin
  • 原文地址:https://www.cnblogs.com/mhbs/p/4730964.html
Copyright © 2011-2022 走看看