Cmake + CMakeLists.txt 编译SO库(JNI编译)

cmake android-ndk google demo- https://github.com/googlesamples/android-ndk

  在Android Studio中使用C/C++库有两种方式:cmake和ndk-build。cmake是最新支持的方法,通过配置CMakeLists.txt文件来实现;ndk-build是传统的方式,通过配置Android.mk文件来实现。
  Cmake是跨平台的一个编译配置工具,android studio 2.2之后就开始支持这个cmake工具了,之前Android studio开发c++都是利用NDK的方式,也就是Android.mk + Application.mk + soucre.cpp的构建方式,然后在gradle构建工具下执行一条命令生成c++ so库并打包进去;而cmake则是 CMakeLists.txt + source.cpp 的形式。

  Android Studio 2.2 之后你有2种选择来编译你写的 c/c++ 代码。一个是 ndk-build + Android.mk + Application.mk 组合,另一个是 CMake + CMakeLists.txt 组合。这2个组合与Android代码和c/c++代码无关,只是不同的构建脚本和构建命令。

  JNI(Java Native Interface),NDK(Native Development Kit),ABI(Application binary interface)。

Android SO文件的兼容和适配- http://blog.coderclock.com/2017/05/07/android/Android-so-files-compatibility-and-adaptation/?ref=myread

-- A C++ library for interacting with JSON- https://github.com/open-source-parsers/jsoncpp
 底层(C++)那里给过来的有可能是.a静态库,也有可能是.so动态库,然后如何集成进项目里,.a是怎么构建出来的,a和
so的区别又是什么?在Android中使用CMake常遇的问题,解决方法是什么。
#include<jni.h>

#define XONGFUNC(name)Java_com_xong_andcmake_jni_##name
extern "C" JNIEXPORT
jstring JNICALL

XONGFUNC(NativeFun_stringFromJNI)(JNIEnv *env, jclass thiz)

  return env->NewStringUTF("Hello,I from C++");

}

用Cmake的方式构建a静态库,so动态库,且集成到项目中- https://github.com/lilinxiong/UseCmakeBuildLib
libcode: 以源码的形式将SDK依赖到cpp中使用
libsosimple: 构建hello简单的.so动态库,且将.so和所需头文件导出到 project/export/libsohello 目录中
libsojsoncpp: 构建jsoncpp的.so动态库,且将.so和所需头文件导出到 project/export/libsojsoncpp 目录中
libasimple: 构建一个hello简单的.a静态库,且将.a和所需头文件导出到 project/export/libahello 目录中
libajsoncpp: 构建jsoncpp的.a静态库,且将.a和所需头文件导出到 project/export/libajsoncpp 目录中

Android导入第三方静态库.a,编译成动态库.so。

> CMake编译SO库

  CMake是一个工程文件生成工具。用户可以使用预定义好的CMake脚本。CMake的CMakeList.txt文件从Linux平台跨到Windows平台。

