Android Unity il2cpp 编译异常

开发背景

利用Unity开发3d模块,将3d模块嵌入Android项目。

开发环境

Android Studio 2020.3.1 Patch3

Gradle 6.1.1

Android Gradle Plugin(AGP) 3.1.4

Unity 2020.3.20f1c1

问题描述

当前Android 嵌入Unity模块的方案:

Unity采用Mono编译,导出AndroidProject,在主Android项目中引入AndroidProject中的UnityLibiary。

后来将Unity设置为il2cpp,然后依照上述步骤构建Android项目时候,报错

Execution failed for task ':unityLibrary:compileDebugNdk'.

Error: Your project contains C++ files but it is not using a supported native build system. Consider using CMake or ndk-build integration. For more information, go to: https://d.android.com/r/studio-ui/add-native-code.html Alternatively, you can use the experimental plugin: https://developer.android.com/r/tools/experimental-plugin.html

经过测试,是将Android Gradle Plugin版本调整为 3.4.0 可以构建成功,3.3+版本则编译不通过。

但是由于Android主工程限制Android Gradle Plugin必须为3.1.4。所以不能通过升级Android Gradle Plugin解决问题。

经过分析Unity到出的AS工程中的Gradle文件做出以下分析

改为il2cpp后,工程内有c++代码,但是Android工程没有配置NDK或者cmake编译,所以AGP3.1.4认为这是不合理的,故报上述错误。分析Unit生成的文件,之所以 Unity 导出的工程没配置NDK 、cmake 编译,是因为 unity是通过自己的il2cpp.exe程序构建的,不需要“Add c++ to Moudle”。

主要是Gradle文件中的BuildIl2Cpp在负责c++的构建过程。

def BuildIl2Cpp(String workingDir, String targetDirectory, String architecture, String abi, String configuration) {
    exec {
        commandLine(workingDir + "/src/main/Il2CppOutputProject/IL2CPP/build/deploy/netcoreapp3.1/il2cpp.exe",
            "--compile-cpp",
            "--libil2cpp-static",
            "--platform=Android",
            "--architecture=" + architecture,
            "--configuration=" + configuration,
            "--outputpath=" + workingDir + targetDirectory + abi + "/libil2cpp.so",
            "--cachedirectory=" + workingDir + "/build/il2cpp_"+ abi + "_" + configuration + "/il2cpp_cache",
            "--additional-include-directories=" + workingDir + "/src/main/Il2CppOutputProject/IL2CPP/external/bdwgc/include",
            "--additional-include-directories=" + workingDir + "/src/main/Il2CppOutputProject/IL2CPP/libil2cpp/include",
            "--tool-chain-path=" + android.ndkDirectory,
            "--map-file-parser=" + workingDir + "/src/main/Il2CppOutputProject/IL2CPP/MapFileParser/MapFileParser.exe",
            "--generatedcppdir=" + workingDir + "/src/main/Il2CppOutputProject/Source/il2cppOutput",
            "--baselib-directory=" + workingDir + "/src/main/jniStaticLibs/" + abi,
            "--dotnetprofile=unityaot")
        environment "ANDROID_SDK_ROOT", getSdkDir()
    }
    delete workingDir + targetDirectory + abi + "/libil2cpp.sym.so"
    ant.move(file: workingDir + targetDirectory + abi + "/libil2cpp.dbg.so", tofile: workingDir + "/symbols/" + abi + "/libil2cpp.so")
}

android {
    task BuildIl2CppTask {
        doLast {
              BuildIl2Cpp(projectDir.toString().replaceAll('\\\\', '/'), '/src/main/jniLibs/', 'ARMv7', 'armeabi-v7a', 'Release');
        }
    }
    afterEvaluate {
        if (project(':unityLibrary').tasks.findByName('mergeDebugJniLibFolders'))
            project(':unityLibrary').mergeDebugJniLibFolders.dependsOn BuildIl2CppTask
        if (project(':unityLibrary').tasks.findByName('mergeReleaseJniLibFolders'))
            project(':unityLibrary').mergeReleaseJniLibFolders.dependsOn BuildIl2CppTask
    }
    sourceSets {
        main {
            jni.srcDirs = ["src/main/Il2CppOutputProject"]
        }
    }
}

经测试,先用AGP3.5 构建工程然后,注释掉gradle 文件中 il2cpp.exe的构建过程,同时删除c++代码后,然后改用AGP3.1.4 插件,构建通过,程序正常运行。

过经过分析大致得出以下几个解决方案

  1. 升级AGP到3.4以上版本(因为项目限制,本项目不适用)

  2. 降级Unity到一个旧版本,找一个和AGP3.1.4同时代的旧版本(只是个方案而已,不推荐)

  3. 升级AGP到3.4以上版本,构建好Unity项目中的c++,然后删除c++文件(即src/main/Il2CppOutputProject目录),然后删除Gradleil2cpp构建步骤(即上边贴出的代码),将AGP改回到3.1.4(实验过程得出的方案,很绕,不推荐)

  4. 将Unity导出的Android构建成aar,给Android主工程调用(AGP用Unity默认的版本4.0.1即可)。(本项目最适用的方案)

总结

问题根源Android项目太老,Unity项目较新,导致的不匹配。两者步调一致,就能避免类似的坑。

个人建议,在时间精力足够的条件下,项目和开发环境最好能跟着时代节奏比较好。举个例子,2021年了,有人还是喜欢用Photoshop cs5,殊不知Photoshop2020都有一键抠图的功能了。

你可能感兴趣的:(Unity3D,android,unity,il2cpp,gradle)