前言
在做项目过程中需要使用Assimp这个3D模型读取库来读取obj格式的模型,因为项目是基于Android平台,采用NDK开发,所以就打算编译Assimp库并生成.so文件。本文使用Assimp-v.5.0.0.rc1(https://github.com/assimp/assimp/releases/tag/v.5.0.0.rc1),此版本已经支持导入blendshape。
步骤
- 下载Android Studio(主要是利用其带的SDK以及CMAKE)
- 下载并安装Python,注意安装过程中需要勾选添加到环境变量,我安装的是Python3.5,可通过命令行键入python检查Python是否已经配置好
- 下载NDK, 本文使用r14b 64位 (https://github.com/assimp/assimp/wiki/Android-compilation-on-Windows-%28Quick-overview%29)
- 下载并解压Assimp-v.5.0.0.rc1
- 在NDK目录下的build/tools下,通过以下命令生成编译时所需要的交叉编译ToolChain,注意:
a) –arch 参数指定不同的架构:arm64-v8a对应arm64,armeabi-v7a对应arm等等
b) 这里要指定使用哪种stl,本文使用gnustl,如果不指定的话,会报一些中的函数的错误。“xx”is not a member of ‘std’ 等等。后续在使用编译出来的Assimp库时,Application.mk中要配置同样的C库。
c) –api 选择了9。
- 将生成的android-toolchain-24-llvm-armeabi_v7a整个文件夹复制到Assimp-v.5.0.0.rc1的同级目录下。
- 在Assimp-v.5.0.0.rc1的同级目录下,新建一个build_assimp.bat,用于编译生成.so文件,文件内容如下;
1. @echo off
2. cls
3.
4. REM *NOTE* Change these based on
5. SET ASSIMP_DIR=assimp-v.5.0.0.rc1
6. SET OUTPUT_DIR=aassimp-build-armeabi-v7a
7. SET ANDROID_PATH=C:/Users/chenchengju/AppData/Local/Android/Sdk
8. SET NDK_PATH=G:/software/android-ndk-r16b
9. SET NDK_TOOLCHAIN=%~dp0android-toolchain-24-llvm-armeabi-v7a
10. SET CMAKE_TOOLCHAIN=%NDK_PATH%/build/cmake/android.toolchain.cmake
11. SET CMAKE_PATH=%ANDROID_PATH%/cmake/3.6.4111459
12.
13. REM *NOTE* Careful if you don't want rm -rf, I use it for testing purposes.
14.
15. mkdir %OUTPUT_DIR%
16.
17. REM pushd doesn't seem to work ):<
18. cd %OUTPUT_DIR%
19.
20. if not defined ORIGPATH set ORIGPATH=%PATH%
21. SET PATH=%CMAKE_PATH%\bin;%ANDROID_PATH%\tools;%ANDROID_PATH%\platform-tools;%ORIGPATH%
22.
23. cmake ^
24. -GNinja ^
25. -DCMAKE_TOOLCHAIN_FILE=%CMAKE_TOOLCHAIN% ^
26. -DASSIMP_ANDROID_JNIIOSYSTEM=ON ^
27. -DANDROID_NDK=%NDK_PATH% ^
28. -DCMAKE_MAKE_PROGRAM=%CMAKE_PATH%\bin\ninja.exe ^
29. -DCMAKE_BUILD_TYPE=Release ^
30. -DANDROID_ABI="armeabi-v7a" ^
31. -DANDROID_NATIVE_API_LEVEL=9 ^
32. -DANDROID_FORCE_ARM_BUILD=TRUE ^
33. -DCMAKE_INSTALL_PREFIX=install ^
34. -DANDROID_STL=gnustl_static ^
35. -DCMAKE_CXX_FLAGS=-Wno-c++11-narrowing ^
36. -DANDROID_TOOLCHAIN=clang ^
37.
38. -DASSIMP_BUILD_TESTS=OFF ^
39.
40. ../%ASSIMP_DIR%
41.
42. cmake --build .
43.
44. cd ..
45.
46. pause
注意一下情况:
1 ASSIMP_DIR是第4步解压的Assimp库所在的文件夹
2 OUTPUT_DIR是保存编译生成文件的文件夹
3 ANDROID_PATH跟NDK_PATH需要修改为自己机器上的路径
4 NDK_TOOLCHAIN是保存工具链的文件夹
5 下面的-DANDROID_ABI和-DANDROID_NATIVE_API_LEVEL参数需要改成所需的值。
6 DANDROID_STL=gnustl_static ^ ,需要与之前生成工具链选择的c库一致。
7 然后双击运行.bat文件,如果没有报错,就能在< OUTPUT_DIR>/code/下找到libassimp.so文件,想要生成其他架构下的.so文件,只需修改生成toolchain和.bat文件参数(-DANDROID_ABI=“armeabi-v7a” ^ ),再执行即可。
8 如果想生成静态库.a,需要打开assimp/CMakeList.txt,将BUILD_SHARED_LIBS关掉,并增加下面三行,然后重复上面步骤。
去符号
使用ndk 下面的 工具 使用以下命令去符号
/data/Android/android-ndk-r14b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin$ ./arm-linux-androideabi-strip -g --strip-debug --strip-unneeded /data/work/assimp_4/libassimp.a
一些错误的记录:
**解决方法:**去assimp/code/CMakeList.txt中将IrrXML相关的代码注释掉,然后Assimp支持很多格式,但是在实际使用中,除非本身就是一个3D模型查看器或者转换器,否则最终可能就固定使用那么2,3个格式。显然编译时把其他的格式编进去是无用且浪费的,徒增库的大小,并且一些模型的导入用到了IrrXML相关的代码,比如上图中ColladaParser。剔除不需要的模型格式的方法是:将对应的导入的代码注释掉,并且添加一个宏。
- 有些std::xxx在assimp自己的文件中有定义,会发生冲突,这种情况根据报错进行对应的修改。
- atof not find,头文件没包含,include一下
Assimp定制化:
assimp功能强大,可以加载和导出多种3D模型,附加多种效果优化功能,但在需求中有很多功能使用不到,所以可以在编译时直接剔除已达到减小静态库的目的,需要注意的是:除了需要在编译时通过宏控制编译之外还需要直接在code/CMakeLists.txt文件中将相应的源码注释掉。
- 在编译时只保留obj模块,其余模块都不需要编译,可以直接通过cmake-gui工具直接取消对应模块的勾选来达到排除对应模块编译的效果。
- 因为我们只使用assimp的模型加载功能,所以在assimp项目code/CMakeLists.txt文件中将*Exporter.cpp源码【如:AssxmlExporter.cpp】列表注释以达到将该源码剔除编译列表的目的。
- 根据assimp项目code/PostStepRegistry.cpp文件,查看使用到的每个process的作用,决定哪些process是可以去掉的,若要去掉对应的process,可在项目根目录下的CMakeLists.txt文件中定义对应的宏,如:
add_definitions(-DASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS),然后在code/CMakeLists.txt文件中将该宏中对应的源码从列表中注释掉。同理可将如下process也一起去除:
- ASSIMP_BUILD_NO_SPLITBYBONECOUNT_PROCESS
- ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
- ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS
- ASSIMP_BUILD_NO_DEBONE_PROCESS
- ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
- ASSIMP_BUILD_NO_FLIPUVS_PROCESS
- ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS
- SSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
- ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS
- ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS
- ASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS
- ASSIMP_BUILD_NO_FINDINSTANCES_PROCESS
结语
assimp库是有内存泄漏的!!!
assimp库是有内存泄漏的!!!
assimp库是有内存泄漏的!!!
重要的事情说三遍。
谢谢!