美文网首页JNI
Android NDK(JNI)详解教程一 CMakeLists

Android NDK(JNI)详解教程一 CMakeLists

作者: Kael_Zhang的安卓笔记 | 来源:发表于2023-02-28 11:11 被阅读0次

    什么是NDK、JNI

    • JNI
      Java Native Interface,即 Java 本地接口,可以理解为在 Java 中调用 C/C++ 代码、在 C/C++ 中调用 Java 代码,JNI 是 Java 的,和 Android 无关
    • NDK
      Native Development Kit,Android NDK 是一个工具集,可让您使用 C 和 C++ 等语言以原生代码实现应用的各个部分,NDK 可以理解为 Android 中实现 JNI 的一种手段,通过 NDK,还可以打包 C/C++ 动态库,并自动打包进 APK/AAR 中

    CMakeLists.txt 是什么?

    • Android Studio 新建项目的时候可以选择各种各样的模板,选择 Native C++ 模板就可以创建一个简单的 NDK 项目
      在 app/src/main/cpp 下可以看到有 CMakeLists.txt 和 native-lib.cpp。
    • 当只有一个源文件时,直接使用gcc命令就可以直接编译,如果有很多源文件、团队成员多个时,直接使用gcc命令编译就非常繁琐;这个时候make指令应运而生,可以多人编辑同一个编译规则文件后,make工具依照这个编译规则文件进行编译,源文件、目标文件、目标类型等等都在该文件中体现,这个文件就是makefile文件;但是慢慢地大家发现大项目时编写makefile文件依然是一个繁琐容易出错的事情,这个时候cmake工具就出现了,它可以依据简单的配置文件自动生成makefile、project等文件,这个配置文件就是 CMakeLists.txt !很显然,相对于编写makefile文件,编写cmakelists文件要简单的多。
    • CMakeLists.txt + cmake -> makefile;makefile + make -> 编译出目标结果

    CMakeLists.txt 详解

    • 常用变量
      PROJECT_NAME: 用函数project(demo)指定的项目名称,这里变量的值为demo
      PROJECT_SOURCE_DIR: 工程的根目录
      PROJECT_BINARY_DIR: 执行cmake命令的目录,如果mkdir build ,cd build, cmake ../,的话,该变量的值为build目录
      CMAKE_CURRENT_SOURCE_DIR:当前处理的CMakeLists.txt文件所在目录
      CMAKE_CURRENT_BINARY_DIR: cmake当前正在处理的二进制目录
      CMAKE_CURRENT_LIST_DIR: CMakeLists.txt的完整路径
      CMAKE_CURRENT_LIST_LINE: 当前所在行
      CMAKE_C_FLAGS: 设置C编译选项
      CMAKE_CXX_FLAGS:设置C++编译选项
      CMAKE_INSTALL_PREFIX: 指定install指令安装文件的根目录
      EXECUTABLE_OUTPUT_PATH: 生成目标可执行文件的输出位置
      LIBRARY_OUTPUT_PATH: 库文件输出位置

    • 指定cmake最小版本:(必须设置)

    cmake_minimum_required(VERSION 3.10.2)
    
    • 设置项目名称:(必须设置)
    project("projectname")
    
    • 设置编译类型:(必须设置)
    add_executable(projectname native-lib.cpp) //生成可执行文件
    add_library(projectname STATIC native-lib.cpp) //生成静态库(默认)
    add_library(projectname SHARED native-lib.cpp) //生成动态库
    
    • 制定编译包含的源文件(必须设置)
      1.明确指定源文件
    add_library(projectname SHARED native-lib.cpp)
    

    2.搜索指定目录下所有源文件(不会递归遍历子目录)

    //搜索一个目录下所有的源代码文件,并将列表存储再一个变量中
    aux_source_directory(. SRC_LIST)
    add_library(projectname SHARED ${SRC_LIST})
    

    3.自定义搜索源文件规则(推荐使用 aux_source_directory,不推荐使用 file)

    //搜索一个目录下所有的源代码文件,并将列表存储再一个变量中
    file(GLOB SRC_LIST "*.cpp")
    file(GLOB SRC_LIST "*.c")
    file(GLOB SRC_LIST "src/*.cpp")
    aux_source_directory(src SRC_PROTOCOL_LIST)
    add_library(projectname SHARED ${SRC_LIST})
    
    • 查找指定的库文件
    // find_library(VAR name path)查找到指定的预编译库,并将它的路径存储在变量中。
    // 默认的搜索路径为cmake 包含的系统库,因此如果是NDK的公共库只需要指定库的name即可。
    # Searches for a specified prebuilt library and stores the path as a
    # variable. Because CMake includes system libraries in the search path by
    # default, you only need to specify the name of the public NDK library
    # you want to add. CMake verifies that the library exists before
    # completing its build.
    
    find_library( # Sets the name of the path variable.
            log-lib
    
            # Specifies the name of the NDK library that
            # you want CMake to locate.
            log)
    
    • 设置包含的目录(编译环境、头文件等)
    include_directories(
        ${CMAKE_CURRENT_SOURCE_DIR}
        ${CMAKE_CURRENT_SOURCE_DIR}
        ${CMAKE_CURRENT_SOURCE_DIR}/include
    )
    
    • 设置链接库的搜索目录
    link_directories(
        ${CMAKE_CURRENT_SOURCE_DIR}/libs
    )
    
    • 设置target需要连接的库(${log-lib}也可以使用绝对路径、指定链接多个库在${log-lib}后换行追加即可)
    # Specifies libraries CMake should link to your target library. You
    # can link multiple libraries, such as libraries you define in this
    # build script, prebuilt third-party libraries, or system libraries.
    
    target_link_libraries( # Specifies the target library.
            projectname
    
            # Links the target library to the log library
            # included in the NDK.
            ${log-lib})
    
    • set 常用指令
    set(SRC_LIST main.cpp test1.cpp) //设置源代码变量
    set(SRC_LIST test2.cpp) //追加
    set(EXECUTABLE_OUTPUT_PATH [path]) //设置可执行文件的输出路径
    set(LIBRARY_OUTPUT_PATH [output_path]) //设置库文件的输出路径
    set(CMAKE_CXX_FLAGS "-Wall std=c++11") //设置C++编译参数
    
    • 打印信息
    message(${PROJECT_SOURCE_DIR})
    message("build with debug mode")
    message(WARNING "this is warnning message")
    
    • 条件控制
      1.if...elseif...else...endif
      2.while...endwhile
      3.foreach...endforeach

    • 多目录、多源文件、多CMakeLists.txt
      主CMakeLists.txt

    ...
    #添加child目录
    add_subdirectory(child)
    ...
    target_link_libraries( # Specifies the target library.
            projectname
            child
            # Links the target library to the log library
            # included in the NDK.
            ${log-lib})
    

    子CMakeLists.txt

    #child目录下的CMakeLists.txt
    ...
    aux_source_directory(. DIR_SRCS)
    ...
    add_library(
            child
            SHARED
            ${DIR_SRCS}
    )
    

    相关文章

      网友评论

        本文标题:Android NDK(JNI)详解教程一 CMakeLists

        本文链接:https://www.haomeiwen.com/subject/ptehldtx.html