【CMake】Android Studio 中使用 CMake 编译单个 C++ 源文件 ( 常用的 CMake 命令解析 )

举报
韩曙亮 发表于 2022/01/11 01:52:36 2022/01/11
【摘要】 文章目录 一、Android Studio 中使用 CMake 编译单个 C++ 源文件二、cmake_minimum_required 命令设置最小 CMake 版本三、project 命令设置...



该系列博客的应用场景是 Android Studio 下 NDK 编程 , 使用 CMake 构建 C/C++ 工程 ;





一、Android Studio 中使用 CMake 编译单个 C++ 源文件



Android Studio 自动生成的 CMakeLists.txt 构建脚本就是默认编译单个 C++ 源码的构建脚本 ;

cmake_minimum_required(VERSION 3.10.2)

project("cmake")

add_library(
        native-lib
        SHARED
        native-lib.cpp )

find_library( 
        log-lib
        log )

target_link_libraries( 
        native-lib
        ${log-lib} )

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

下面开始逐个解析上面使用到的命令 ;

CMakeList.txt 中使用到的命令一共只有 93 93 93 个, 47 47 47 个脚本命令 , 46 46 46 个工程命令 , 可以到 CMake 官方查询这些命令的用法 , 在稍后的博客中也会逐一讲解 Android Studio 中的 NDK 常用的 CMake 命令 ;

参考 【CMake】CMake 引入 ( Android NDK 构建脚本 | CMake 命令手册 ) 博客 ;





二、cmake_minimum_required 命令设置最小 CMake 版本



指定 CMake 最低版本 : 使用 cmake_minimum_required 命令 , 指定编译 C/C++ 源码的 CMake 工具的最低版本 , 这里会自动生成 ;

# 指定 CMake 最低版本
cmake_minimum_required(VERSION 3.10.2)

  
 
  • 1
  • 2

设置格式说明 : VERSION 是固定必须写的 , VERSION 后面就是 CMake 的版本号 ;

这里推荐大家一定要安装最新的 CMake 版本 ;

在这里插入图片描述

官方文档地址 : https://cmake.org/cmake/help/latest/command/cmake_minimum_required.html





三、project 命令设置工程名称



project 命令用于声明工程名称 , 同时还可以指定工程支持的语言 , 其中支持的语言可以忽略, 默认支持所有的语言 ;

# 声明项目并为项目命名.
project("cmake")

  
 
  • 1
  • 2

如果支持 C++ 语言的话 , 可以设置 project(“cmake” CXX) ;

官方文档地址 : https://cmake.org/cmake/help/latest/command/project.html





四、add_library 命令设置生成函数库



add_library 命令用于设置生成函数库 , 这个函数库包括 so 动态库 和 a 静态库 ;


add_library 命令作用 : 创建函数库并为函数库命名.

  • 函数库类型 : 设置该函数库的类型 ① 静态库 STATIC ② 动态库 SHARED.

  • 相对路径 : 指定源码路径, 注意是相对路径.

  • 函数库个数据 : 可以定义多个函数库, CMake 会负责构建这些函数库.

  • 动态库打包 : Gradle 会自动将动态库打包到 APK 安装包中.


add_library 命令三个参数说明 :

  • 参数 1 : 设置生成的动态库名称.

  • 参数 2 : 设置生成的函数库类型 : ① 静态库 STATIC ② 动态库 SHARED.

  • 参数 3 : 配置要编译的源文件.

# 创建函数库并为函数库命名.
# 函数库类型 : 设置该函数库的类型 ① 静态库 STATIC ② 动态库 SHARED.
# 相对路径 : 指定源码路径, 注意是相对路径.
# 函数库个数据 : 可以定义多个函数库, CMake 会负责构建这些函数库.
# 动态库打包 : Gradle 会自动将动态库打包到 APK 安装包中.

add_library( # 参数 1 : 设置生成的动态库名称.
        native-lib

        # 参数 2 : 设置生成的函数库类型 : ① 静态库 STATIC ② 动态库 SHARED.
        SHARED

        # 参数 3 : 配置要编译的源文件.
        native-lib.cpp )

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

官方文档地址 : https://cmake.org/cmake/help/latest/command/add_library.html





五、find_library 命令设置查找函数库



find_library 命令的作用是用于搜索函数库 , 找到的函数库的全路径名称保存到第一个参数变量中 ;

搜索存储 : 搜索指定的预编译库, 并存储该预编译库的路径到变量中, 这里存储到了 log-lib 变量中.

指定库名称 : CMake 的搜索路径默认包含了系统库, 只需要指定想添加的公共 NDK 库的名称即可, 这里指定 log 即可. 不需要指定 log 库的完整路径 ndk-bundle\platforms\android-29\arch-arm\usr\lib\liblog.so.

验证存在性 : 在完成编译之前, CMake 会验证该函数库是否存在.

下面的构建脚本作用 : 到预设的目录查找 log 库 , 将找到的路径赋值给 log-lib , 这个路径是 NDK 的 ndk-bundle\platforms\android-29\arch-arm\usr\lib\liblog.so , 不同的 Android 版本号 和 CPU 架构 需要到对应的目录中查找 , 此处是 29 版本 32 位 ARM 架构的日志库

