C++写了一个基于CGAL库的算法,VS平台的编译很简单,下载boost并DOS编译,下载CGAL使用cmake-gui编译,最后将得到库链接到自己的项目就行,但用于Android,难度瞬间增加。
初学ndk,就分配了巨麻烦的对新手十分不友好的任务。主要涉及到以下步骤
1.编译CGAL源码,得到cgal的.a静态库文件,包含其依赖:gmp库,boost库,mpfr库。
2.编写jni
3.编写cmake脚本,编译自己写的代码,并链接静态库,得到动态库
4.,调用动态库,java代码调用so的实现,打包成aar,方便别的Android项目使用。
我可能用了最最朴实的方法,看了很多的教程。但最后我的实现没有用到Android.mk文件,没有用到Android studio的link c++ source,没有用AS去调用NDK(自己手动调用的ndk工具链),也没有swig。
1编译:
准备工作有,linux系统,linux系统下载解压ndk,下载解压源码,ndk配置环境变量,下载g++,gcc编译器。
首先需要获得交叉工具链,ndk里面有脚本,可以输入自己的配置,指定api版本,(我用的21),指定cpu,(我用的androideabi-va7,这个是32位,64位选用arm64-v8a);
得到工具链以后,在linux系统里面,cd 进入源码目录,首先编译gmp和mpfr,使用./configure命令编译,默认就是linux的,android是无法使用的,输入命令得到android可用的.a
2.编写jni
3.编写Cmakelists
有了库,这个就简单多了。关键代码就5句。需要复杂目录结构的,自行学习cmake。
project(CGALhellworld)#项目名
cmake_minimum_required(VERSION 3.1)#所需版本,这两句加着就行
include_directories(./3rdParty/windows/include)//添加头文件目录
aux_source_directory(./AreaCaculate Allcpp )//将整个文件夹的cpp定义成变量 Allcpp
link_directories(./3rdParty/android/lib/32) //添加库目录
#生成库(
库名
动态库,静态库是STATIC
放入cpp,使用Allcpp,直接添加整个文件的cpp
)
add_library(
AreaCaculate
SHARED
${Allcpp})
#cmake的逻辑似乎是栈,先生成库,然后才链接。
#链接顺序也是,mpfr是依赖gmp的,得先写link mpfr,然后link gmp。顺序错了库没法使用,找不到gmp实现
target_link_libraries(AreaCaculate libCGAL.a)
target_link_libraries(AreaCaculate libCGAL_Core.a)
target_link_libraries(AreaCaculate libboost_atomic.a)
target_link_libraries(AreaCaculate libboost_system.a)
target_link_libraries(AreaCaculate libboost_thread.a)
target_link_libraries(AreaCaculate libmpfr.a)
target_link_libraries(AreaCaculate libgmp.a)
3.编写jni,
先写好java代码,使得方法能和c++能够匹配对接的上,百度教程java生成jni,可以得到头文件,
将2步得到的so文件放在jnilibs文件夹里的armeabi-v7a文件夹里(都是手动新建的),android里配置一下库路径。
编写头文件的具体实现,java里loadlibrary方法调用so,