Windows環境下編譯Assimp庫生成Android可用的.a/.so文件

前言

在做項目過程中需要使用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。

步驟

  1. 下載Android Studio(主要是利用其帶的SDK以及CMAKE)
  2. 下載並安裝Python,注意安裝過程中需要勾選添加到環境變量,我安裝的是Python3.5,可通過命令行鍵入python檢查Python是否已經配置好
  3. 下載NDK, 本文使用r14b 64位 (https://github.com/assimp/assimp/wiki/Android-compilation-on-Windows-%28Quick-overview%29)
  4. 下載並解壓Assimp-v.5.0.0.rc1
    在這裏插入圖片描述
  5. 在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。
    在這裏插入圖片描述
  6. 將生成的android-toolchain-24-llvm-armeabi_v7a整個文件夾複製到Assimp-v.5.0.0.rc1的同級目錄下。
  7. 在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

一些錯誤的記錄:

  • List item
    **解決方法:**去assimp/code/CMakeList.txt中將IrrXML相關的代碼註釋掉,然後Assimp支持很多格式,但是在實際使用中,除非本身就是一個3D模型查看器或者轉換器,否則最終可能就固定使用那麼2,3個格式。顯然編譯時把其他的格式編進去是無用且浪費的,徒增庫的大小,並且一些模型的導入用到了IrrXML相關的代碼,比如上圖中ColladaParser。剔除不需要的模型格式的方法是:將對應的導入的代碼註釋掉,並且添加一個宏。
    在這裏插入圖片描述
  • 有些std::xxx在assimp自己的文件中有定義,會發生衝突,這種情況根據報錯進行對應的修改。
  • atof not find,頭文件沒包含,include一下

Assimp定製化:

assimp功能強大,可以加載和導出多種3D模型,附加多種效果優化功能,但在需求中有很多功能使用不到,所以可以在編譯時直接剔除已達到減小靜態庫的目的,需要注意的是:除了需要在編譯時通過宏控制編譯之外還需要直接在code/CMakeLists.txt文件中將相應的源碼註釋掉。

  1. 在編譯時只保留obj模塊,其餘模塊都不需要編譯,可以直接通過cmake-gui工具直接取消對應模塊的勾選來達到排除對應模塊編譯的效果。
  2. 因爲我們只使用assimp的模型加載功能,所以在assimp項目code/CMakeLists.txt文件中將*Exporter.cpp源碼【如:AssxmlExporter.cpp】列表註釋以達到將該源碼剔除編譯列表的目的。
  3. 根據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庫是有內存泄漏的!!!
重要的事情說三遍。
謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章