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 /ndk-bundle/build/tools/make_standalone_toolchain.py --arch=arm64 --stl=libc++ --api=24 --install-dir=

以我的环境为例,我的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参数,该参数选值见下表:

工具链

mips64 编译器

–arch=mips64

mips GCC 4.8 编译器

–arch=mips

x86 GCC 4.8 编译器

–arch=x86

x86_64 GCC 4.8 编译器

–arch=x86_64

arm GCC 4.8 编译器

–arch=arm

bat脚本里的–api参数需要改成自己所需的Android API,保存后双击bat文件执行,会在参数install-dir所对应的文件夹生成工具链,下图是我的运行结果:

不同的架构生成的工具链内容不同,可以在< Path to SDK>/ndk-bundle/toolchains文件夹下查看。

6.同样在目标文件夹下(我的是第4步创建的Assimp文件夹)新建一个build_assimp.bat文件,用于编译生成.so文件,文件内容如下:

@echo off

cls

REM *NOTE* Change these based on

SET ASSIMP_DIR=assimp-4.0.1

SET OUTPUT_DIR=assimp-build-arm64v8a

SET ANDROID_PATH=H:\Android\sdk

SET NDK_PATH=H:\Android\sdk\ndk-bundle

SET NDK_TOOLCHAIN=%~dp0android-toolchain-24-llvm-arm64v8a

SET CMAKE_TOOLCHAIN=%NDK_PATH%\build\cmake\android.toolchain.cmake

SET CMAKE_PATH=%ANDROID_PATH%\cmake\3.6.4111459

REM *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

assimp android build,Windows环境下编译Assimp库生成Android可用的.so文件相关推荐

  1. Windows环境VS2017编译skia库-m84,亲测成功,使用官方编译的方法

    环境准备 Windows7/10电脑需要能访问https://skia.org/和https://skia.googlesource.com/skia.git 在Windows上安装Visual St ...

  2. Android笔记——Windows环境下Android Studio v1.0安装教程

    本文主要讲解Windows环境下Android Studio的安装教程,Mac的Android Studio安装与此类似不在赘述,另外友情提示Windows下的SDK与Mac的SDK是通用的,可以直接 ...

  3. 四种环境下编译nanomsg库

    VS2013编译生成nanomsg库文件 因为工作中用到了nanomsg,又需要编译成库来使用,发现网上资料很少,所以做此记录. 编译准备,CMake工具软件和下载好的nanomsg源码包.我的是CM ...

  4. android源码环境下编译fourthling.cling库的依赖问题

    记录下,编译fourthline.cling静态库的依赖问题. 1,因为需要在android的源码环境下调试依赖cling的投屏,需要将fourthline.cling编译为静态库. 首先预制依赖的. ...

  5. 在Windows环境下编译VPX

    首先到CygWin的官网下载CygWin的安装包,编译环境需在此环境下进行,https://cygwin.com/install.html,安装的过程中,记得一定要安装perl,make,wget,a ...

  6. Windows环境下编译Airsim

    AirSim是微软基于UE4(后来也添加了Unity工程)开发的一款开源模拟器,可以模拟无人机.无人车.源码地址: https://github.com/Microsoft/AirSim 下面简单说下 ...

  7. 在Windows环境下编译cocos2d-x-3.0

    1. 安装配置开发环境 1.1 安装JDK 1) 下载并安装jdk-7u7-windows-i586.exe     2) 设置[JAVA_HOME]为"C:\Program Files\J ...

  8. Windows环境下编译FreeRDP

    关于在Linux下如何编译FreeRDP,在github的wiki上面已经说的很明白了,而且相当简单,具体细节参考网址:FreeRDP构建说明.大抵就是make,make install之类的,并且之 ...

  9. Windows环境下编译pjsip

    pjsip大体上是什么,更多内容可以参考pjsip背景组成等.项目需求在 Windows上部署运行,并开发客户端,客户端打算用MicroSip改造.MicroSip依赖pjsip. 首先编译pjsip ...

  10. Windows环境下编译OpenOCD

    1.安装git for windows sdk 下载地址:Git for Windows ps:如果安装失败,需要将安装目录删除后才能重新安装. 2.打开 Git SDK 64-bit,安装编译所需环 ...

最新文章

  1. 微生物组:3分和30分文章差距在哪里?
  2. java中属性文件读取案例_java相关:Spring中属性文件properties的读取与使用详解
  3. linux redis 启动警告解决方法
  4. Python技巧:Docker框架的使用系列教程(一)
  5. 弧焊 不同气体对焊缝的影响 100二氧化碳 15%氩气CO2混合
  6. PHP require和include的区别
  7. 1143 Lowest Common Ancestor 甲级
  8. 使用PDF.js实现前端和手机端网页预览PDF文件(可定制,支持本地文件、Base64编码和远程URL跨域方式)
  9. 永洪报表工具_2020年最值得推荐的五大BI工具
  10. 作者:李俊清,山东农业大学副教授。
  11. 浅入浅出 Android 安全:第五章 Android 应用层安全
  12. mysql limit分页_MySQL order by limit 分页数据重复问题
  13. 为什么那么多人用“ji32k7au4a83”作密码?
  14. Oracle基础入门完整版(课程笔记)
  15. 完全掌握AS中点(.)语法的应用
  16. typora的安装和配置
  17. 包含的前缀数目超过了最大值。最大值为 2_「西法带你学算法」一次搞定前缀和...
  18. linux下使用ffmpeg下载m3u8视频
  19. 看我如何抓取最新房价数据
  20. UG NX 12 草图创建过程

热门文章

  1. 怎么用PS替换图片背景色?这个方法你需要知道
  2. 对象存储介绍(腾讯云cos)
  3. storm任务提交流程
  4. Taro小程序 Input组件focus属性失效解决方案
  5. 腾讯云服务器购买与备案
  6. 龙之谷手游微信连接授权服务器失败,龙之谷手游ios微信授权失败怎么办_龙之谷手游ios微信授权失败解决办法-66街机网...
  7. fun的用法c语言,fun的用法_fun的用法
  8. 我用Python的Matplotlib库绘制25个超好看图表
  9. 单打打法类型及技、战术特点
  10. java加锁_JAVA最好的加锁方法是什么