本文与 Unity Mono DLL加密 有异曲同工之处,目标是在 Android 平台下实现 C# 代码的热更新。更进一步的方向是更新 .so 文件,从而实现 il2cpp 的热更。

搭建 Mono 编译环境

参考:https://blog.csdn.net/huutu/article/details/58184031

  1. 下载 mono 的 Unity 分支源代码:https://github.com/Unity-Technologies/mono
  2. 下载 Ubuntu 14 64 位系统。
  3. Unity 5.6 版本必须使用 NDK r10e,下载对应版本的 NDK。
  4. 切换到 root 并安装 NDK:
    sudo su
    ./android-ndk-r10e-linux-x86.bin
  5. 安装完成后,在安装目录中找到 RELEASE.txt,确认 NDK 完整版本号,去掉其中的 rc4,修改为 r10e
  6. 设置环境变量 ANDROID_NDK_ROOT
    sudo gedit /etc/bashrc
  7. 在文件末尾添加一行:
    export ANDROID_NDK_ROOT=/home/css/android-ndk-r10e;
  8. 使环境变量立即生效并验证:
    source /etc/bashrc
    echo $ANDROID_NDK_ROOT
  9. 修改脚本 build_runtime_android.sh
    sudo gedit build_runtime_android.sh
    • 搜索 KRAIT_PATCH_PATH,修改为:
      KRAIT_PATCH_PATH="${CWD}/android_krait_signal_handler/build"
    • 搜索 (cd "$KRAIT_PATCH_PATH" &&,修改为:
      (cd "$KRAIT_PATCH_PATH" && perl ./build.pl)
    • 删除 android_krait_signal_handler/build.pl 第一行的注释。
  10. 安装编译所需依赖环境:autoconf、automake、bison、gcc、gettext、glib、make、perl。
  11. 在 mono 目录下直接执行编译脚本:
    ./external/buildscripts/build_runtime_android.sh
    输出目录为 builds/embedruntimes/android/xxxxxx

踩坑记录

  1. 修改 build_runtime_android.sh,将编译选项中的 -fpic -g 去掉 -g,并添加 -O2 优化。注意:-O3-O4 会导致闪退。

  2. 注释掉 ARMv5 和 ARMv6 相关的编译步骤:

    #clean_build "$CCFLAGS_ARMv5_CPU" "$LDFLAGS_ARMv5" "$OUTDIR/armv5"
    #clean_build "$CCFLAGS_ARMv6_VFP" "$LDFLAGS_ARMv5" "$OUTDIR/armv6_vfp"
  3. image.c 中对 name 字段需要加空值判断,否则在调用 Assembly.LoadXXXXX 等反射接口时会闪退。

  4. 重定向路径时务必确认路径的正确性,注意 Application.perXXXXXPath 的实际值。

2013.3.0 f1 版本的编译方式相同,只需更新 mono 相关部分,NDK r10e 同样适用。

TODO