• Android NDK CMakeLists.txt 说明


    1. 新建的NDK项目

    当我们新建了一个NDK项目,打开CMakeLists.txt,会有如下内容,下面对这些命令做了注解

    #指定CMake最小支持版本
    cmake_minimum_required(VERSION 3.18.1)
    
    #项目名称
    project("myndktest")
    
    # 添加一个库,根据native-lib,cpp源文件编译一个native-lib的动态库
    add_library(
            myndktest #设置库的名称
            SHARED #将库设置为动态链接库(.so文件)
            native-lib.cpp) # 源文件的相对路径
    
    # 查找系统库,这里查找的是系统日志库,并赋值给变量lig-lib
    # 实际路径:D:\Android\SDK\ndk-bundle\platforms\android-21\arch-arm\usr\lib\liblog.so
    find_library( 
            log-lib #设置名称
            log) # 指定在NDK库中的路径
    
    
    # 设置依赖的库 (第一个参数必须为目标模块,顺序不能换)
    target_link_libraries( # Specifies the target library.
            myndktest
            ${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

    2. 常用的一些命令

    2.1 cmake_minimum_required

    指定Cmake最低支持的版本

    2.2 aux_source_directory(. DIR_SRCS)

    查找当前目录所有源文件,并将源文件名称列表保存到DIR_SRCS变量,但是不能查找子目录

    2.3 add_library

    作用一:添加一个库
    add_library(<name> [STATIC|SHARED|MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN)
    
    • 1

    name:设置库的名称
    STATIC|SHARED|MODULE:指定库的类型。STATIC:静态库,SHARED:动态库(.so文件),MODULE:在使用dyld的系统有效,若不支持dyld,等同于STATIC
    EXCLUDE_FROM_ALL:表示该库不会被默认构建
    source1 source2 ... sourceN: 用来指定库的源文件

    作用二:导入预编译库

    添加一个已存在的预编译库,名为
    一般配合set_target_properties使用

    add_library(<name> <STATIC|SHARED|MODULE|UNKNOWN> IMPORTED)
    
    • 1

    比如

    add_library(test SHARED IMPORTED)
    
    set_target_properties(
          test #指定目标库名
          PROPERTIES IMPORTED_LOCATION #指明要设定的参数
          库路径/${ANDROID_ABI}/xxxxx.so #导入库的路径
          )  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.4 常用命令之set

    用来设置CMake的变量

    # 设置可执行文件的输出路径 (EXECUTABLE_OUTPUT_PATH是全局变量)
    set(EXECUTABLE_OUTPUT_PATH [output_path])
    # 设置库文件的输出路径 (LIBRARY_OUTPUT_PATH是全局变量)
    set(LIBRARY_OUTPUT_PATH [output_path])
    # 设置C++编译参数 (CMAKE_CXX_FLAGS是全局变量)
    set(CMAKE_CXX_FLAGS "-Wall std=c++11")
    # 设置源文件集合 (SOURCE_FILES是本地变量即自定义变量)
    set(SOURCE_FILES main.cpp test.cpp ...)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.5 include_directories

    设置头文件目录,相当于g++选项中的-l参数

    #可以使用相对或绝对路径,也可以用自定义的变量值
    include_directories(./include ${MY_INCLUDE})
    
    • 1
    • 2

    2.6 add_executable

    添加可执行文件

    add_executable(<name> ${SRC_LIST})
    
    • 1

    2.7 target_link_libraries

    将若干库链接到目标库文件

    target_link_libraries(<name> lib1 lib2 lib3)
    
    • 1

    2.8 add_definitions

    add_definitions(-DFOO -DDEBUG ...)
    
    • 1

    为当前路径以及子目录的源文件加入由-D引入的define flag,通常用来添加编译参数

    2.9 add_subDirectory

    如果当前目录下还有子目录时可以用add_subDirectory,子目录中也需要包含有CMakeLists.txt

    2.10 file命令

    进行文件操作
    在这里插入图片描述

    2.11 set_directory_properties

    set_directory_properties(PROPERTIES prop1 value1 prop2 value2)  
    
    • 1

    设置某个路径的一种属性
    prop1prop2代表属性,取值为
    INCLUDE_DIRECTORIES
    LINK_DIRECTORIES
    INCLUDE_REGULAR_EXPRESSION
    ADDITIONAL_MAKE_CLEAN_FILES

    2.12 set_property

    在给定的作用域内设置一个命名的属性

    3. 常用处理

    3.1 多个源文件处理

    如果源文件很多,把所有文件一个个加入很麻烦,可以使用aux_source_directory命令或file命令,查找指定目录下的所有源文件,然后将结果存进指定变量名。

    # 查找当前目录所有源文件,并将名称保存到 DIR_SRCS 变量,不能查找子目录
    aux_source_directory(. DIR_SRCS)
    # 也可以使用
    file(GLOB DIR_SRCS *.c *.cpp)
    
    add_library(
            myndktest
            SHARED
            ${DIR_SRCS})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.2 多目录多源文件处理

    主目录中的CMakeLists.txt中添加add_subdirectory(child)命令,指明本项目包含一个子项目child
    并在target_link_libraries指明本项目需要链接一个名为child的库。

    aux_source_directory(. DIR_SRCS)
    # 添加 child 子目录下的cmakelist
    add_subdirectory(child)
    
    add_library(
            native-lib
            SHARED
            ${DIR_SRCS}
    )
    
    target_link_libraries(native-lib child)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    子目录child中创建CMakeLists.txt,这里child编译为动态库

    aux_source_directory(. DIR_LIB_SRCS)
    add_library(
        child
        SHARED
        ${DIR_LIB_SRCS}
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3.3 添加预编译库(Android6.0版本以后)

    Android6.0及以上版本,使用这种方式添加预编译动态库

    # set命令定义一个变量
    # CMAKE_C_FLAGS : c的参数,会传递给编译器
    # 如果是c++文件,需要用CMAKE_CXX_FLAGS
    # -L : 库的查找路径
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -L[SO所在目录]")
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.4 添加头文件目录

    为了确保CMake可以字啊编译时定位头文件,使用include_directories,相当于g++选项中的-l参数。
    这样就可以使用#include ,否则需要使用#include "path/xx.h"

    # 设置头文件目录
    include_directories(<文件目录>)
    set(CMAKE_C_FLAGS  "${CMAKE_C_FLAGS} -L[SO所在目录]")
    aux_source_directory(. DIR_SRCS)
    add_library(
            native-lib
            SHARED
            ${DIR_SRCS}
    )
    target_link_libraries(native-lib imported-lib)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.5 Build.gradle配置

    android {
      	//...
        defaultConfig {
          	//...
            externalNativeBuild {
                cmake {
                    //使用的编译器 clang/gcc
                    //cmake默认就是 gnustl_static arguments "-DANDROID_TOOLCHAIN=clang","-DANDROID_STL=gnustl_static"
                    //指定cflags和cppflags,效果和cmakelist使用一样
                    cFlags ""
                    cppFlags ""
                    //指定需要编译的CPU架构
                    abiFilters "armeabi-v7a","arm64-v8a"
                }
            }
        }
        externalNativeBuild {
            cmake {
                //指定CMakeLists.txt文件相较于当前Build.gradle的路径
                path file('src/main/cpp/CMakeLists.txt')
                //设置CMake版本
                version '3.18.1'
            }
        }
        //...
    }
    
    • 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
  • 相关阅读:
    【JY】YJK前处理参数详解及常见问题分析:刚度系数(三)
    算法--差分
    springboot本地启动多个模块报错:Address already in use: JVM_Bind
    C++(第四篇):C++的类和对象(下 —— 再谈构造函数、static成员、成员初始化、友元、内部类)
    数据库事务到底是什么?
    我用python分析买房数据
    麒麟KYLINIOS软件仓库搭建02-软件仓库添加新的软件包
    阈值与平滑处理
    点云从入门到精通技术详解100篇-LiDAR 点云与影像匹配点云的滤波方法研究与应用(中)
    Golang 必知必会Go Mod命令
  • 原文地址:https://blog.csdn.net/EthanCo/article/details/126542287