Android NDK(JNI)详解教程一 CMakeLists.txt 详解

什么是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}
)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容