AS下cmake使用

首先将以前写的搬出来方便看

AS下编辑native—较新方法-使用cmake(常用!)

AS可以先写好java类,然后点击错误修正可以自动生成对应c文件与原生函数头。
AS生成的:注意as下如果是cpp文件extern “C” 必加
当你使用错误修正时是生成c版本的时自动不加,当是cpp文件中错误修正时自动加

AS所有配置文件基础目录都是当前同一目录下
例如AndroidManifest.xml中指明了java代码路径
build.gradle中的文件cmakelist从当前下找

创建项目

创建支持原生代码的项目与创建任何其他 Android Studio 项目类似,不过前者还需要额外几个步骤:

  1. 在向导的 Configure your new project 部分,选中 Include C++ Support 复选框。点击 Next。
  2. 正常填写所有其他字段并完成向导接下来的几个部分。
  3. 在向导的 Customize C++ Support 部分,您可以使用下列选项自定义项目:
    C++ Standard:使用下拉列表选择您希望使用哪种 C++ 标准。选择 Toolchain Default 会使用默认的 CMake 设置。
    Exceptions Support:如果您希望启用对 C++ 异常处理的支持,请选中此复选框。如果启用此复选框,Android Studio 会将 -fexceptions 标志添加到模块级 build.gradle 文件的 cppFlags 中,Gradle 会将其传递到 CMake。
    Runtime Type Information Support:如果您希望支持 RTTI,请选中此复选框。如果启用此复选框,Android Studio 会将 -frtti 标志添加到模块级 build.gradle 文件的 cppFlags 中,Gradle 会将其传递到 CMake。
    点击 Finish。

目录

  1. 在 cpp 组中,您可以找到属于项目的所有原生源文件、标头和预构建库。对于新项目,Android Studio 会创建一个示例 C++ 源文件 native-lib.cpp,并将其置于应用模块的 src/main/cpp/ 目录中。本示例代码提供了一个简单的 C++ 函数 stringFromJNI(),此函数可以返回字符串“Hello from C++”。
  2. 在 External Build Files 组中,您可以找到 CMake 或 ndk-build 的构建脚本。与 build.gradle 文件指示 Gradle 如何构建应用一样,CMake 和 ndk-build 需要一个构建脚本来了解如何构建您的原生库。对于新项目,Android Studio 会创建一个 CMake 构建脚本 CMakeLists.txt,并将其置于模块的根目录中。且必须叫这个名字。
  3. cmake与ndk-build的配置都在build.gradle的管理配置下。
    1
    2
    3
    4
    5
    6
    使用cmake构建,指定文件
    externalNativeBuild {
    cmake {
    path "CMakeLists.txt"
    }
    }

运行过程

  1. Gradle 调用您的外部构建脚本 CMakeLists.txt。
  2. CMake 按照构建脚本中的命令将 C++ 源文件 native-lib.cpp 编译到共享的对象库中,并命名为 libnative-lib.so,Gradle 随后会将其打包到 APK 中。
  3. 运行时,应用的 MainActivity 会使用 System.loadLibrary() 加载原生库。现在,应用可以使用库的原生函数 stringFromJNI()。
  4. MainActivity.onCreate() 调用 stringFromJNI(),这将返回“Hello from C++”并使用这些文字更新 TextView。

CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)
CMake最小版本使用的是3.4.1。

add_library()

这个就是往项目中添加要生成的东西 即使是第三方库生成或使用也要先生成目标文件,这里决定最后lib中有什么
配置so库信息(为当前当前脚本文件添加库)
参一:这个是声明引用so库的名称,在项目中,如果需要使用这个so文件,引用的名称就是这个。生成的会加前后缀
参二:
STATIC:静态库,是目标文件的归档文件,在链接其它目标的时候使用。
SHARED:动态库,会被动态链接,在运行时被加载。
MODULE:模块库,是不会被链接到其它目标中的插件,但是可能会在运行时使用dlopen-系列的函数动态链接。
参三:构建so库的源文件路径,注意是相对cmakelist的。

还可以用来构建有源代码的库

1
2
3
4
5
6
add_library( app-glue
STATIC
${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c )
# You need to link static libraries against your shared native library.
target_link_libraries( native-lib app-glue ${log-lib} )

还可以用来构建使用已有so的库,set_target_properties用于设置查找so库的路径

1
2
3
4
5
6
add_library( imported-lib
SHARED
IMPORTED )
set_target_properties(target1 target2 ...
PROPERTIES prop1 value1
prop2 value2 ...)

include_directories

配置头文件路径,注意这里指定的是目录而非文件

find_library()

这个就是用来使用android上提供的
这个方法与我们要创建的so库无关而是使用NDK的Apis或者库,默认情况下Android平台集成了很多NDK库文件,所以这些文件是没有必要打包到apk里面去的。直接声明想要使用的库名称即可
参一:出口,存放库的路径
参二:指定使用的库

这个就是一个连接操作,将后面的连接到第一个文件中

如果你本地的库(native-lib)想要调用log库的方法,那么就需要配置这个属性,意思是把NDK库关联到本地库。
参一:要被关联的库名称
其它参:要关联的库名称。${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
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
64
#添加一个库,可用于目标
add_library( # 指定库的名称。生成后会加前后缀根据下面的设置
native-lib
# 将库设置为共享库。
SHARED
# 提供源文件的相对路径。可以多个文件编译为一个库
src/main/jni/native-lib.cpp )
#添加头文件
include_directories(src/main/cpp/include/)
______________________________________________________________________
#从源码形式的库获取
add_library( app-glue
STATIC
${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c )
______________________________________________________________________
#添加一个已有的库
add_library( imported-lib
SHARED
#表示这个已经存在,只要导入就可以,set_target_properties()指定路径
IMPORTED )
#指定目标库的位置
set_target_properties( # Specifies the target library.
imported-lib
# Specifies the parameter you want to define.
PROPERTIES IMPORTED_LOCATION
# Provides the path to the library you want to import.
imported-lib/src/${ANDROID_ABI}/libimported-lib.so )
#编译时定位标头文件
include_directories( imported-lib/include/ )
_______________________________________________________________________
#使用android上存在的
find_library( # find用来找到库,这个变量被赋予要找的库的路径
log-lib
# 这里是你要找的库的名字,该库已存在于android中
log )
_______________________________________________________________________
#第一个参数是最终要生成的,其它都是需要连接进去的
target_link_libraries( # 指定目标库
native-lib
#连接已有的库
imported-lib
#连接自己建的库
app-glue
# 连接的android ndk平台已存在目标,将找到的路径传入即可
${log-lib} )