NDK开发(一):初识NDK,从CMakeLists开始

   在Android开发进阶之路上,ndk开发是一项重要、必不可少的技能,是众多公司检验Android高级开发人员的考核点之一,在此我也记录下ndk学习历程 。

   在这里就不介绍如何搭建ndk环境及新建带有ndk开发环境的项目,或在老项目中配置ndk的开发环境,大家可以自行google。以下我们进入正文:

   新建ndk开发环境的工程后,我们发现多了一个C++路径,以后开发中所有的C++文件和库都将放到这个路径之下。这个文件夹下默认生成了两个文件,先看native-lib.cpp这个文件:

NDK开发(一):初识NDK,从CMakeLists开始_第1张图片

这里面的方法就是java调用c的方法,就是通过这样的方式关联的,需要注意的是这个方法的命名规则:

Java_文件路径_类名_java文件里的方法名

NDK开发(一):初识NDK,从CMakeLists开始_第2张图片

   接下来我们来看下CMakeLists.txt这个文件:

   默认情况下只有四条命令:

#指定cmake最低支持的版本(这是一条可选命令)
cmake_minimum_required(VERSION 3.4.1)
#设置本地动态库,编译生成动态库
#
add_library(
        #添加库的库名
        native-lib
        #添加库的类型  STATIC:静态库  SHARED :动态库  MODULE:在使用dyld的系统有效,若不支持dyld,等同于SHARED
        SHARED
        #表示该库不会被默认构建
        #EXCLUDE_FROM_ALL  native-lib.cpp
        native-lib.cpp)
#查找系统库,日志输出文件log
find_library(
        log-lib
        log)
#需要连接或者编译库
target_link_libraries(
        native-lib
        ${log-lib})

除此之外还有一些比较常用的命令如下:

#查找当前目录的所有源文件,并将源文件名称列表保存到DIR_SRCS变量
#不能查找子目录
#前一个参数为要查找的路径(.代表当前路径)
aux_source_directory(. DIR_SRCS)


#导入预编译库
#例如,假设我们本地项目引用了libimported-lib.so
#android6.0之前
add_library(
        imported-lib
        SHARED
        IMPORTED)
set_target_properties(
        #指明目标库名
        test
        #指明要设置的参数
        PROPERTIES IMPORTED_LOCATION
        #导入库的路径
        <路径>/libimported-lib.so)
aux_source_directory(. DIR_SCRS)
add_library(
        native-lib
        SHARED
        ${DIR_SRCS})
target_link_libraries(native-lib impoted-lib)
#android6.0之后
#set命令定义一个变量
#CMAKE_C_FLAGS:c的参数,会传递给编译器
#如果是c++文件,需要CMAKE_CXX_FLAGS
#-L:库的查找路径
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -L[so所在的目录]")
#设置头文件目录
include_directories(<文件目录>)
aux_source_directory(. DIR_SCRS)
add_library(
        native-lib
        SHARED
        ${DIR_SRCS})

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

#设置头文件目录
#相当于g++选项中的-i参数
#可以用相对路径或绝对路径,也可以用自定义的变量值
include_directories(./include ${MY_INCLUDE})

#添加可执行文件
#第一个参数是文件名 第二个参数是源文件
add_executable( ${SRC_LIST})

#将若干库链接到目标库文件
#链接的顺序应当符合gcc链接顺序规则,被链接的库放在依赖它的库的后面,
#即如果lib1依赖于lib2,lib2又依赖于lib3,则命令必须严格按照lib1,lib2,lib3的顺序排列,否则会报错
target_link_libraries(<目标库> lib1 lib2 lib3)
#如果出现相互依赖的静态库,CMake会允许循环依赖,如:
add_library(A STATIC a.c)
add_library(B STATIC b.c)
target_link_libraries(A B)
target_link_libraries(B A)
add_executable(main main.c)
target_link_libraries(main A)

#添加编译参数
add_definitions(-DFOO -DDEBUG ...)

#添加子目录cmake源文件
#如果当前目录下还有子目录时可以使用add_subdirectory,子目录中也需要包含CMakeLists.txt
#sub_dir指定包含CMakeLists.txt和源码文件的子目录位置
#binary_dir 是输出路径,一般可不指定
add_subdirectory(sub_dir [binary_dir])


#file文件操作命令
#将message写入filename文件中,会覆盖原有内容
file(WRITE filename "message")
#将message写入filename文件中,会追加在文件末尾
file(APPEND filename "message")
#从filename文件中读取内容并存储到var变量中,如果指定了numBytes和offset,
#则从offset处开始最多读numbytes个字节,另外如果指定了HEX参数,则内容会以十六进制形式存储在var变量中
file(READ filename var [LIMT numBytes] [OFFSET offset] [HEX])
#重命名文件
file(RENAME  )
#删除文件,等于rm命令
file(REMOVE [file1 ...])
#递归的执行删除文件命令,等于rm .r
file(REMOVE_RECURES [file1 ...])
#根据指定的url下载文件
#timeout时间超时;下载状态会保存到status中;下载日志会保存到log;sum指定所下载文件预期的MD5值,
#如果指定会自动进行比对,如果不一致,则返回一个错误;SHOW_PROGRESS,进度信息会以状态信息的形式被打印出来
file(DOWNLOAD url file [TIMEOUT timeout] [STATUS status] [LOG log] [EXPECTED_MD5 sum] [SHOW_PROGRESS])
#创建目录
file(MAKE_DIRECTORY [dir1 dir2 ...])
#会把path转换为以unix的/为开头的cmake风格路径,保存在result中
file(TO_CMAKE_PATH path result)
#将会为所有匹配查询表达式的文件生成一个文件list,并将改list存储进变量variable里,
#如果一个表达式指定了RELATIVE,返回的结果将会是相对于给定路径的相对路径,
#查询表达式例子:*.cxx,*.vt?
file(GLOB variable [RELATIVE path] [globbing expressions] ...)

#设置某个路径的一种属性
#prop1,prop2代表属性,取值为:
#INCLUDE_DIRECTORIES
#LINL_DIRECTORIES
#INCLUDE_REGULAR_EXPRESSION
#ADDITIONAL_MAKE_CLEAN_FILES
set_directory_properties(PROPERTIES prop1 value1 prop2 value2)


#多个源文件添加方式,选其一即可
#方法1:
aux_source_directory(.DIR_SRCS)
#方法2:
file(GLOB DIR_SRCS *.c *.cpp)
add_library(
        native-lib
        SHARED
        ${DIR_SRCS})


#添加多目录,多源文件的处理方式
#主目录中的CMakeLists.txt中添加add_subdirectory(child)命令,指明本项目包含一个子项目child
#并在target_link_libraries指明本项目需要链接一个名为child的库
#子目录child中创建CMakeLista.txt,这里child编译为共享库
cmake_minimum_required(VERSION 3.4.1)
aux_source_directory(. DIR_SRCS)
#添加child子目录下的cmakelists
add_subdirectory(child)

add_library(
        native-lib
        SHARED
        ${DIR_SRCS})
target_link_libraries(native-lib child)
#-------------------------------------------
#child目录下的CmakeLists.txt:
cmake_minimum_required(VERSIO 3.4.1)
aux_source_directory(. DIR_LIB_SRCS)
add_library(
        child
        SHARED
        ${DIR_LIB_SRCS})

 

你可能感兴趣的:(ndk)