Android Studio 配置 CMake

Android Studio 配置 CMake

原文

如果您的原生源文件还没有 CMake 构建脚本,则需要自行创建一个并包含适当的 CMake 命令。CMake 构建脚本是一个纯文本文件,您必须将其命名为 CMakeList.txt

本部分介绍了您会用到的一些基本的 CMake 命令,用于指示在创建原生库时需要用到哪些源文件。

当您创建了一个 CMake 构建脚本后,您需要配置 Gradle 文件去关联 CMake 脚本,使 Gradle 构建的时候能将原生库打包到您的 APK 里。

:如果您的项目使用 ndk-build,则不需要创建 CMake 构建脚本。可以通过一个指向您原生库的 Android.mk 文件,将原生库包含到 Gradle 中。

创建 CMake 脚本

要创建一个用作 CMake 构建脚本的纯文本文件,请按照以下步骤操作:

  1. IDE 切换到 Project 视图。
  2. 右键点击 您的模块 的根目录,选择 New > File

    :您可以在任何位置创建脚本文件,不过在构建脚本文件时,原生源文件和库的路径将和构建脚本的位置相关。

  3. 输入文件名 “CMakeLists.txt”,点 OK

现在,您可以添加 CMake 命令,对您的构建脚本进行配置。要让 CMake 从原生源代码中创建一个原生库,需要添加 cmake_minimum_required()add_library() 这两个命令。

# Sets the minimum version of CMake required to build your native library.
# This ensures that a certain set of CMake features is available to
# your build.

cmake_minimum_required(VERSION 3.4.1)

# Specifies a library name, specifies whether the library is STATIC or
# SHARED, and provides relative paths to the source code. You can
# define multiple libraries by adding multiple add_library() commands,
# and CMake builds them for you. When you build your app, Gradle
# automatically packages shared libraries with your APK.

