Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库.docx
- 文档编号:3033020
- 上传时间:2022-11-17
- 格式:DOCX
- 页数:9
- 大小:21.18KB
Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库.docx
《Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库.docx》由会员分享,可在线阅读,更多相关《Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库.docx(9页珍藏版)》请在冰豆网上搜索。
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
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库 Studio 通过 CMake 使用 NDK 编译 自定义 添加 预编