Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库.docx

上传人:b****6 文档编号:3033020 上传时间:2022-11-17 格式:DOCX 页数:9 大小:21.18KB
下载 相关 举报
Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库.docx_第1页
第1页 / 共9页
Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库.docx_第2页
第2页 / 共9页
Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库.docx_第3页
第3页 / 共9页
Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库.docx_第4页
第4页 / 共9页
Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库.docx_第5页
第5页 / 共9页
点击查看更多>>
下载资源
资源描述

Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库.docx

《Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库.docx》由会员分享,可在线阅读,更多相关《Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库.docx(9页珍藏版)》请在冰豆网上搜索。

Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库.docx

AndroidStudio中通过CMake使用NDK并编译自定义库和添加预编译库

AndroidStudio中通过CMake使用NDK并编译自定义库和添加预编译库

Note:

这篇文章是基于AndroidStudio2.3版本的,对于很多功能2.2开始就已经支持,但是存在一些bug,例如CMake中的add_custom_command用echo打印调试信息再2.2版本中无法查看,直到2.3才修复。

其他的更新暂时没有体会。

当然在进行下面的步骤前,需要先在AndroidStudio中的SDKManager安装好LLDB、CMake还有NDK。

从没有勾选C++Support的空项目开始在新建项目的时候,是可以勾选添加C++Support选项的,它会自动产生CMakeLists.txt以及在build.gradle中添加对CMakeLists.txt的引用。

但是为了理解AndroidStudio中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

│├──include

│└──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,然后选AndroidLibrary,输入库的名称MathLib,然后Finish,系统就会生成对应的模块,并构建好初始的目录树。

系统将库命名为MathLib,但是目录树中还是小写的mathlib。

这个时候系统会自动在顶级settings.gradle添加对于这个新模块的include语句。

并且在模块目录下构建好了初始的build.gradle。

现在我们开始创建自己的C++库,首先右键mathlib目录下的src/main,然后选择New->Directory,输入cpp并确定。

这个目录就是我们要创建的库的源文件的位置。

右键add,点击New->C/C++SourceFile,输入add.cpp,并选中Createanassociatedheader。

在.cpp文件中定义好一个简单的加法函数,并在.h文件中添加好对应声明。

库本身的定义就到此为止。

将源文件关联到构建系统中我们用CMake来构建C++库,然后CMake又要和gradle结合,在AndroidStudio里面协作管理C++和Java的代码。

我们在模块mathlib的根目录下创建一个名为CMakeLists.txt的文件,写入cmake_minimum_required(VERSION3.4.1)

add_library(addSHARED

src/main/cpp/add.cpp)

set(distribution_DIR${CMAKE_CURRENT_SOURCE_DIR}/../distribution)

set_target_properties(addPROPERTIES

LIBRARY_OUTPUT_DIRECTORY

${distribution_DIR}/libs/${ANDROID_ABI})

target_include_directories(add

PUBLIC${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp)

#add_custom_command(TARGETaddPOST_BUILD

#COMMAND${CMAKE_COMMAND}-E

#copy${distribution_DIR}/libs/${ANDROID_ABI}/libadd.so

#${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libadd.so

#COMMAND${CMAKE_COMMAND}-E

#echo"outputlibadd.soto${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"

#COMMENT"Copyingaddtooutputdirectory")

上面的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还是独立的,并没有与AndroidStudio的构建系统联系起来。

接下来我们在模块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(VERSION3.4.1)

set(distribution_DIR${CMAKE_SOURCE_DIR}/../distribution)

#setaddlib

add_library(lib_addSHAREDIMPORTED)

set_target_properties(lib_addPROPERTIESIMPORTED_LOCATION

${distribution_DIR}/libs/${ANDROID_ABI}/libadd.so)

include_directories(lib_add

${distribution_DIR}/include)

add_library(native-mathSHARED

src/main/cpp/native-math.cpp)

set_target_properties(native-mathPROPERTIES

LIBRARY_OUTPUT_DIRECTORY${distribution_DIR}/libs/${ANDROID_ABI})

target_link_libraries(native-math

android

lib_add

log)

我们将之前创建的libadd.so使用导入,指定其路径,并在这里命名为lib_add。

然后使用target_link_libraries将包括默认的android在内的lib_add链接到native-math中。

在模块app的局部build.gradle中,像之前一样添加好对应的语句:

defaultConfig{}中:

externalNativeBuild{

cmake

arguments'-DANDROID_PLATFORM=android-19',

'-DANDROID_TOOLCHAIN=clang','-DANDRO

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1