add_library( # Specifies the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp )

当使用 add_library() 向您的 CMake 构建脚本添加源文件或库时,Android Studio 还会在 Project 视图下显示关联的标头文件。不过,为了确保 CMake 在编译时定位您的标头文件,您需要将 include_directories() 命令添加到 CMake 构建脚本中并指定标头路径:

add_library(...)

# Specifies a path to native header files.
include_directories(src/main/cpp/include/)

CMake 使用以下规范来为库文件命名:

lib库名称.so

例如,您在构建脚本中指定“native-lib”作为共享库的名称,CMake 将创建一个名称为 libnative-lib.so 的文件。不过,在Java 代码中加载此库时,请使用您在 CMake 构建脚本中指定的名称:

static {
    System.loadLibrary("native-lib");
}

:如果您在 CMake 构建脚本中重命名或移除某个库,您需要先清理项目,Gradle 随后才会应用更改或者从 APK 中移除旧版本的库。要清理项目,请从菜单栏中选择 Build > Clean Project

Android Studio 会自动添加源文件和标头文件到 Project 视图的 cpp 组中,使用多个 add_library() 命令可以使 CMake 定义要从其他源文件构建的更多库。

添加 NDK API

Android NDK 提供了一套实用的原生 API 和 库。通过将 NDK 库包含到项目的 CMakeLists.txt 脚本文件中,您可以使用这些 API。

预构建的 NDK 库已经存在于 Android 平台上,因此,您无需再构建或将其打包到 APK 中。由于 NDK 库已经是 CMake 搜索路径的一部分,您甚至不需要在您的本地 NDK 安装中指定库的位置 - 只需要向 CMake 提供您希望使用的库的名称,并将其关联到您自己的原生库中。

您可以是用命令 find_library() 来使 CMake 定位 NDK 库的位置,并将其路径保存为一个变量。您可以在构建脚本的其他部分通过变量引用 NDK 库。以下实例可以找到 Android 特定的日志支持库 并将其存储在变量 log-lib 中。

find_library( # Defines the name of the path variable that stores the
              # location of the NDK library.
              log-lib

              # Specifies the name of the NDK library that
              # CMake needs to locate.
              log )

为确保原生库可以调用 log 库中的函数,您需要使用 CMake 构建脚本中的 target_link_libraries() 命令来关联 log 库。

find_library(...)

# Links your native library against one or more other native libraries.
target_link_libraries( # Specifies the target library.
                       native-lib

                       # Links the log library to the target library.
                       ${log-lib} )

NDK 还可以以源码的形式包含一些库,您需要构建和关联您的原生库时需要使用这些代码。您可以使用 CMake 构建脚本中的 add_library() 命令,将源代码编译到原生库中。要提供本地的 NDK 库的路径,您可以使用 ANDROID_NDK 路径变量,Android Studio 会自动定义该变量。

一下命令可以指示 CMake 构建 android_native_app_glue.c,第二段代码会将 NativeActivity 生命周期事件和触摸输入置于静态库中,并将其关联到 native-lib:

add_library( app-glue
             STATIC
             ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c )

# You need to link static libraries against your shared native library.
target_link_libraries( native-lib app-glue ${log-lib} )

添加其他预构建库

添加预构建库与为 CMake 指定要构建另一个原生库类似。不过,由于库已经预先构建,您需要使用 IMPORTED 标示告知 CMake 您只希望将库导入到项目中:

add_library( imported-lib
             SHARED
             IMPORTED )

然后,您需要使用 set_target_properties() 命令来指定库的路径,如下所示。

某些库为特定的 CPU 架构(或应用二进制接口(ABI))提供了单独的软件包,并将其组织到单独的目录中。此方法有助于库充分利用特定的 CPU 架构,又能让您仅适用所需的库版本。要向 CMake 构建脚本中添加库的多个 ABI 版本,而不必为库的每个版本编写多个命令,您可以使用 ANDROID_ABI 路径变量。此变量使用 NDK 支持的一组默认 ABI,或者您手动配置 Gradle 而让其使用一组经过筛选的 ABI。例如:

add_library(...)
set_target_properties( # Specifies the target library.
                       imported-lib

                       # Specifies the parameter you want to define.
                       PROPERTIES IMPORTED_LOCATION

                       # Provides the path to the library you want to import.
                       imported-lib/src/${ANDROID_ABI}/libimported-lib.so )

为了确保 CMake 可以在编译时定位到您的标头文件,您需要使用 include_directories() 命令,并包含标头文件路径:

include_directories( imported-lib/include/ )

:如果您想打包一个并不是构建时依赖的预构建库(例如再添加属于 imported-lib 依赖项的预构建库是,则不需要执行以下说明来关联库)

要将预构建库关联到自己的原生库,请在您的 CMake 脚本中添加命令 target_link_libraries()

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

在构建应用时,Gradle 会自动将导入的库打包到 APK 中。您可以使用 APK 分析器验证哪些库打包到您的 APK 中。

关联其他 CMake 项目

如果您想编译多个 CMake 项目并将其添加到您的 Android 工程中,您可以让 Gradle 只关联一个 CMakeLists.txt 脚本文件作为一级脚本文件,在这个脚本文件中添加其它 CMake 项目的依赖。如下所示,一级脚本文件需要使用命令 add_subdirectory() 来指定其它 CMakeLists.txt 文件作为依赖项目,然后就像其它预编译库一样进行关联。

# Sets lib_src_DIR to the path of the target CMake project.
set( lib_src_DIR ../gmath )

# Sets lib_build_DIR to the path of the desired output directory.
set( lib_build_DIR ../gmath/outputs )
file(MAKE_DIRECTORY ${lib_build_DIR})

# Adds the CMakeLists.txt file located in the specified directory
# as a build dependency.
add_subdirectory( # Specifies the directory of the CMakeLists.txt file.
                  ${lib_src_DIR}

                  # Specifies the directory for the build outputs.
                  ${lib_build_DIR} )

# Adds the output of the additional CMake build as a prebuilt static
# library and names it lib_gmath.
add_library( lib_gmath STATIC IMPORTED )
set_target_properties( lib_gmath PROPERTIES IMPORTED_LOCATION
                       ${lib_build_DIR}/${ANDROID_ABI}/lib_gmath.a )
include_directories( ${lib_src_DIR}/include )

# Links the top-level CMake build output against lib_gmath.
target_link_libraries( native-lib ... lib_gmath )
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值