CMake构建脚本是一个纯文本文件,您必须命名 CMakeLists.txt并包含CMake用于构建C / C ++库的命令。如果您的本机源代码还没有CMake构建脚本,则需要自己创建一个脚本并包含相应的CMake命令。
本节介绍了您应该在构建脚本中包含的一些基本命令,以便告诉CMake在创建本机库时使用哪些源。要了解更多信息,请阅读有关CMake命令的官方文档。
配置新的CMake构建脚本后,您需要 配置Gradle 以将CMake项目包含为构建依赖项,以便Gradle使用您的应用程序的APK构建和打包本机库。
注意:如果您的项目使用ndk-build,则无需创建CMake构建脚本。您可以 通过提供文件路径,将 Gradle配置为包含现有本机库项目 Android.mk。
创建一个CMake构建脚本
要创建可用作CMake构建脚本的纯文本文件,请执行以下操作:
从IDE左侧打开“ 项目”窗格,然后从下拉菜单中选择“ 项目”视图。
右键单击模块的根目录,然后选择“ 新建”>“文件”。
注意:您可以在任何所需位置创建构建脚本。但是,在配置构建脚本时,本机源文件和库的路径与构建脚本的位置相关。
输入“CMakeLists.txt”作为文件名,然后单击“ 确定”。
您现在可以通过添加CMake命令来配置构建脚本。要指示CMake从本机源代码创建本机库,请将cmake_minimum_required()和add_library()命令添加到构建脚本:
#设置构建本机库所需的最小CMake版本。
#这确保可以使用某组CMake功能
#你的构建。
cmake_minimum_required(VERSION 3.4.1)
#指定库名称,指定库是STATIC还是
#SHADED,并提供源代码的相对路径。您可以
#通过添加多个add_library()命令定义多个库,
#和CMake为您构建它们。在构建应用程序时,Gradle
#自动将共享库与APK打包在一起。
add_library(#指定库的名称。
本机LIB
#将库设置为共享库。
共享
#提供源文件的相对路径。
src / main / cpp / native-lib.cpp)
提示:类似于如何告诉CMake从源文件创建本机库,您可以使用该 命令告诉CMake从这些源文件创建可执行文件。但是,从本机源构建可执行文件是可选的,构建包装到APK中的本机库可以满足大多数项目要求。 add_executable()
使用时,将源文件或库添加到CMake构建脚本时 add_library(),在同步项目后,Android Studio还会在项目视图中显示关联的头文件。但是,为了让CMake在编译期间找到头文件,您需要将include_directories()命令添加到CMake构建脚本并指定头的路径:
add_library(…)
#指定本机头文件的路径。
include_directories(SRC /主/ CPP /包含/)
CMake用于命名库文件的约定如下:
liblibrary-name.so
例如,如果在构建脚本中将“native-lib”指定为共享库的名称,则CMake会创建一个名为的文件 libnative-lib.so。但是,在Java或Kotlin代码中加载此库时,请使用您在CMake构建脚本中指定的名称:
静态{
系统。loadLibrary (“native-lib” );
}
注意:如果您在CMake构建脚本中重命名或删除库,则需要在Gradle应用更改之前清理项目,或从APK中删除旧版本的库。要清理项目,请从菜单栏中选择“ 生成”>“清理项目 ”。
Android Studio会自动将源文件和标题添加到“ 项目”窗格中的 cpp组。通过使用多个命令,您可以为CMake定义其他库以从其他源文件构建。 add_library()
添加NDK API
Android NDK提供了一组您可能会觉得有用的本机API和库。您可以通过在项目的 脚本文件中包含NDK库来使用任何这些API CMakeLists.txt。
Android平台上已经存在预构建的NDK库,因此您无需构建它们或将它们打包到APK中。因为NDK库已经是CMake搜索路径的一部分,所以您甚至不需要在本地NDK安装中指定库的位置 - 您只需要为CMake提供您要使用的库的名称并链接它反对你自己的本土图书馆。
将find_library()命令添加到CMake构建脚本以查找NDK库并将其路径存储为变量。您可以使用此变量在构建脚本的其他部分中引用NDK库。以下示例查找特定于Android的日志支持库, 并将其路径存储在log-lib:
find_library(#定义存储的路径变量的名称
#NDK库的位置。
登录LIB
#指定NDK库的名称
#CMake需要找到。
日志)
为了让本机库调用库中的log 函数,您需要使用target_link_libraries()CMake构建脚本中的命令链接库:
find_library(…)
#将本机库与一个或多个其他本机库相链接。
target_link_libraries(#指定目标库。
本机LIB
#将日志库链接到目标库。
$ {log-lib})
NDK还包含一些库作为源代码,您需要构建和链接到本机库。您可以使用add_library()CMake构建脚本中的命令将源代码编译到本机库中。要提供本地NDK库的ANDROID_NDK路径,可以使用Android Studio自动为您定义的 路径变量。
以下命令告诉CMake构建 android_native_app_glue.c(管理NativeActivity 生命周期事件和触摸输入)到静态库并将其链接到 native-lib:
add_library(app-glue
静态的
$ {ANDROID_NDK} /sources/android/native_app_glue/android_native_app_glue.c)
#您需要将静态库链接到共享本机库。
target_link_libraries(native-lib app-glue $ {log-lib})
添加其他预建库
添加预构建的库类似于为CMake指定另一个本机库来构建。但是,因为库已经构建,所以您需要使用该IMPORTED标志告诉CMake您只想将库导入到项目中:
add_library(imported-lib
共享
进口)
然后,您需要使用set_target_properties()命令指定库的路径, 如下所示。
某些库为特定的CPU体系结构或应用程序二进制接口(ABI)提供单独的包 ,并将它们组织到单独的目录中。此方法可帮助库利用某些CPU体系结构,同时允许您仅使用所需库的版本。要将库的多个ABI版本添加到CMake构建脚本,而不必为每个版本的库编写多个命令,可以使用ANDROID_ABI路径变量。此变量使用NDK支持的默认ABI列表,或者 手动配置Gradle使用的ABI的筛选列表 。例如:
add_library(…)
set_target_properties(#指定目标库。
进口-LIB
#指定要定义的参数。
物业IMPORTED_LOCATION
#提供要导入的库的路径。
imported-lib / src / $ {ANDROID_ABI} /libimported-lib.so)
要让CMake在编译期间找到头文件,您需要使用该include_directories()命令并包含头文件的路径:
include_directories(imported-lib / include /)
注意:如果要打包不是构建时依赖项的预构建库(例如,在添加作为依赖项的预构建库时),则imported-lib不需要执行以下指示来链接库。
要将预构建的库链接到您自己的本机库,请将其添加到target_link_libraries()CMake构建脚本中的 命令:
target_link_libraries(native-lib imported-lib app-glue $ {log-lib})
要将预构建的库打包到APK中,您需要 手动配置Gradle并使用该sourceSets块来包含.so文件的路径。构建APK后,您可以使用APK分析器验证Gradle将哪些库打包到您的 APK中。
包括其他CMake项目
如果你想构建多个CMake项目并在Android项目中包含它们的输出,你可以使用一个CMakeLists.txt文件作为顶级CMake构建脚本(这是你链接到Gradle的脚本 )并添加其他CMake项目作为该构建的依赖项脚本。以下顶级CMake构建脚本使用该 add_subdirectory()命令将另一个CMakeLists.txt文件指定为构建依赖项,然后链接其输出,就像对任何其他预构建库一样。
#将lib_src_DIR设置为目标CMake项目的路径。
set(lib_src_DIR …/gmath)
#将lib_build_DIR设置为所需输出目录的路径。
set(lib_build_DIR …/gmath/outputs)
文件(MAKE_DIRECTORY $ {lib_build_DIR})
#添加位于指定目录中的CMakeLists.txt文件
#作为构建依赖项。
add_subdirectory(#指定CMakeLists.txt文件的目录。
$ {} lib_src_DIR
#指定构建输出的目录。
$ {lib_build_DIR})
#将附加CMake构建的输出添加为预构建的静态
#library并将其命名为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)
#将顶级CMake构建输出链接到lib_gmath。
target_link_libraries(native-lib … lib_gmath)