Windows环境下编译Assimp库生成Android可用的.so文件
来源:互联网 发布:法文翻译软件 编辑:程序博客网 时间:2024/06/07 02:39
Windows环境下编译Assimp库生成Android可用的.so文件
前言
在做项目过程中需要使用Assimp这个3D模型读取库来读取obj格式的模型,因为项目是基于Android平台,采用NDK开发,所以就打算编译Assimp库并生成.so文件,由此掀开了一段痛苦的编译之旅。在真机测试可用的前提下,记录一下整个过程以及遇到的坑和解决办法。
步骤
1.下载并安装好最新版的Android Studio,在写这篇博文的时候,最新版是2.3.3。
2.下载并安装Python,注意安装过程中需要勾选添加到环境变量,我安装的是Python3.5,可通过命令行键入python检查Python是否已经配置好:
如果出现类似上图的结果就是成功,否则把Python安装目录添加到环境变量Path中。
3.打开Android Studio,在File->Settings->Appearance & Behavior->System Settings->Android SDK下,点击SDK Tools便签,勾选如下图红框所示的选项并点击Apply按钮进行安装:
安装成功后,CMake和NDK的位置就位于SDK目录下的cmake文件夹和ndk-bundle文件夹:
具体文件路径根据SDK安装路径而定,在后续的步骤中需要到CMake和NDK,所以必须确定好这两个工具的位置。
4.上面完成了编译前的准备,接下来下载Assimp,我所使用的版本是4.0.1,将压缩包内容解压到一个目标文件夹中,我这里是新建了一个assimp文件夹,注意解压后的文件夹内应该直接包含Assimp库的内容:
5.在目标文件夹(我的是第4步所创建的assimp文件夹)下编写一个make_standalone_toolchain.bat文件,用于创建编译所需的工具链,bat文件内容如下:
python <Path to your sdk>/ndk-bundle/build/tools/make_standalone_toolchain.py --arch=arm64 --stl=libc++ --api=24 --install-dir=<path to store toolchain>
以我的环境为例,我的SDK路径是H:/Android/sdk,并将工具链保存在assimp的android-toolchain-24-llvm-arm64v8a目录下,所以我的bat脚本内容就是:
python H:/Android/sdk/ndk-bundle/build/tools/make_standalone_toolchain.py --arch=arm64 --stl=libc++ --api=24 --install-dir=android-toolchain-24-llvm-arm64v8a
上面是以arm64-v8a架构为例,对于其他六种架构(armeabi,armeabi-v7a,mips,mips64,x86,x86_64),需要修改–arch参数,该参数选值见下表:
bat脚本里的–api参数需要改成自己所需的Android API,保存后双击bat文件执行,会在参数install-dir所对应的文件夹生成工具链,下图是我的运行结果:
不同的架构生成的工具链内容不同,可以在< Path to SDK>/ndk-bundle/toolchains文件夹下查看。
6.同样在目标文件夹下(我的是第4步创建的Assimp文件夹)新建一个build_assimp.bat文件,用于编译生成.so文件,文件内容如下:
@echo offclsREM *NOTE* Change these based on SET ASSIMP_DIR=assimp-4.0.1SET OUTPUT_DIR=assimp-build-arm64v8aSET ANDROID_PATH=H:\Android\sdkSET NDK_PATH=H:\Android\sdk\ndk-bundleSET NDK_TOOLCHAIN=%~dp0android-toolchain-24-llvm-arm64v8aSET CMAKE_TOOLCHAIN=%NDK_PATH%\build\cmake\android.toolchain.cmakeSET CMAKE_PATH=%ANDROID_PATH%\cmake\3.6.4111459REM *NOTE* Careful if you don't want rm -rf, I use it for testing purposes.rm -rf %OUTPUT_DIR%mkdir %OUTPUT_DIR%REM pushd doesn't seem to work ):<cd %OUTPUT_DIR%if not defined ORIGPATH set ORIGPATH=%PATH%SET PATH=%CMAKE_PATH%\bin;%ANDROID_PATH%\tools;%ANDROID_PATH%\platform-tools;%ORIGPATH%cmake ^ -GNinja ^ -DCMAKE_TOOLCHAIN_FILE=%CMAKE_TOOLCHAIN% ^ -DASSIMP_ANDROID_JNIIOSYSTEM=ON ^ -DANDROID_NDK=%NDK_PATH% ^ -DCMAKE_MAKE_PROGRAM=%CMAKE_PATH%\bin\ninja.exe ^ -DCMAKE_BUILD_TYPE=Release ^ -DANDROID_ABI="arm64-v8a" ^ -DANDROID_NATIVE_API_LEVEL=24 ^ -DANDROID_FORCE_ARM_BUILD=TRUE ^ -DCMAKE_INSTALL_PREFIX=install ^ -DANDROID_STL=c++_shared ^ -DCMAKE_CXX_FLAGS=-Wno-c++11-narrowing ^ -DANDROID_TOOLCHAIN=clang ^ -DASSIMP_BUILD_TESTS=OFF ^ ../%ASSIMP_DIR%cmake --build .cd ..pause
其中ASSIMP_DIR是第4步解压的Assimp库所在的文件夹,OUTPUT_DIR是保存编译生成文件的文件夹,ANDROID_PATH跟NDK_PATH需要修改为自己机器上的路径,NDK_TOOLCHAIN是第5步保存工具链的文件夹,下面的-DANDROID_ABI和-DANDROID_NATIVE_API_LEVEL参数需要改成所需的值,参照这里的说明。
保存后,双击build_assimp.bat文件执行。
7.如果没有报错,就能在< OUTPUT_DIR>/code/下找到libassimp.so文件,想要生成其他架构下的.so文件,只需修改第5,6步中bat文件参数,再执行即可。
问题&解决方法
问题1:
CMake Error at xxx/android.toolchain.cmake:1622 (enable_language): Language 'C' is currently being enabled. Recursive call not allowed.
出现这个错误,一般是因为使用了taka-no-me所提供的android.toolchain.cmake文件,(注意,上面的步骤并没有使用这个文件,而是使用了NDK中的android.toolchain.cmake文件,见build_assimp.bat文件中的CMAKE_TOOLCHAIN参数)。
解决方法:
在taka-no-me提供的android.toolchain.cmake文件中,注释掉下图所示的几行:
个人建议还是使用NDK中的android.toolchain.cmake文件。
问题2:
code/D3MFImporter.cpp:230:29: error: invalid operands to binary expression ('float (*)(const char *, const char *)' and 'nullptr_t') vertex.z = ai_strtof>(xmlReader->getAttributeValue(D3MF::XmlTag::z.c_str()), nullptr);
这个bug很让我无语,这个错误是Assimp库中D3MFImporter.cpp源文件有错,该文件位于< Path to Assimp>/code文件夹下,出错位置为:
解决方法:
就是多了一个>符号,删掉就行。看Assimp的提交,这个bug应该是早已经被修复了,但是不知道为什么下载下来的文件中还存在这个错误。
问题3:
code/D3MFOpcPackage.cpp:221:16: error: use of undeclared identifier 'malloc' m_Buffer = malloc(m_Size); ^code/D3MFOpcPackage.cpp:225:5: error: use of undeclared identifier 'free' free(m_Buffer); ^2 errors generated.
解决方法:
这个问题同样是Assimp库源文件的bug,在< Path to Assimp>/code文件夹下找到并打开D3MFOpcPackage.h文件,在开头添加#include < stdlib.h >:
问题4:
'to_string' is not a member of 'std'error: '::atof' has not been declared
我使用其他方法编译Assimp库会出现上面两个错误,不知道怎么解决,改用上文所示的方法则没有这两个错误产生。
总结
通过这一次编译的过程,对于NDK开发和C++程序的编译有了更深刻的理解,有一些问题可以直接通过报错发现的,比如需要在build_assimp.bat中设置-DCMAKE_CXX_FLAGS=-Wno-c++11-narrowing,不然会报错,错误是提醒我们需要设置该值。其他问题则是通过各种谷歌搜索查找解决方式,希望我的一点经验能帮助到其他想在Android中使用Assimp库的人。
参考链接
Android NDK build fails. #1233
- Windows环境下编译Assimp库生成Android可用的.so文件
- windows android studio环境下.so文件的配置
- 在Ubuntu下编译Assimp库
- Windows下编译使用Android NDK,调用SO文件
- ndk编译android可用的libjpeg.so
- Linux下gcc编译生成动态链接库*.so文件
- 在Windows下使用MinGW静态编译Assimp
- 从Android源码编译生成的so文件查找源码
- windows环境下svn不能上传.so文件的问题
- windows 下 ffmpeg2.6.1 编译so文件
- 编译Speex生成so库文件(android-speex)
- 在android源码下编译生成.so
- Android--ndk编译生成.so文件
- Android Studio jni编译生成so文件
- android studio 编译C生成.so文件
- android studio编译c生成.so文件
- android studio 编译C生成.so文件
- android ndk开发编译生成so文件
- Jquery Grid表格插件 设置指定行/每行 颜色
- Mybatis 小总结
- kotlin集合操作符——顺序操作符
- Python-day14
- 微信支付接入遇到的问题
- Windows环境下编译Assimp库生成Android可用的.so文件
- spring boot jpa配置
- jQuery实现的简单鼠标拖拽功能
- java中的线程安全
- 关于iOS11下关于UIViewController属性弃用导致含有ScrollView功能的控件出现问题的解决方案
- 利用@media screen实现网页布局的自适应
- Zxing生成二维码 条形码
- 重写BaseAdapter后getView的模版
- Oracle格式模型(Format Models)