# 搜索存储 : 搜索指定的预编译库, 并存储该预编译库的路径到变量中, 这里存储到了 log-lib 变量中.
# 指定库名称 : CMake 的搜索路径默认包含了系统库, 只需要指定想添加的公共 NDK 库的名称即可, 这里指定 log 即可.
#            不需要指定 log 库的完整路径 ndk-bundle\platforms\android-29\arch-arm\usr\lib\liblog.so.
# 验证存在性 : 在完成编译之前, CMake 会验证该函数库是否存在.

# 到预设的目录查找 log 库 , 将找到的路径赋值给 log-lib
#   这个路径是 NDK 的 ndk-bundle\platforms\android-29\arch-arm\usr\lib\liblog.so
#   不同的 Android 版本号 和 CPU 架构 需要到对应的目录中查找 , 此处是 29 版本 32 位 ARM 架构的日志库

find_library( # 设置保存函数库路径的变量名称.
        log-lib

        # 指定 CMake 想要定位的 NDK 库名称
        log )

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

官方文档地址 : https://cmake.org/cmake/help/latest/command/find_library.html





六、target_link_libraries 命令设置链接函数库



target_link_libraries 命令的作用是为目标函数库添加需要链接的函数库 ;

目标函数库 : 就是在 Java / Kotlin 代码中使用 System.loadLibrary(“native-lib”) 加载的动态库 , 这是整个 C/C++ 代码的调用入口 ;

链接多个函数库 : 指定 CMake 应该连接到目标函数库的若干函数库. 可以链接多个函数库, 如使用的 Android NDK 函数库, 预编译的第三方函数库, 系统库等.

链接函数库命令参数说明 :

  • 参数 1 : 本构建脚本要生成的动态库目 标
  • 参数 2 ~ … : 后面是之前预编译的动态库或静态库 , 或引入的动态库
# 指定 CMake 应该连接到目标函数库的若干函数库.
# 可以链接多个函数库, 如使用的 Android NDK 函数库, 预编译的第三方函数库, 系统库等.
# 链接函数库
#       参数 1 : 本构建脚本要生成的动态库目 标
#       参数 2 ~ ... : 后面是之前预编译的动态库或静态库 , 或引入的动态库

target_link_libraries( # 指定目标函数库.
        native-lib

        # 链接目标库到 NDK 中包含的日志库.
        ${log-lib} )

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

官方文档 : https://cmake.org/cmake/help/latest/command/target_link_libraries.html


Kotlin 中的加载动态库 : 与 Java 有些不同 , 这里展示一下 ;

class MainActivity : AppCompatActivity() {
    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    external fun stringFromJNI(): String

    companion object {
        // Used to load the 'native-lib' library on application startup.
        init {
            System.loadLibrary("native-lib")
        }
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14




七、CMakeLists.txt 详细中文注释



下面就是自动生成的 CMake 配置文件 , 我添加中文注释 :


# 指定 CMake 最低版本
cmake_minimum_required(VERSION 3.10.2)

# 声明项目并为项目命名.
project("cmake")

# 创建函数库并为函数库命名.
# 函数库类型 : 设置该函数库的类型 ① 静态库 STATIC ② 动态库 SHARED.
# 相对路径 : 指定源码路径, 注意是相对路径.
# 函数库个数据 : 可以定义多个函数库, CMake 会负责构建这些函数库.
# 动态库打包 : Gradle 会自动将动态库打包到 APK 安装包中.

add_library( # 参数 1 : 设置生成的动态库名称.
        native-lib

        # 参数 2 : 设置生成的函数库类型 : ① 静态库 STATIC ② 动态库 SHARED.
        SHARED

        # 参数 3 : 配置要编译的源文件.
        native-lib.cpp )

# 搜索存储 : 搜索指定的预编译库, 并存储该预编译库的路径到变量中, 这里存储到了 log-lib 变量中.
# 指定库名称 : CMake 的搜索路径默认包含了系统库, 只需要指定想添加的公共 NDK 库的名称即可, 这里指定 log 即可.
#            不需要指定 log 库的完整路径 ndk-bundle\platforms\android-29\arch-arm\usr\lib\liblog.so.
# 验证存在性 : 在完成编译之前, CMake 会验证该函数库是否存在.

# 到预设的目录查找 log 库 , 将找到的路径赋值给 log-lib
#   这个路径是 NDK 的 ndk-bundle\platforms\android-29\arch-arm\usr\lib\liblog.so
#   不同的 Android 版本号 和 CPU 架构 需要到对应的目录中查找 , 此处是 29 版本 32 位 ARM 架构的日志库

find_library( # 设置保存函数库路径的变量名称.
        log-lib

        # 指定 CMake 想要定位的 NDK 库名称
        log )

# 指定 CMake 应该连接到目标函数库的若干函数库.
# 可以链接多个函数库, 如使用的 Android NDK 函数库, 预编译的第三方函数库, 系统库等.
# 链接函数库
#       参数 1 : 本构建脚本要生成的动态库目 标
#       参数 2 ~ ... : 后面是之前预编译的动态库或静态库 , 或引入的动态库

target_link_libraries( # 指定目标函数库.
        native-lib

        # 链接目标库到 NDK 中包含的日志库.
        ${log-lib} )

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

文章来源: hanshuliang.blog.csdn.net,作者:韩曙亮,版权归原作者所有,如需转载,请联系作者。

原文链接:hanshuliang.blog.csdn.net/article/details/111951238

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。