Android Studio 中集成 ASSIMP

软件版本

SDK、NDK 和 CMake 都是使用 Android Studio 的 SDK Manager 下载的。

  • 操作系统:macOS Big Sur Beta
  • Android Studio: 4.0.1
  • ASSIMP:5.0.1,官网下载地址:The 5.0.1 bugfix release
  • SDK:30.0.1
  • NDK:21.0.6113669
  • CMake:3.10.2.4988404
  • Gradle:6.1.1(Android Gradle Plugin Version 是 4.0.1)

交叉编译工具Toolchain

根据NDK版本设定其路径,这里我使用的是 21.0.6113669。NDK提供的standalone_toolchain的路径如下:

$NDK_PATH/build/tools/make-standalone-toolchain.sh

设置环境变量

export NDK_PATH=/Users/zhuxiaoyang/Library/Android/sdk/ndk/21.0.6113669

创建Toolchain 工具

sh make-standalone-toolchain.sh –platform=android-8 –ndk-dir=$NDK_PATH –install-dir=/Users/zhuxiaoyang/Library/Android/sdk/android-toolchain –toolchain=arm-linux-androideabi-4.4.3

安装成功后,提示如下:
Android Studio 中集成 ASSIMP_第1张图片
到这个目录下会发现名为arm-linux-androideabi.tar.bz2的压缩文件,请把它解压,并放到/Users/zhuxiaoyang/Library/Android/sdk/android-toolchain下。在Mac下是这样的,其他平台应该会直接生成到/Users/zhuxiaoyang/Library/Android/sdk/android-toolchain目录下。
解压后放好,如下图所示。
Android Studio 中集成 ASSIMP_第2张图片

ASSIMP编译 .so 文件

这里编译的是 armeabi-v7a 版本,其他版本可根据需要修改。

基础环境变量设置

编译时用到的一些工具,都是通过环境变量的形式传给脚本。必须设置的几个环境变量如下:

export ANDROID_NDK_PATH=/Users/zhuxiaoyang/Library/Android/sdk/ndk/21.0.6113669
export ANDROID_SDK_PATH=/Users/zhuxiaoyang/Library/Android/sdk
export CMAKE_TOOLCHAIN=/Users/zhuxiaoyang/Library/Android/sdk/ndk/21.0.6113669/build/cmake/android.toolchain.cmake
export ANDROID_NDK_TOOLCHAIN=/Users/zhuxiaoyang/Library/Android/sdk/android-toolchain
export PATH=$PATH:/Users/zhuxiaoyang/Library/Android/sdk/android-toolchain/bin

CMake 生成 makefile

cd xxx/assimp // 下载assimp解压缩的位置
mkdir build // 创建文件夹
cd build // 进入这个文件夹

然后执行CMake命令

cmake -DCMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN -DCMAKE_INSTALL_PREFIX=/assimp -DANDROID_ABI=armeabi-v7a -DANDROID_NATIVE_API_LEVEL=android-14 -DANDROID_FORCE_ARM_BUILD=TRUE -DANDROID_STL=c++_shared -DASSIMP_BUILD_OBJ_IMPORTER=TRUE -DASSIMP_BUILD_FBX_IMPORTER=TRUE -DANDROID_NDK=$ANDROID_NDK_PATH -DCMAKE_BUILD_TYPE=Release -DANDROID_FORCE_ARM_BUILD=TRUE -DCMAKE_CXX_FLAGS=-Wno-c++11-narrowing -DANDROID_TOOLCHAIN=clang -DASSIMP_BUILD_TESTS=OFF -DASSIMP_NO_EXPORT=TRUE -DASSIMP_BUILD_ASSIMP_TOOLS=FALSE -DASSIMP_BUILD_SAMPLES=FALSE -DASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT=FALSE ..

如果是想生成arm64-v8a版本的库,可执行如下命令:

cmake -DCMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN -DCMAKE_INSTALL_PREFIX=/assimp -DANDROID_ABI=arm64-v8a -DANDROID_NATIVE_API_LEVEL=android-16 -DANDROID_FORCE_ARM_BUILD=TRUE -DANDROID_STL=c++_shared -DASSIMP_BUILD_OBJ_IMPORTER=TRUE -DASSIMP_BUILD_FBX_IMPORTER=TRUE -DANDROID_NDK=$ANDROID_NDK_PATH -DCMAKE_BUILD_TYPE=Release -DANDROID_FORCE_ARM_BUILD=TRUE -DCMAKE_CXX_FLAGS=-Wno-c++11-narrowing -DANDROID_TOOLCHAIN=clang -DASSIMP_BUILD_TESTS=OFF -DASSIMP_NO_EXPORT=TRUE -DASSIMP_BUILD_ASSIMP_TOOLS=FALSE -DASSIMP_BUILD_SAMPLES=FALSE -DASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT=FALSE ..

