• Android NDK 之CmakeList 笔记


    前言

    在android ndk 开发中,是经常需要通过cmakelist 来配置 引入库或者编译配置的。这里总结一些常用的cmakelist 中api 语法。

    1.add_library 添加库

    c++库:静态库(.a、.lib)和动态库(.so、.dll),更多详情,请度娘。

    1.1添加已经编译好的so库

    #添加 libavcodec-56.so 库
    add_library(
        avcodec-lib
        SHARED
        IMPORTED)
    set_target_properties( avcodec-lib
                           PROPERTIES IMPORTED_LOCATION
                           ${distribution_DIR}/${ANDROID_ABI}/libavcodec-56.so)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • add_library(): 第一个参数avcodec-lib 是库的别名,第二个参数SHARED是库类型,这里是动态库。第三个参数IMPORTED是引入方式,这里是导入,通常是默认这个。

    • set_target_propeties() 中:第一个参数avcodec-lib 是库的别名 , 第二个参数PROPERTIES IMPORTED_LOCATION是指定引入方式,这里是本地引入。第三个参数${distribution_DIR}/${ANDROID_ABI}/libavcodec-56.so 是so库的路径。

    因此,引入第三方的库使用add_library就要使用set_target_propeties这个组合。

    1.2 添加c/c++ 源代码编译的库

    #添加一个名为webp_view的动态库,指定包含 webp_decode.cpp和webp_view.cpp文件。
    add_library(webp_view SHARED
        webp_decode.cpp
        webp_view.cpp)
    
    • 1
    • 2
    • 3
    • 4

    这种方式是添加c/c++源码文件,这种不需要使用set_target_propeties()去设置路径。第一个参数webp_view: 是库名字,第二个参数shared: 是动态库,第三个参数webp_decode.cpp webp_view.cpp 是需要参与编译的源文件。

    2.find_library 查找库

    用于查找使用android ndk 中系统库,比如 打印日志log库。

    #查找log库,且重新别名为log-lib
    find_library( log-lib  log )
    
    • 1
    • 2

    第一个参数log-lib : 重新定义log库的别名 ,第二个参数log : 需要使用库的库名。

    3. set 设置变量

    用于显示的声明一个变量,比如定义一个变量,其地址是根目录下的libwebp 目录。

    # web_simple_proj_dir=项目root目录的绝对路径
    get_filename_component(WEBP_SAMPLE_PROJ_DIR
                           ${CMAKE_CURRENT_SOURCE_DIR}/../../../.. ABSOLUTE)
    
    
    # 设置webp_src_dir(即libwebp的目录地址)= 项目root目录/libwebp
    set(WEBP_SRC_DIR ${WEBP_SAMPLE_PROJ_DIR}/libwebp)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    也可以设置cmake 中的一些配置:

    设置c++ 11的版本:

    # 使用c++11
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
    
    • 1
    • 2

    设置c 99 的版本:

    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
    
    • 1

    更改so库中一些输出路径: 比如输出在在app/src/main下看到jniLibs目录

    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI})
    
    • 1

    4. include_directories 导入头文件

    4.1 include_directories

    当前CMakeList.txt中的所有目标以及所有在其调用点之后添加的子目录中的所有目标将具有此头文件搜索路径。

    #导入ndk 中native_app_glue目录下的头文件
    include_directories(${ANDROID_NDK}/sources/android/native_app_glue)
    
    • 1
    • 2

    4.2 target_include_directories

    格式:target_include_directories( [SYSTEM] [AFTER|BEFORE] [items1…])

    指定目标tagert 包含的头文件路径。

    • INTERFACE:target对应的头文件使用
    • PRIVATE:target对应的源文件使用
    • PUBLIC:target对应的头文件、源文件都使用
    # 为web_view 导入指定的头文件( private 限定是源文件才可以使用导入的头文件)。
    target_include_directories(webp_view PRIVATE
        ${WEBP_SRC_DIR}/examples
        ${WEBP_SRC_DIR}/src)
    
    • 1
    • 2
    • 3
    • 4

    ps:如果有不同目录相同名称的头文件会产生影响,所以这里建议针对特定的target进行添加头文件的操作,不要使用include_directories

    5.link_libraries 关联需链接的库

    在linux中c/c++的编译一般都是用gcc来编译的,c/c++编译时会产生.o文件要通过make工具来把这些.o文件链接起来,这样才能得一个可执行程序。所以.so在编译时要把所有库链接起来才能编。

    target_link_libraries 是为了关联我们自己的库和一些第三方库或者系统库。把要链接的库别名都写到这里就可以了,如果是系统的库要用这个格式${库的名字},比如:

    # 为webp_view 添加各种依赖库
    target_link_libraries(webp_view android log m native_app_glue webp)
    
    • 1
    • 2

    6.add_subdirectory 添加其他cmakelist 编译

    在实际开发中,项目可能还包含其他子项目(使用一些开源库的源码)的编译,这时需要指定子项目的cmakelist 参与编译。

    #调用libwebp module 下 CamkeList.txt
    add_subdirectory(${WEBP_SRC_DIR} ${WEBP_SRC_DIR}/build/)
    
    • 1
    • 2

    add_subdirectory() 是可以引入多个需要编译的cmakelist 的目录。这里webp_src_dir 在3.set设置变量中定义好的路径=项目root目录/libwebp。

    7.一个谷歌官方的webp 的cmakelist 案例

    先看下webp lib库的目录结构:
    在这里插入图片描述

    接着看下app工程 的目录结构:
    在这里插入图片描述

    最后看下app module中完整cmakelist :

    # 使用camke 的版本
    cmake_minimum_required(VERSION 3.4.1)
    set(CMAKE_VERBOSE_MAKEFILE on)
    
    # 定义一个变量web_simple_proj_dir=项目root目录的绝对路径
    get_filename_component(WEBP_SAMPLE_PROJ_DIR
                           ${CMAKE_CURRENT_SOURCE_DIR}/../../../.. ABSOLUTE)
    
    
    # 设置webp_src_dir(即libwebp的目录地址)= 项目root目录/libwebp
    set(WEBP_SRC_DIR ${WEBP_SAMPLE_PROJ_DIR}/libwebp)
    
    
    # clone the dependency repo.
    # git submodule could also be used if this sample does not need
    #     Android Studio's "Import Android code sample" option
    
    # 若是不存在libwebp module(即不存在libwebp 目录或者libwebp/CMakeLists.txt) ,执行 从谷歌仓库拷贝 libwebp 1.0.0版本 到webp_src_dir的目录下。
    # 或者通过AndroidStudio  import 导入方式导入libwebp module源码
    if ((NOT EXISTS ${WEBP_SRC_DIR}) OR
        (NOT EXISTS ${WEBP_SRC_DIR}/CMakeLists.txt))
        execute_process(COMMAND git clone -b 1.0.0
                                https://chromium.googlesource.com/webm/libwebp
                                libwebp
                        WORKING_DIRECTORY ${WEBP_SAMPLE_PROJ_DIR}/)
    endif()
    
    SET(WEBP_ENABLE_SWAP_16BIT_CSP ON CACHE BOOL
        "Enable byte swap for 16 bit colorspaces." FORCE)
        
    #调用libwebp module 下 CamkeList.txt
    add_subdirectory(${WEBP_SRC_DIR} ${WEBP_SRC_DIR}/build/)
    
    # build native_app_glue as a static lib
    # 导入ndk路径/source/android/native_app_glue 目录下的头文件
    include_directories(${ANDROID_NDK}/sources/android/native_app_glue)
    #添加一个名为native_app_glue的静态库,包含的文件有ndk路径/source/android/native_app_glue.c
    add_library(native_app_glue STATIC
        ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
    
    # 使用c99 版本
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
    # 使用c++11
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
    
    # Export ANativeActivity_onCreate(),
    
    # Refer to: https://github.com/android-ndk/ndk/issues/381.
    set(CMAKE_SHARED_LINKER_FLAGS
        "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")
        
    #添加一个名为webp_view的动态库,指定包含 webp_decode.cpp和webp_view.cpp文件。
    add_library(webp_view SHARED
        webp_decode.cpp
        webp_view.cpp)
    # 为web_view 导入指定的头文件( private 限定是源文件才可以使用导入的头文件)。
    target_include_directories(webp_view PRIVATE
        ${WEBP_SRC_DIR}/examples
        ${WEBP_SRC_DIR}/src)
    
    # 为webp_view 添加各种依赖库
    target_link_libraries(webp_view android log m native_app_glue webp)
    
    
    • 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
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
  • 相关阅读:
    python RPC框架
    C++的构造函数
    用proteus直接仿真stm32-可以完全丢弃编程器
    秒杀系统设计
    Threads and Locks
    阿里 P8 最新版 SpringCloud 面试题是如何让我“颜面扫地”的?
    NeuPhysics: Editable Neural Geometry and Physics from Monocular Videos 解读
    数据标注典型案例,景联文科技如何助力企业搭建数据方案
    近端安全互联样例使用指导
    React知识点系列(7)-每天10个小知识
  • 原文地址:https://blog.csdn.net/hexingen/article/details/125908779