Unity 2018.4 编译 Mono
文章目录
需求
编译自定义版本的 Mono 运行时,可以用来做 DLL 更新。考虑到跨平台编译,因此尝试使用虚拟机 + Linux 方式编译。
环境
- macOS 10.14.6
- Virtual Box 6.0.12
- Ubuntu 18.04.5 LTS Server
- Android NDK r13b
- Unity Mono 2018.4 mbe
准备
下载
Unity Mono
Unity Mono 分支 unity-2018.4-mbe 使用 GitHub Zip 方式下载
编译时使用的版本是 unity-2018.4-mbe 当前的最新版本 https://github.com/Unity-Technologies/mono/commit/7d3af3b2665639dbe0d4be714dbc66c93d419f17
Android NDK
Android NDK r13b
Ubuntu
Ubuntu 18.04 LTS
Ubuntu
安装 Ubuntu
创建一个新的虚拟机,使用专家模式
- 名字 Ubuntu 18.04 LTS,4096MB内存
- 2TB硬盘 VMDK(虚拟机磁盘)动态分配
设置 | 网络
- 网卡1 | 端口转发 添加宿主机 2222 到客户机 22 的映射
- 网卡2 | 启用网络连接 连接方式:桥接网卡
安装
全程默认设置
设置
- 名字 ubuntu
- 服务器名字 ubuntu-server
- 用户名 ubuntu
- 密码 123456
按空格键勾选 Install OpenSSH Server
,不安装其他任何组件,开始安装
安装完成后直接重启,提示推出光盘时忽略直接按回车即可。
SSH 连接虚拟机
1
|
ssh -p 2222 ubuntu@127.0.0.1 |
配置 SSH 密钥登录
如果觉得每次登录、传输文件时输入密码麻烦,可以添加一个公钥到虚拟机中
在宿主机中拷贝公钥:
1
|
pbcopy < ~/.ssh/id_rsa.pub |
在虚拟机中执行
1 2 3 4 5 6 |
cd mkdir .ssh touch .ssh/authorized_keys chmod 700 .ssh chmod 600 .ssh/authorized_keys vi .ssh/authorized_keys |
把公钥保存到 authorized_keys
中,保存退出即可。
工程文件
传输文件
1 2 3 4 5 |
scp -P 2222 mono-unity-2018.4-mbe.zip ubuntu@127.0.0.1:~ scp -P 2222 bdwgc-50b55f29ee4783dd5cc01a975e5bcdf8703cb1ee.zip ubuntu@127.0.0.1:~ scp -P 2222 boringssl-3e0770e18835714708860ba9fe1af04a932971ff.zip ubuntu@127.0.0.1:~ scp -P 2222 libatomic_ops-268c37a63b3d77803c7cec6e5b318c015a9a157c.zip ubuntu@127.0.0.1:~ scp -P 2222 android-ndk-r13b-linux-x86_64.zip ubuntu@127.0.0.1:~ |
切换 root 账户
SSH 连接后切换账户
1 2 |
ssh -p 2222 ubuntu@127.0.0.1 sudo -i |
从这儿开始所有的后续操作都是使用 root 账户进行的。
解压文件
切换当前目录到 root 用户目录 /root
,然后执行解压操作将文件解压到 /root
下。
1 2 3 4 5 6 |
cd apt install unzip unzip -q /home/ubuntu/mono-unity-2018.4-mbe.zip unzip -q /home/ubuntu/bdwgc-50b55f29ee4783dd5cc01a975e5bcdf8703cb1ee.zip unzip -q /home/ubuntu/boringssl-3e0770e18835714708860ba9fe1af04a932971ff.zip unzip -q /home/ubuntu/libatomic_ops-268c37a63b3d77803c7cec6e5b318c015a9a157c.zip |
移动文件
1 2 3 4 5 6 7 8 |
rmdir mono-unity-2018.4-mbe/external/bdwgc/ mv bdwgc-50b55f29ee4783dd5cc01a975e5bcdf8703cb1ee/ mono-unity-2018.4-mbe/external/bdwgc rmdir mono-unity-2018.4-mbe/external/bdwgc/libatomic_ops mv libatomic_ops-268c37a63b3d77803c7cec6e5b318c015a9a157c/ mono-unity-2018.4-mbe/external/bdwgc/libatomic_ops rmdir mono-unity-2018.4-mbe/external/boringssl/ mv boringssl-3e0770e18835714708860ba9fe1af04a932971ff/ mono-unity-2018.4-mbe/external/boringssl |
验证文件
输出目录内所有文件,确保内部都是正确的文件,而不是只有错误的目录或空目录。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# ls mono-unity-2018.4-mbe/external/bdwgc allchblk.c BCC_MAKEFILE CMakeLists.txt doc gc_cpp.cpp ia64_save_regs_in_stack.s Makefile.direct new_hblk.c pthread_start.c reclaim.c tests windows-untested alloc.c bdw-gc.pc.in configure.ac dyn_load.c gc_dlopen.c include malloc.c NT_MAKEFILE pthread_stop_world.c SMakefile.amiga thread_local_alloc.c appveyor.yml blacklst.c cord extra gcj_mlc.c libatomic_ops mallocx.c obj_map.c pthread_support.c sparc_mach_dep.S tools AUTHORS build darwin_stop_world.c finalize.c gc.mak m4 mark.c OS2_MAKEFILE ptr_chck.c sparc_netbsd_mach_dep.s typd_mlc.c autogen.sh ChangeLog dbg_mlc.c fnlz_mlc.c headers.c mach_dep.c mark_rts.c os_dep.c README.md sparc_sunos4_mach_dep.s WCC_MAKEFILE backgraph.c checksums.c digimars.mak gc_cpp.cc heapsections.c Makefile.am misc.c PCR-Makefile README.QUICK specific.c win32_threads.c # ls mono-unity-2018.4-mbe/external/bdwgc/libatomic_ops AUTHORS autogen.sh ChangeLog configure.ac COPYING doc m4 Makefile.am pkgconfig README.md src tests TODO # ls mono-unity-2018.4-mbe/external/boringssl BUILDING.md CMakeLists.txt codereview.settings CONTRIBUTING.md crypto decrepit fuzz FUZZING.md include INCORPORATING.md LICENSE PORTING.md README.md ssl STYLE.md third_party tool util |
编译
官方文档
建议先参考官方文档了解编译流程,然后再参考下面的流程手动处理。
安装构建软件
直接执行命令会提示有依赖软件未安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# ./autogen.sh --prefix=$PREFIX **Error**: You must have `autoconf' installed to compile Mono. Download the appropriate package for your distribution, or get the source tarball at ftp://ftp.gnu.org/pub/gnu/ **Error**: You must have `libtoolize' installed to compile Mono. Get ftp://ftp.gnu.org/gnu/libtool/libtool-1.2.tar.gz (or a newer version if it is available) **Error**: You must have `automake' installed to compile Mono. Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz (or a newer version if it is available) configure: error: "cmake not found" |
需要安装官方文档上指明的依赖软件
1
|
apt-get install git autoconf libtool automake build-essential gettext cmake python3 curl |
初始化编译环境
所有的命令行输出中只截取了最后的一段输出,中间的省略了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# cd mono-unity-2018.4-mbe # mkdir /opt/mono # PREFIX=/opt/mono # echo $PREFIX /opt/mono # ./autogen.sh --prefix=$PREFIX === configuring in external/bdwgc (/root/mono-unity-2018.4-mbe/external/bdwgc) configure: WARNING: no configuration information is in external/bdwgc mcs source: mcs C# Compiler: roslyn Engine: Host: x86_64-pc-linux-gnu Target: x86_64-pc-linux-gnu GC: sgen (concurrent by default) and Included Boehm GC with typed GC and parallel mark TLS: __thread SIGALTSTACK: no Engine: Building and using the JIT BigArrays: no DTrace: no LLVM Back End: no (dynamically loaded: no) Libraries: .NET 4.x: yes Xamarin.Android: no Xamarin.iOS: no Xamarin.WatchOS: no Xamarin.TVOS: no Xamarin.Mac: no Windows AOT: no Unity JIT: default Unity AOT: default Orbis: no Unreal: no WebAssembly: no Test profiles: AOT Full (no), AOT Hybrid (no) JNI support: IKVM Native libgdiplus: assumed to be installed zlib: BTLS: yes (x86_64) Now type `make' to compile |
说明大部分条件已准备好,但是缺失 bdwgc
配置文件,实际 bdwgc
目录是空的。
打开构建脚本,注释掉不用的平台 armv5 armv6_vfp,加快构建时间。
1
|
vi external/buildscripts/build_runtime_android.pl |
1 2 3 4 5 |
# By default, build runtime for all the variants we need. But allow something to specify an individual variation to build if ($androidArch eq "") { # system("perl", "$buildScriptsRoot/build.pl", "--build=1", "--clean=1", "--artifact=1", "--arch32=1", "--androidarch=armv5", "--forcedefaultbuilddeps=1", "--windowssubsystemforlinux=$windowsSubsystemForLinux", "--stevedorebuilddeps=$stevedoreBuildDeps") eq 0 or die ("Failed building mono for armv5\n"); # system("perl", "$buildScriptsRoot/build.pl", "--build=1", "--clean=1", "--artifact=1", "--arch32=1", "--androidarch=armv6_vfp", "--forcedefaultbuilddeps=1", "--windowssubsystemforlinux=$windowsSubsystemForLinux", "--stevedorebuilddeps=$stevedoreBuildDeps") eq 0 or die ("Failed building mono for armv6_vfp\n"); |
第一次编译
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# sh external/buildscripts/build_runtime_android.sh >>> PATH in Build All = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin >>> Build All Args = --build=1 --clean=1 --artifact=1 --arch32=1 --androidarch=armv7a --forcedefaultbuilddeps=1 --windowssubsystemforlinux=0 --stevedorebuilddeps=1 >>> Mono checkout = /root/mono-unity-2018.4-mbe >> System Info : Linux ubuntu-server 4.15.0-117-generic #118-Ubuntu SMP Fri Sep 4 20:02:41 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux fatal: not a git repository (or any of the parent directories): .git fatal: not a git repository (or any of the parent directories): .git >>> Mono Revision = >>> Build Scripts Revision = >>> External build deps = /root/mono-unity-2018.4-mbe/external/buildscripts/artifacts/Stevedore >>> Existing Mono = >>> Mono Arch = i686 >>> No existing mono supplied. Checking for external... >>> Running bee to download build-deps... ./bee: 5: ./bee: mono: not found ^Cfailed to run bee Failed building mono for armv7a |
安装 Mono
必须先安装 Mono 才能编译 Mono,这是一个自举问题。
编译安装 Mono
虽然 Unity 官方文档中提到了编译安装 monolite,但是速度实在是太慢了
1 2 |
# Run the following line after ./autogen.sh make get-monolite-latest |
包管理器 Mono
不要使用 apt install mono-devel
安装 ubuntu 包管理器的 mono,无法运行 bee,提示
1 2 3 4 |
>>> Running bee to download build-deps... Unhandled Exception: System.TypeLoadException: Could not load type 'Bee.StandaloneBeeDriver' from assembly 'bee, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. |
如果安装了需要先删除
1
|
sudo apt-get --purge remove mono-runtime |
Mono 官方预编译版本
Mono 官方的源太慢,需要使用代理
1
|
vi /etc/apt/apt.conf.d/proxy.conf |
修改代理地址为局域网内代理
1 2 3 4 |
Acquire { HTTP::proxy "http://192.168.1.1:7890"; HTTPS::proxy "http://192.168.1.1:7890"; } |
必须使用代理下载安装 Mono,否则安装极慢
Ubuntu 18.04 (i386, amd64, armhf, arm64, ppc64el)
1 2 3 4 5 |
sudo apt install gnupg ca-certificates sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF echo "deb https://download.mono-project.com/repo/ubuntu stable-bionic main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list sudo apt update apt install mono-devel |
第二次编译
1 2 3 4 5 6 7 |
# sh external/buildscripts/build_runtime_android.sh >>> Android NDK needs to be extracted >>> Android NDK Extension = .zip unzip: cannot find or open /root/mono-unity-2018.4-mbe/external/buildscripts/artifacts/Stevedore/android-ndk-r13b-linux/android-ndk-r13b-linux-x86_64.zip, /root/mono-unity-2018.4-mbe/external/buildscripts/artifacts/Stevedore/android-ndk-r13b-linux/android-ndk-r13b-linux-x86_64.zip.zip or /root/mono-unity-2018.4-mbe/external/buildscripts/artifacts/Stevedore/android-ndk-r13b-linux/android-ndk-r13b-linux-x86_64.zip.ZIP. Something went wrong with the NDK extraction Failed building mono for armv7a |
需要将 ndk 移动到指定位置
1 2 3 |
mv /home/ubuntu/android-ndk-r13b-linux-x86_64.zip . mkdir /root/mono-unity-2018.4-mbe/external/buildscripts/artifacts/Stevedore/android-ndk-r13b-linux mv android-ndk-r13b-linux-x86_64.zip /root/mono-unity-2018.4-mbe/external/buildscripts/artifacts/Stevedore/android-ndk-r13b-linux/android-ndk-r13b-linux-x86_64.zip |
第三次编译
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# sh external/buildscripts/build_runtime_android.sh >>> LIBTOOLIZE before Build = /root/mono-unity-2018.4-mbe/external/buildscripts/artifacts/Stevedore/built-tools/bin/libtoolize >>> LIBTOOL before Build = /root/mono-unity-2018.4-mbe/external/buildscripts/artifacts/Stevedore/built-tools/bin/libtool >>> Cleaning /root/mono-unity-2018.4-mbe/tmp >>> Calling autogen in mono >>> Configure parameters are : --disable-mcs-build --with-glib=embedded --disable-nls --disable-btls --with-mcs-docs=no --prefix=/root/mono-unity-2018.4-mbe/tmp --host=armv5-linux-androideabi --disable-parallel-mark --disable-shared-handles --with-sigaltstack=no --with-tls=pthread --disable-visibility-hidden mono_cv_uscore=yes **Error**: You must have `libtoolize' installed to compile Mono. Get ftp://ftp.gnu.org/gnu/libtool/libtool-1.2.tar.gz (or a newer version if it is available) failing autogenning mono at /root/mono-unity-2018.4-mbe/external/buildscripts/build.pl line 1344. Failed building mono for armv7a |
修改 /root/mono-unity-2018.4-mbe/external/buildscripts/build.pl
1 2 3 4 5 6 7 8 9 |
# vi /root/mono-unity-2018.4-mbe/external/buildscripts/build.pl 450 $ENV{'LIBTOOLIZE'} = "$builtToolsDir/bin/libtoolize"; 451 $ENV{'LIBTOOL'} = "$builtToolsDir/bin/libtool"; 改为 450 $ENV{'LIBTOOLIZE'} = "/usr/bin/libtoolize"; 451 $ENV{'LIBTOOL'} = "/usr/bin/libtool"; |
第四次编译
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# sh external/buildscripts/build_runtime_android.sh python ./genmdesc.py TARGET_ARM . cpu-arm.h arm_cpu_desc ./cpu-arm.md /bin/bash: python: command not found Makefile:3594: recipe for target 'cpu-arm.h' failed make[3]: *** [cpu-arm.h] Error 127 make[3]: Leaving directory '/root/mono-unity-2018.4-mbe/mono/mini' Makefile:481: recipe for target 'all-recursive' failed make[2]: *** [all-recursive] Error 1 make[2]: Leaving directory '/root/mono-unity-2018.4-mbe/mono' Makefile:555: recipe for target 'all-recursive' failed make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory '/root/mono-unity-2018.4-mbe' Makefile:485: recipe for target 'all' failed make: *** [all] Error 2 Failed to make Failed building mono for armv7a |
提示缺少 Python2,手动安装:
1
|
apt install python |
第五次编译
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# sh external/buildscripts/build_runtime_android.sh 最终提示 >>> Skipping make install. We don't need to run this step when building the runtime on non-desktop platforms. >>> Skipping build Unity Script and Boo >>> Creating artifact... >>> Creating embedruntimes directory : /root/mono-unity-2018.4-mbe/builds/embedruntimes/android/x86 >>> Copying libmonosgen-2.0.so >>> Copying libmonobdwgc-2.0.so >>> Copying libMonoPosixHelper.so >>> Creating monodistribution directory >>> Creating version file : /root/mono-unity-2018.4-mbe/builds/versions-android-x86.txt >>> Skipping unit tests |
证明编译成功,检查构建结果
检查
确认编译的目标平台目录里都存在需要的库文件:
1 2 3 4 |
# ls /root/mono-unity-2018.4-mbe/builds/embedruntimes/android/x86 libmonobdwgc-2.0.so libMonoPosixHelper.so libmonosgen-2.0.so # ls /root/mono-unity-2018.4-mbe/builds/embedruntimes/android/armv7a/ libmonobdwgc-2.0.so libMonoPosixHelper.so libmonosgen-2.0.so |
把所有文件拷贝到 Gradle 工程中输出使用
注意
不要按下面的方法修改 libbdwgc_libs
,会导致编译出来的 mono 无法运行,Unity 运行时在屏幕中间提示
1 2 |
Error Failed to load Mono. |
1 2 3 4 5 |
5,修改编译文件错误 打开 mono/mini目录下的 makefile文件,找到 libbdwgc_libs = $(monodir)/external/bdwgc/libgc_static.la 改为 libbdwgc_libs = $(monodir)/external/bdwgc/libgc.la |
参考资料
文章作者 狂飙
初次发布 2020-09-20 22:15:10 +0800
永久链接 https://networm.me/2020/05/10/unity-2018.4-compile-mono/