参数解释

-DCMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN 指向上面生成的toolchain
-DCMAKE_INSTALL_PREFIX=/assimp 最终生成的.so文件的名称
-DANDROID_ABI=armeabi-v7a 应用程序二进制接口类型,详见[ABI Management](https://developer.android.com/ndk/guides/abis)
-DANDROID_NATIVE_API_LEVEL=android-14 api版本,设成这个就行
-DANDROID_FORCE_ARM_BUILD=TRUE 强制编译arm架构
-DANDROID_STL=c++_shared c++类型
-DASSIMP_BUILD_OBJ_IMPORTER=TRUE 支持OBJ格式的3D模型文件导入
-DASSIMP_BUILD_FBX_IMPORTER=TRUE 支持FBX格式的3D模型文件导入
-DASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT=FALSE assimp默认支持很多种3D模型格式,这里只指定常用的一两种格式即可,减小.so包的大小
-DASSIMP_BUILD_TESTS=OFF 这个要关掉,不然make时会有一些奇怪的错误
-DASSIMP_NO_EXPORT=TRUE 只需要解析3D模型,不需要生成3D模型

正确运行的结果如下:
Android Studio 中集成 ASSIMP_第3张图片
之后执行make命令

make -j4

如无意外,即可编译成功。生成的 libassimp.so 文件在 assimp-5.0.1/buildAndroid/code 目录下。
Android Studio 中集成 ASSIMP_第4张图片

简单测试

使用 Android Studio 创建Native C++项目。具体可参考 Android Studio 中集成 OpenCV (Java 和 NDK 均可,不使用Manager) 中的 创建 Native C++ 项目

头文件和库文件拷贝

将 assimp-5.0.1/include/assimp 文件夹整体拷贝到项目app/src/main/cpp/include 文件夹下;将 assimp-5.0.1/build/include/assimp/config.h 文件也拷贝到项目app/src/main/cpp/include 文件夹下。
将 assimp-5.0.1/build/code/libassimp.so 文件拷贝到项目app/src/main/jniLibs/armeabi-v7a 文件夹下。
拷贝完成后,其目录结构如下所示(自动忽略opencv的相关文件夹):
Android Studio 中集成 ASSIMP_第5张图片

CMakeLists.txt 设置

添加头文件和库文件的引用

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# ====================================================================================
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -fexceptions -frtti")

set(libs "${CMAKE_SOURCE_DIR}/../jniLibs")
include_directories(include)

# =====  ASSIMP  =====
add_library(libassimp SHARED IMPORTED )
set_target_properties(libassimp PROPERTIES
        IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libassimp.so")
# ====================================================================================

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             native-lib.cpp )

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
                       native-lib

                       # Links the target library to the log library
                       # included in the NDK.
                       libassimp
                       android
                       ${log-lib} )

build.gradle 设置

这里需要注意的是以下几行,否则程序可能会闪退

arguments "-DANDROID_STL=c++_shared"

        ndk{
            abiFilters "armeabi-v7a"
        }
        
    packagingOptions {
        pickFirst 'lib/armeabi-v7a/libassimp.so'
    }

完整文件如下所示:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.1"

    defaultConfig {
        applicationId "com.casmc.opencvndk"
        minSdkVersion 21
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags "-std=c++11 -frtti -fexceptions"
                arguments "-DANDROID_ABI=armeabi-v7a"
                arguments "-DANDROID_STL=c++_shared"
                arguments "-DCMAKE_BUILD_TYPE=Release"
            }
        }
        ndk{
            abiFilters "armeabi-v7a"
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
        }
    }

    packagingOptions {
        pickFirst 'lib/armeabi-v7a/libassimp.so'
    }
}


dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

}

测试文件

为了进行简单的测试,这里需要在 native-lib.cpp 中加上头文件引用

#include 

并在任意一个函数里面添加以下语句:

Assimp::Importer();

编译程序并运行,如果程序不出现闪退,则说明程序能够正常运行。

实际测试

实际的Demo我参考的是 使用Android Studio+CMakeLists编译assimp,并附有 GitHub代码。可根据需要进行更改,这里就不再赘述了。当程序正常运行时,结果如下所示。
Android Studio 中集成 ASSIMP_第6张图片

参考链接

  1. Android: Use Assimp to load a 3D model
  2. 使用Android Studio+CMakeLists编译assimp
  3. Assimp Android 编译

你可能感兴趣的:(工具安装)