cmake官方文档(http://www.cmake.org/),cmake 实践

AndroidStudio之NDK开发CMake CMakeLists.txt编写入门-https://blog.csdn.net/tabactivity/article/details/78364296

Android Studio 下Cmake的CMakeLists.txt文件配置(生成多.so模式)- https://blog.csdn.net/u012149399/article/details/79164263
Android studio中NDK开发(一):CMakeLists.txt编写入门- https://blog.csdn.net/liopo/article/details/77686563

Cmake实践- https://blog.csdn.net/xyz599/article/details/53606149

 在linux 下进行开发很多人选择编写makefile 文件进行项目环境搭建,而makefile 文件依赖关系复杂,工作量很大
 采用自动化的项目构建工具cmake 可以将程序员从复杂的makefile 文件中解脱出来。cmake 根据内置的规则和语法来自动生成相关的 makefile 文件进行编译,同时还支持静态库和动态库的构建。

cmake 要求工程主目录和所有存放源代码子目录下都要编写CMakeLists.txt 文件,注意大小写(cm 大写,list中l 大写且落下s).
#cmake file for project association                     #表示注释   
      #author:>---double__song  
      #created:>--2011/03/01  
  
      CMAKE_MINIMUM_REQUIRED(VERSION 2.8)    #cmake 最低版本要求,低于2.6 构建过程会被终止。   
  
      PROJECT(server_project)                          #定义工程名称  
  
      MESSAGE(STATUS "Project: SERVER")               #打印相关消息消息   
      MESSAGE(STATUS "Project Directory: ${PROJECT_SOURCE_DIR}")  
      SET(CMAKE_BUILE_TYPE DEBUG)                      #指定编译类型  
      SET(CMAKE_C_FLAGS_DEBUG "-g -Wall")          #指定编译器   
        
      ADD_SUBDIRECTORY(utility)                              #添加子目录   

      ADD_SUBDIRECTORY(server) 

---------------------------------

Android CMake生成简单so文件:

CMake生成多个.so文件- https://blog.csdn.net/liu_qin_bin/article/details/78108262

1.编写带有Native方法的Java 文件;

2.使用Studio的Terminal控制台,切到app/src/main/java,使用javah -jni *(App包名).native_method(包).Caculate(Java类),生成.h文件;javah -jni com.desaco.practiceknowing.native_method.NativeEncryptDecode

3.将.h文件拷贝到cpp文件夹下,编写.h对应的.cpp文件

4.配置App Gradle文件

android {
    compileSdkVersion 25
    buildToolsVersion '26.0.2'
    defaultConfig {
        applicationId "com.desaco.practiceknowing"
        minSdkVersion 18
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        externalNativeBuild {
            cmake {
                cppFlags "-frtti -fexceptions"
            }
        }

        ndk {
            abiFilters "armeabi", "x86"
        }

    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }

    sourceSets.main {
        jniLibs.srcDirs = ['libs']
        jni.srcDirs = []
    }
}

5.配置CMakeLists文件

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

#这个时候会生成你的.so,不过你不能去clean project,因为你会让你的工程apk的.so被清除。

# 编译出一个动态库 native-lib,源文件只有 src/main/cpp/native-lib.cpp
add_library( # Sets the name of the library.
             caculate-lib
             # Sets the library as a shared library.
             SHARED
             # Provides a relative path to your source file(s).
             src/main/cpp/Caculate.cpp )

# 找到预编译库 log_lib 并link到我们的动态库 native-lib中
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 )

target_link_libraries( # Specifies the target library.
                       caculate-lib
                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

6.build - Make Project,即在app/build/intermediates/cmake/路径下;如果没有配置路径的话

 

CMakeLists.txt中,我们可以使用以下方式设定so的输出路径。 首先,我们需要在CMakeLists.txt文件中添加以下代码来设置so的输出路径: ```cmake set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}) ``` 上述代码设置了CMake生成的so文件的输出路径为`${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}`,其中`${CMAKE_SOURCE_DIR}`代表项目的根目录,`${ANDROID_ABI}`代表当前的Android ABI(Application Binary Interface)。 在这个例子中,我们假设你的项目使用了多个不同的ABI,比如armeabi-v7a、arm64-v8a和x86等。在这种情况下,`${ANDROID_ABI}`将根据当前编译的ABI自动设置为相应的值。 此外,我们还需要在Android.mk文件中添加以下代码,以确保编译生成的so文件被正确复制到相应的输出路径。 ```makefile $(call import-add-path,$(LOCAL_PATH)/../../libs/$(TARGET_ARCH_ABI)) ``` 上述代码将`${PROJECT_PATH}/libs/${TARGET_ARCH_ABI}`路径添加到了编译路径中,其中`${TARGET_ARCH_ABI}`代表当前编译的ABI。 最后,我们需要在app的build.gradle文件中添加以下代码,以确保生成的so文件被正确复制到APK的libs目录下。 ```groovy android { // ... sourceSets { main { jniLibs.srcDirs = ['libs'] } } // ... } ``` 上述代码将项目的libs目录设置为so文件的源目录,这样在构建APK时,so文件就会被复制到APK的libs目录下。 通过以上步骤,我们就可以成功设置CMake生成的so文件的输出路径为项目的libs目录下的相应ABI目录。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值