从上篇文章中,大家按操作勾选了support C++后,应该可以发现,项目中会多了个cpp文件夹,里面有.cpp文件,还有个CMakeLists.txt,这个CMakeLists.txt就是cmake编译的配置文件,所以我们这就说一下怎样配置CMakeLists,和怎样用另外的这一种方法生成所要的so库。


mysql cmake 编译 cmake编译so_编译so库


首先,我们在StringJni.java中再声明一个native方法getStringSecond


mysql cmake 编译 cmake编译so_jni_02


方法有一个int类型的参数type,然后再对应的用C++代码实现这个方法,这次我们不用javah生成头文件了,直接在main任意目录下新建一个.cpp文件,文件名可以随便写,然后实现方法



#include <jni.h>
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_qjl_ndklibrary_StringJni_getStringSecond(JNIEnv *env, jobject jobject1, jint type) {
    return (env) -> NewStringUTF("Hello JNI Second");
}

方法的命名还是和javah命令生成的一样的命名方式,如果不知道怎样命名,可以在native方法的声明外点击Alt+Enter键,右边显示的就是方法名。

mysql cmake 编译 cmake编译so_cmake_03

方法的命名还是和javah命令生成的一样的命名方式,如果不知道怎样命名,可以在native方法的声明外点击Alt+Enter键,右边显示的就是方法名。


方法都写好后,就可以编辑CMakeLists.txt了


CMakeLists可以设置的很多,想了解的可去查看官方的文档,以下选取了一些做为说明


# Sets the minimum version of CMake required to build the native library. 

 

  #指定最小的版本 

 

  cmake_minimum_required(VERSION 3.4.1) 

 
 
 
 

  #C 的编译选项是 CMAKE_C_FLAGS 

 

  # 指定编译参数,可选 

 

  #SET(CMAKE_CXX_FLAGS "-Wno-error=format-security -Wno-error=pointer-sign") 

 
 
 
 

  #设置生成的so动态库最后输出的路径 

 

  #set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}) 

 
 
 
 

  #设置头文件搜索路径(和此txt同个路径的头文件无需设置),可选 

 

  #INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/common) 

 
 
 
 

  #指定用到的系统库或者NDK库或者第三方库的搜索路径,可选。 

 

  #LINK_DIRECTORIES(/usr/local/lib) 

 
 
 
 

  #添加子目录,将会调用子目录中的CMakeLists.txt 

 

  #ADD_SUBDIRECTORY(one) 

 

  #ADD_SUBDIRECTORY(two)

CMakeLists是不区分大小写的,以上的我们这个demo可以不设置,用默认的就可以了,下面说说我们要配置的内容

add_library( # Sets the name of the library. 

 

  my-lib 

 
 
 
 

  # Sets the library as a shared library. 

 

  SHARED 

 
 
 
 

  # Provides a relative path to your source file(s). 

 

  src/main/cpp/OtherLib.cpp) 

 
 
 
 
 
 
 

  add_library( # Sets the name of the library. 

 

  my-lib-second 

 
 
 
 

  # Sets the library as a shared library. 

 

  SHARED 

 
 
 
 

  # Provides a relative path to your source file(s). 

 

  src/main/jni/StringJni.cpp) 

 

  #add_library表示新建一个动态库,第一个参数设置生成的so库的名称,第二个参数是生成的库类

STATIC库是目标文件的归档文件,在链接其它目标的时候使用。 SHARED库 会# 被动态链接(动态链接库),在运行时会被加载。MODULE库是一种不会被链接到其它目标中的插


件,但是可能会在运行时使用dlopen-系列的函数,后面的参数是要生成so库.cpp文件位置,可以有多# 个,如果多个,则最后这几个cpp文件会生成一个库,如果要生成多个,可以add多个library.


# 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 ) 

 
 
 
 

  # 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. 

 
#该命令用于查找库。将创建一个名为log-lib 
 的缓存条目以存储此命令的结果。如果找到
 
#该库,结果将存储在该变量中,log为搜索库的名称,其它的参数还有能指定搜索的位置。
 

  target_link_libraries( # Specifies the target library. 

 

  my-lib 

 
 
 
 

  # Links the target library to the log library 

 

  # included in the NDK. 

 

  ${log-lib} )



最后,在build.gradle下配置cmake


externalNativeBuild { 

 

  cmake { 

 

  path "CMakeLists.txt" 

 

  } 

 

  }


然后编译,编译完成后会在build的cmake目录下生成相应的so库


mysql cmake 编译 cmake编译so_android_04

方法的命名还是和javah命令生成的一样的命名方式,如果不知道怎样命名,可以在native方法的声明外点击Alt+Enter键,右边显示的就是方法名。


最后使用的方法与上篇的方法一样,就可以了,现在android studio对JNI的支持方便了很多,可以更简单的进行JNI的调用了。



方法的命名还是和javah命令生成的一样的命名方式,如果不知道怎样命名,可以在native方法的声明外点击Alt+Enter键,右边显示的就是方法名。