Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库
- 格式:doc
- 大小:19.78 KB
- 文档页数:19
注意:如果要在AndroidStudio里面使用terminal(终端)的话,必须先配置环境变量。
AS中的terminal其实和windows带的中断是一样的,只不过内嵌到了AS上。
1、配置java环境变量(可以百度,配置完成必须重启terminal才能运行javac、javah等命令)。
2、写好如下HelloNDK.java文件(这个文件演示了jni的调用)3、然后执行在AndroidStudio中执行Build-->Make Project,生成class文件。
生成class文件放在了Project的目录\ndk_demo_2\build\intermediates\classes\debug\com\lcj\ndk_demo_2中,并且是隐藏的。
(不查看这个文件也没关系,当然前提是执行没有错误)4、生成h文件4.1在AS的terminal输入javah,然后回车。
----------------------------------------这一步可以省略,我这里将javah怎么使用。
出现如下帮助文档。
这里出现了javah的使用帮助。
我们要用的命令是javah -d <dir> -classpath <path>javah是生成jni头文件的命令;-d是生成的头文件存放的目录(这个目录如果事先没有建立,那么运行成功会自动新建);<dir>是前面-d选项的目录名称,如果目录是src的话,不要写成<src>!!,直接写src就好;-classpath从中加载类的路径命令;<path>是需要生成头文件的class文件的目录。
4.2、进入到使用cd命令进入HelloNDK.java的文件夹main。
cd <dir> 如下的第一行。
如果不进入这个目录等会运行javah的时候会提示:错误: 找不到'com.lcj.ndk_demo_2.HelloNDK' 的类文件。
ndk编译dlib -回复NDK编译dlib:如何在Android上使用C++库在移动应用开发中,经常需要使用到一些高性能的计算功能,如图像处理、人脸识别等。
为了提高性能和灵活性,许多开发者选择使用C++来实现这些功能,并通过使用NDK(Native Development Kit)在Android上编译和使用C++库。
本文将详细介绍如何使用NDK编译dlib库,并在Android应用程序中使用该库。
第一步:准备工作在开始编译dlib之前,我们需要配置好开发环境。
首先,我们需要安装CMake和最新版本的NDK。
CMake是一个流行的用于构建C++应用程序的工具,而NDK则是一个用于开发和编译Android原生代码的工具包。
安装CMake:1. 在CMake官网(2. 在终端中输入cmake version命令,确认CMake已经正确安装。
安装NDK:1. 在Android Studio中打开SDK Manager。
2. 在SDK Tools选项卡中,勾选NDK并点击"Apply"按钮进行安装。
3. 在NDK安装完成后,记下NDK的路径,后面会用到。
第二步:下载并配置dlibdlib是一个强大的C++机器学习和图像处理库,它提供了许多高性能的功能,如人脸识别、目标检测等。
我们需要下载并配置dlib库。
1. 在GitHub上下载最新版本的dlib库(2. 将下载好的dlib库解压到合适的本地目录。
第三步:创建CMakeLists.txt文件为了能够使用CMake来构建和编译dlib库,我们需要创建一个CMakeLists.txt文件,来定义构建和编译过程。
1. 在dlib库的根目录下创建一个名为CMakeLists.txt的文件。
2. 打开CMakeLists.txt文件,添加以下内容:cmake_minimum_required(VERSION 3.4.1)add_library(dlib SHARED)target_include_directories(dlib PRIVATE include)add_library(dlib_native SHARED src/main/cpp/native-lib.cpp)target_link_libraries(dlib_native PRIVATE dlib)以上代码中,我们定义了一个名为dlib的C++库,并将它的头文件目录指定为include文件夹。
cmake ndk路径CMake是一种跨平台的构建工具,可以自动生成Makefile或者Visual Studio等IDE所需的工程文件。
而NDK(Native Development Kit)是Android提供的一种开发工具包,可以让开发者使用C/C++等语言编写Android应用程序。
在使用NDK开发Android应用程序时,需要使用CMake来构建应用程序的Native部分。
因此,需要设置CMake的NDK路径,以便CMake能够正确地找到NDK中所需的头文件和库文件。
设置CMake的NDK路径有两种方法:方法一:在CMakeLists.txt文件中设置NDK路径在CMakeLists.txt文件中添加以下代码:```set(NDK_ROOT /path/to/ndk)set(CMAKE_SYSTEM_NAME Android)set(CMAKE_SYSTEM_VERSION 21)set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)set(CMAKE_ANDROID_NDK /path/to/ndk)set(CMAKE_ANDROID_STL_TYPE c++_static)```其中,/path/to/ndk需要替换为NDK的实际路径。
这种方法的优点是可以针对不同的项目设置不同的NDK路径,缺点是需要在每个CMakeLists.txt文件中都添加这些代码。
方法二:在环境变量中设置NDK路径在系统环境变量中添加ANDROID_NDK_HOME变量,并将其值设置为NDK的实际路径。
这种方法的优点是可以在任何项目中使用同一个NDK路径,缺点是需要手动设置环境变量。
总结:无论是哪种方法,都需要正确设置NDK路径,以便CMake能够正确地找到NDK中所需的头文件和库文件。
在使用CMake构建Android 应用程序时,需要注意以下几点:1. 确保NDK的版本和API级别与应用程序的目标版本兼容。
AndroidStudio⽤Cmake⽅式编译NDK代码(cmake配置.a库)1.cmake是什么?CMake是⼀个跨平台的安装()⼯具,可以⽤简单的语句来描述所有平台的安装(编译过程)。
他能够输出各种各样的makefile或者project⽂件,能测试所⽀持的C++特性,类似UNIX下的automake。
⾕歌从AndroidStudio2.2以上就添加了Cmake⽅式来编译NDK代码,并从NDK例⼦看出,默认编译的⽅式就是cmake⽅式。
2.⾕歌官⽅的⽤cmake⽅式编译NDK的教程⾕歌从AndroidStudio2.2以上就添加了Cmake⽅式来编译NDK代码,并从NDK例⼦看出,默认编译的⽅式就是cmake⽅式。
如果您希望向现有项⽬添加原⽣代码,请执⾏以下步骤:1. 并将其添加到您的 Android Studio 项⽬中。
如果您已经拥有原⽣代码或想要导⼊预构建的原⽣库,则可以跳过此步骤。
2. ,将您的原⽣源代码构建到库中。
如果导⼊和关联预构建库或平台库,您也需要此构建脚本。
如果您的现有原⽣库已经拥有CMakeLists.txt构建脚本或者使⽤ ndk-build 并包含构建脚本,则可以跳过此步骤。
3. 提供⼀个指向您的 CMake 或 ndk-build 脚本⽂件的路径,。
Gradle 使⽤构建脚本将源代码导⼊您的 Android Studio 项⽬并将原⽣库(SO ⽂件)封装到 APK 中。
配置完项⽬后,您可以使⽤从 Java 代码中访问您的原⽣函数。
要构建和运⾏应⽤,只需点击 Run 。
Gradle 会以依赖项的形式添加您的外部原⽣构建流程,⽤于编译、构建原⽣库并将其随 APK ⼀起封装。
创建新的原⽣源⽂件要在应⽤模块的主源代码集中创建⼀个包含新建原⽣源⽂件的cpp/⽬录,请按以下步骤操作:1. 从 IDE 的左侧打开 Project 窗格并从下拉菜单中选择 Project 视图。
2. 导航到您的模块 > src,右键点击 main ⽬录,然后选择 New > Directory。
AndroidStudio之NDK篇 由于⼯作内容的关系,对于NDK的⼯作涉及⽐较⼴(保密性,安全性),所以本章内容讲述⼀下NDK的基本使⽤过程。
⽹上也有很多这样的教程或者描述,但描述的并不完全 开发⼯具:Android Studio 2.1.2 NDK版本:android-ndk-r10e,⽀持64位so库的编译 JDK版本:1.8 64位 使⽤步骤如下: 第⼀步:NDK环境的搭建 ①jdk,Android SDK这些准备充分(只要能正常使⽤Android Studio的,这⼀条基本不⽤考虑) ②下载NDK,可以通过Android Studio的SDK Manager下载,也可以通过这个链接下载:,⾄于版本的话,根据⾃⼰电脑系统⾃⾏选择最新版本, 如果访问不了,需要使⽤FQ的话,可以下载天⾏VPN(有试⽤版,⼀天⼀个⼩时,关键是不要钱还能FQ),FQ⼯具下载链接: 第⼆步:新建⼀个Project,完成NDK的配置 ①在⼯程的local.properties⾥⾯添加NDK的路径代码:ndk.dir=C\:\\android-ndk-r10e ②在gradle.properties⾥⾯声明使⽤NDK的代码eDeprecatedNdk=true ③在app的build.gradle⾥⾯,添加NDK的编译信息(包括⽣成的so库名字,以及编译出来的各种平台版本)apply plugin: 'com.android.application'android {compileSdkVersion 23buildToolsVersion "24.0.0"defaultConfig {applicationId ".as_ndk_demo"minSdkVersion 11targetSdkVersion 23versionCode 1versionName "1.0"ndk{moduleName "MyTestJniLib"//⽣成的.so的名字abiFilters "armeabi","armeabi-v7a","x86"}}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}sourceSets {main {jniLibs.srcDirs = ['libs']}}}dependencies {compile fileTree(dir: 'libs', include: ['*.jar'])testCompile 'junit:junit:4.12'compile 'com.android.support:appcompat-v7:23.4.0'} 第三步:编辑native⽅法,⽣成.h头⽂件 ①编辑native⽅法package .as_ndk_demo.ndktest;/*** Created by ouyangshengduo on 2016/9/23.*/public class NdkJniUtils {static {System.loadLibrary("MyTestJniLib"); //defaultConfig.ndk.moduleName}public native String getCLanguageString();}View Code ②点击Build-->Make Project,⽣成class⽂件 ③找到class⽂件,在app->build->intermediates->classes->debug⽬录下: ④通过javah命令⽣成.h头⽂件,点击Android Studio底下菜单中的Terminal 依次敲⼊:cd app\build\intermediates\classes\debugjavah -jni .as_ndk_demo.ndktest.NdkJniUtils使⽤javah的时候,具体的包名按照实际情况来书写 没有什么错误的话,可以在debug⽬录下看到.h的头⽂件/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class edan_com_as_ndk_demo_ndktest_NdkJniUtils */#ifndef _Included_edan_com_as_ndk_demo_ndktest_NdkJniUtils#define _Included_edan_com_as_ndk_demo_ndktest_NdkJniUtils#ifdef __cplusplusextern"C" {#endif/** Class: edan_com_as_ndk_demo_ndktest_NdkJniUtils* Method: getCLanguageString* Signature: ()Ljava/lang/String;*/JNIEXPORT jstring JNICALL Java_edan_com_as_1ndk_1demo_ndktest_NdkJniUtils_getCLanguageString(JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif 第四步:根据⽣成.h头⽂件,以及新建的.c或者.cpp⽂件,⽣成.so库⽂件 ①在app->src->main⽬录下新建⼀个jni⽂件夹,⽤来存c/c++的头⽂件以及源⽂件,将刚刚⽣成.h头⽂件剪切到这⾥来,然后新建⼀个.c 或者.cpp⽂件#include "edan_com_as_ndk_demo_ndktest_NdkJniUtils.h"/** Class: com_example_edu_ndktest_NdkJniUtils* Method: getCLanguageString* Signature: ()Ljava/lang/String;*/JNIEXPORT jstring JNICALL Java_edan_com_as_1ndk_1demo_ndktest_NdkJniUtils_getCLanguageString(JNIEnv *env, jobject obj){return (*env)->NewStringUTF(env,"My name is Ouyangshengduo,Hi!");} ②点击Build->Make Project进⾏编译,⽣成.so库⽂件,路径:app->build->intermediates->ndk->debug->lib下: ③拷贝lib下的这些⽂件夹,到app->libs下: 第五步:通过MainActivity的TextView显⽰C⾥⾯的内容:package .as_ndk_demo;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.widget.TextView;import .as_ndk_demo.ndktest.NdkJniUtils;public class MainActivity extends AppCompatActivity {private TextView mTextView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.activity_main);mTextView = (TextView) findViewById(R.id.text);NdkJniUtils ndk_util = new NdkJniUtils();mTextView.setText(ndk_util.getCLanguageString());}} ⾄此,Android Studio 的NDK的基础篇讲述完了,期间遇到任何问题或者错误,将错误信息copy去google,基本都能解决,当然,也可以留⾔,知道的必将⾔⽆不尽。
详解Androidstudiondk配置cmake开发nativeCAndroid 2.2 以后的版本对NDK的⽀持已经⾮常好了。
最近把⼀个纯C的android项⽬,从eclipse ADT迁移到Android studio 上。
本⽂是参考官⽅⽂档(需要翻墙),经过各种尝试之后的总结。
Android studio整合NDK开发,有两种模式,⼀种是ndk build,⼀种是cmake,如果是新项⽬官⽅推荐cmake。
原来,ADT的时候只能⽤ndk build,这次切换IDE并没有选⽤ndk build,⽽是尝试了cmake感觉上配置更加简洁⽅便。
本⽂探讨⼀下⼏点:1. 迁移现有native C代码使⽤cmake,如果是新项⽬同理更加简单。
2. 项⽬是native activity就是没有java代码的纯native project。
3. 构建编译出多个so⽂件,并有依赖关系。
4. 使⽤不依赖IDE⽬录结构的代码⽬录。
5. 创建过程中的注意事项。
创建native项⽬,可以有两个选项。
第⼀个是创建的时候,选择带有C++ Support功能的。
第⼆个是对已有⼯程添加c/c++功能。
这⾥,⽆论是不是新项⽬,都推荐使⽤创建⼀个项⽬在添加c/c++功能,这样native code 就可以独⽴于项⽬放在任意⽬录。
创建⼀个没有native code⼯程,在根据CMakeLists.txt⽂件来添加NDK的⽀持。
File -> Link C++ Project with Gradle。
这样,我们的代码就可以独⽴于IDE的⽬录结构。
只要提供CMakeLists.txt⽂件即可。
⼀旦我们提供了CMakeLists.txt⽂件,Android studio就会根据这个⽂件为我们在⼯程下⾯⽣成⼀个cpp⽂件夹⽤来存放CMakeLists.txt⾥⾯配置的native代码⽂件。
下⾯我们来快速的介绍⼀下CMakeLists.txt基本功能的写法,能够应付通常的情况。
ndk 编译NDK是一种能够让开发者使用C/C++等语言编写Android应用程序的工具集。
NDK被广泛应用于需要高性能和底层硬件控制的应用,例如游戏、多媒体应用等。
NDK编译是将C/C++代码转换成Android应用程序的过程。
在NDK编译过程中,我们需要进行一系列配置和设置,方能使C/C++代码能在Android应用中正确运行。
本文将介绍NDK编译的流程、配置和注意事项。
一、NDK编译流程1、准备工作为了进行NDK编译,我们需要先下载NDK工具集以及安装好Android Studio。
然后,在Android Studio中安装好C++插件,以支持C/C++代码的开发。
2、创建项目在Android Studio中新建一个项目,然后选择“native C++”作为项目类型。
这样可以自动生成一些用于编写C/C++代码的文件和目录。
3、编写代码4、配置gradle文件我们需要在项目的gradle文件中指定编译选项和依赖项。
首先,在build.gradle中添加如下代码:此时,我们需要在CMakeLists.txt文件中指定编译选项和依赖项。
例如:```cppcmake_minimum_required(VERSION 3.4.1)target_link_libraries(native-lib# Android NDK librariesandroidlog)```5、进行编译最后,在Android Studio中点击“Sync Project with Gradle Files”按钮,然后再点击“Build”按钮,即可进行NDK编译。
下面是一些NDK编译的配置和注意事项。
1、指定C++标准和编译选项如果我们的C++代码中使用了某些C++11标准的特性,那么需要在gradle文件中指定C++标准。
例如:```cppexternalNativeBuild {cmake {cppFlags "-std=c++11"}}```我们也可以指定一些编译选项,例如“-O3”代表进行优化。
详解AndroidStudio3.0开发调试安卓NDK的C++代码本⽂介绍了AndroidStudio3.0开发调试安卓NDK的C++代码,分享给⼤家,具有如下:⼀、新建项⽬新建项⽬,没有发现Include C++ Support 选项。
因为印象中是有过该选项的,找了半天没找到。
后来⽆意间拖了下窗⼝⼤⼩,原来是被隐藏了,真特么坑。
新建⼀个测试项⽬,勾选Include C++ Support 选项,看看⼯程上有哪些不同。
1、gradle⾸先看gradle⽂件,android节点下添加:externalNativeBuild {cmake {path "CMakeLists.txt"}}defaultConfig节点下添加:externalNativeBuild {cmake {cppFlags "-std=c++14"}}2、CPP与Java节点同级多了⼀个cpp的节点,对应⽬录为src\main\cpp,与src\main\java同级,默认只有⼀个native-lib.cpp⽂件,没有.mk⽂件及其他,⽐较简单:#include <jni.h>#include <string>extern "C"JNIEXPORT jstringJNICALLJava_com_bigsing_myapplication_MainActivity_stringFromJNI(JNIEnv *env,jobject /* this */) {std::string hello = "Hello from C++";return env->NewStringUTF(hello.c_str());}3、CMakeLists.txt在app⽬录下多了⼀个CMakeLists.txt⽂件。
# For more information about using CMake with Android Studio, read the# documentation: https:///studio/projects/add-native-code.html# Sets the minimum version of CMake required to build the native library.cmake_minimum_required(VERSION 3.4.1)# Creates and names a library, sets it as either STATIC# or SHARED, and provides the relative paths to its source code.# You can define multiple libraries, and CMake builds them for you.# Gradle automatically packages shared libraries with your APK.add_library( # Sets the name of the library.native-lib# Sets the library as a shared library.SHARED# Provides a relative path to your source file(s).src/main/cpp/native-lib.cpp )# 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.target_link_libraries( # Specifies the target library.native-lib# Links the target library to the log library# included in the NDK.${log-lib} )其中native-lib为最终⽣成的SO的名称(libnative-lib.so),默认CPU为armeabi-v7a默认的⼯程属性不⽤配置,debugger默认为auto会⾃动适配,直接在cpp⾥下断点,调试⽅式运⾏App,会⾃动断下,变量数值均能在调试状态下看到。
cmake + ndk 编译CMake是一个跨平台的开源工具,用于管理软件构建过程。
NDK (Native Development Kit)是一个允许开发人员使用C和C++编写Android应用程序的工具集。
结合CMake和NDK可以实现在Android平台上使用CMake进行项目的构建和编译。
在使用CMake和NDK进行编译时,首先需要编写CMakeLists.txt文件来描述项目的构建过程。
这个文件中包括了项目的源文件、头文件、依赖库等信息。
然后,通过命令行或者集成开发环境(如Android Studio)的界面来配置CMake和NDK的路径,并执行CMake命令来生成相应的构建系统(如Makefile)。
接着使用NDK的工具链来编译生成的构建系统,生成最终的可执行文件或库文件。
在编译过程中,需要考虑NDK支持的平台架构,如armeabi-v7a、arm64-v8a、x86等,以及对应的ABI(Application Binary Interface)。
在CMakeLists.txt中需要配置好相应的平台架构和ABI信息,以确保生成的可执行文件或库文件能够在目标设备上正确运行。
此外,还需要考虑项目中可能使用的第三方库或模块,需要在CMakeLists.txt中进行相应的配置和链接。
对于涉及到的CMake语法和NDK相关的配置选项,需要仔细查阅官方文档或相关的教程资料,以确保编译过程能够顺利进行。
总的来说,使用CMake和NDK进行编译需要充分了解项目的结构和依赖关系,熟悉CMake的语法和NDK的相关配置,以及对目标平台的要求,才能够顺利完成项目的构建和编译。
希望这些信息能够帮助你更好地理解CMake和NDK的编译过程。
androidstudioCC++jni编写以及调试⽅法原⽂路径:⽬录开发环境IDE: android studio 1.1.0android NDK :R10android SDK : android -19编写hello_jni程序建⽴⼀个空的activity项⽬⽬录如图:进⼊下图标红的⽂件 MainActivity⽂件中添加如下代码在MainActivity类内static {System.loadLibrary("hello_jni");}public native String getstringfromC();打开终端android studio已经提供了终端如图:⾸先进⼊java⽬录执⾏命令:javah -d ../jni com.example.root.ndk_sample.MainActivitycom.example.root.ndk_sample.MainActivity是native函数的所在的包名和类名,中间使⽤“.”号分开。
这时候就会在java⽬录下⾯出现jni⽬录如图:添加*.c⽂件在jni⽬录中如图:(⽂件名字为hello_jni.c)备注:红⾊⽅框内的只是为了⽅便演⽰调试使⽤,没有额外的功能。
编写Android.mk和Application.mk 放在jni⽬录下⾯。
结构如图:Android.mk⽂件的内容如下:LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE :=hello_jniLOCAL_SRC_FILES := hello_jni.cinclude $(BUILD_SHARED_LIBRARY)Application.mk ⽂件内容为:APP_ABI := allAPP_OPIM :=debug配置ndk的⽬录配置⽂件为图中标红的地⽅。
在最后⼀⾏添加如下内容:ndk.dir=配置在红⾊的⽅框内的⽂件夹下的红条出添加如下配置:ndk{moduleName"hello_jni"}在下图中在红⾊的⽅框内的⽂件夹下添加蓝⾊的内容。
Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库Note:这篇文章是基于Android Studio 2.3版本的,对于很多功能2.2开始就已经支持,但是存在一些bug,例如CMake中的add_custom_command用echo打印调试信息再2.2版本中无法查看,直到2.3才修复。
其他的更新暂时没有体会。
当然在进行下面的步骤前,需要先在Android Studio中的SDK Manager安装好LLDB、CMake还有NDK。
从没有勾选C++ Support的空项目开始在新建项目的时候,是可以勾选添加C++ Support选项的,它会自动产生CMakeLists.txt以及在build.gradle中添加对CMakeLists.txt 的引用。
但是为了理解Android Studio中gradle结合CMake 是如何构建NDK项目的,我们还是从零开始。
当最终项目完成之后,目录树应该是下面的样子(去除了与构建结构无直接关联的目录及文件,带星号的是我们即将添加的部分):. ├── app│ ├── build.gradle│ ├── CMakeLists.txt│ └── src│ └── main│ ├── AndroidManifest.xml│ ├──*cpp│ │ ├── native-math.cpp│ │ └── native-opencv.cpp│ └── java│ └── com/huang/opencvtest │ └── MainActivity.java ├──*distribution│ ├── inclu de│ └── libs├──*mathlib│ ├── build.gradle│ ├── CMakeLists.txt│ └── src│ └── main│ ├── AndroidManifest.xml│ └── cpp│ ├── add.cpp│ └── add.h├──*openCVLibrary320│ ├── build.gradle│ └── src│ └── main│ ├── AndroidManifest.xml│ └── java/org/opencv├── gradle.properties├── local.properties├── build.gradle└── settings.gradle我们要添加自己定义的一个简单的数学C++库,以及OpenCV4Android预编译库。
首先将视图切换到Project,今后操作一直在Project视图中进行。
构建的结构顶级的build.gradle在我们一般的使用下并不需要去设置,顶级的构建文件中我们仅仅需要改settings.gradle。
settings.gradle 描述了这一个项目在构建的时候需要包含哪一些模块。
最开始只有app模块,因此里面只有一句话include ':app'。
系统在构建的时候,就会根据这句话,去寻找模块名为app的目录下面的build.gradle文件,并将其纳入构建结构树中。
最终形成一课完整的构建结构树,将所有的部分联系在一起,编译成最终的Android应用。
每个模块中的我们称之为局部build.gradle,在这里面,定义了该模块为application或者library或其他,一般我们考虑这两个选项。
这里面定义了许多构建这个模块时要用到的参数,在后续我们添加NDK支持的时候需要往里面添加一些参数,其中对CMakeLists.txt 的路径就是在这里指定的。
添加自定义的C++库mathlib创建源文件我的项目名称为OpenCVTest,所以右键这个项目点击New->Module,然后选Android Library,输入库的名称MathLib,然后Finish,系统就会生成对应的模块,并构建好初始的目录树。
系统将库命名为MathLib,但是目录树中还是小写的mathlib。
这个时候系统会自动在顶级settings.gradle添加对于这个新模块的include语句。
并且在模块目录下构建好了初始的build.gradle。
现在我们开始创建自己的C++库,首先右键mathlib目录下的src/main,然后选择New->Directory,输入cpp并确定。
这个目录就是我们要创建的库的源文件的位置。
右键add,点击New->C/C++ Source File,输入add.cpp,并选中Create an associated header。
在.cpp文件中定义好一个简单的加法函数,并在.h 文件中添加好对应声明。
库本身的定义就到此为止。
将源文件关联到构建系统中我们用CMake来构建C++库,然后CMake又要和gradle结合,在Android Studio里面协作管理C++和Java的代码。
我们在模块mathlib的根目录下创建一个名为CMakeLists.txt的文件,写入cmake_minimum_required(VERSION 3.4.1)add_library(add SHAREDsrc/main/cpp/add.cpp)set(distribution_DIR${CMAKE_CURRENT_SOURCE_DIR}/../distribution)set_target_properties(add PROPERTIESLIBRARY_OUTPUT_DIRECTORY${distribution_DIR}/libs/${ANDROID_ABI})target_include_directories(addPUBLIC${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp)#add_custom_command(TARGET add POST_BUILD# COMMAND ${CMAKE_COMMAND} -E# copy${distribution_DIR}/libs/${ANDROID_ABI}/libadd.so#${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libadd.so# COMMAND ${CMAKE_COMMAND} -E# echo "output libadd.so to ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"# COMMENT "Copying add to output directory")上面的CMake指令就是将源文件添加,并构件为一个Library即库,然后将创建后的libadd.so复制到项目根目录的distribution中,并最终被主模块app引用。
Note:在这里需要注意的是,target_include_directories,它对创建的库设置include路径,针对目标来设置,可以避免与其他库的冲突,并且此时对自定义的库设置好了此路径后,后续导入这个库就不需要再次设置了。
但对于预构建的库,就需要设置,稍后会有详细讲解。
Note:这里有个问题。
被注释的部分,是将libadd.so复制到${CMAKE_LIBRARY_OUTPUT_DIRECTORY}中,被复制到这个目录的.so文件会被自动添加到.apk文件中去。
但是在稍后为OpenCV的库添加的android.sourceSets.jniLibs.srcDirs会让这个特性失效,因此这里还是注释掉,稍后统一为库设置路径,让系统复制到.apk 文件中。
这个时候,CMakeLists.txt还是独立的,并没有与Android Studio的构建系统联系起来。
接下来我们在模块mathlib的build.gradle中的defaultConfig{}中添加如下语句:externalNativeBuild {cmake {arguments'-DANDROID_PLATFORM=android-19','-DANDROID_TOOLCHAIN=clang','-DANDROID_STL=gnustl_static'targets 'add'}}这里arguments是编译参数,而targets则是相比于add_subdirectory更高权限的方法。
一般来说可以把它删去,即默认构建所有目标。
Note:之所以在defaultConfig{}中设置,是因为在Android中,有许多不同的所谓风味,即免费版和付费版等,defaultConfig{}的设置可以在不同风味中覆盖,即它是缺省设置。
然后在android{}最后添加如下语句,将CMakeLists.txt关联起来。
externalNativeBuild { cmake {path 'CMakeLists.txt'}}这样,我们的自定义C++库就添加完成了。
在主模块中使用自定义C++库C++库已经创建好了,接下来就要在主模块中使用它了。
为了使用自定义C++库,我们需要一个中间人,它从Android本身的Java程序中获取请求,然后使用我们的C++库中的函数计算得到结果,并将数据传回Android本身的Java程序中。
扮演这个角色的,也是一个C++源文件。
我们在主模块app的根目录下创建一个CMakeLists.txt文件,再在src/main下创建一个目录cpp,其中再创建native-math.cpp。
CMakeLists.txt用来将主模块中包括native-math.cpp在内的主模块中的库作为一个顶级库。
我们先将native-math.cpp空着,先写CMakeLists.txt。
在CMakeLists.txt中写入cmake_minimum_required(VERSION 3.4.1)set(distribution_DIR${CMAKE_SOURCE_DIR}/../distribution)# set add libadd_library(lib_add SHARED IMPORTED)set_target_properties(lib_add PROPERTIES IMPORTED_LOCATION${distribution_DIR}/libs/${ANDROID_ABI}/libadd.so) include_directories(lib_add${distribution_DIR}/include)add_library(native-math SHAREDsrc/main/cpp/native-math.cpp)set_target_properties(native-math PROPERTIESLIBRARY_OUTPUT_DIRECTORY${distribution_DIR}/libs/${ANDROID_ABI})target_link_libraries(native-mathandroidlib_addlog)我们将之前创建的libadd.so使用导入,指定其路径,并在这里命名为lib_add。