Mono-mbe版本编译libmonobdwgc-2.0.so

Linux下编译Unity mono源码的libmonobdwgc-2.0.so

1 编译简介

我这里编译mono.so目的是为了安卓做dll热更(也可dll加密),热更和加密部分主要就是修改源码mono/metadata/image.c里面的mono_image_open_from_data_with_name函数(参考http://blog.sina.com.cn/s/blog_9e5d42ee0102vvtg.html),这里不做介绍,只介绍不一样的打包方式。先补充几个概念(这一部分来源:https://www.cnblogs.com/lijiajia/p/7822571.html)
md导过来图片有丢失,可以去下载我这篇文章的PDF版:Mono-mbe版源码编译.pdf

1.1 unity跨平台运行原理

通常Unity的脚本有C#、JS、Boo。不过现在官方都只推荐使用C#了,为什么Unity可以支持用不同的语言编写代码呢?因为它使用了一种叫CIL的中间语言,C#、JS、Boo,最终都会被编译成一种叫IL的中间语言,然后通过Mono运行时编译成原生代码运行。

1.2 Mono JIT

JIT就是及时编译(just in time),能把IL及时编译成原生代码运行,跟解释语言又有些不同,JIT不是逐行解释执行,而是会把解释过的代码缓存起来,以备下次运行,因此从理论上说JIT可以接近以前的纯编译技术。Unity的跨平台是运行在Mono虚拟机上的,在安卓上可以通过JIT实现动态编译IL Assembly来热更新代码,但是在IOS平台,由于苹果公司禁用了JIT,只能通过AOT提前静态编译后执行。

1.3 unity不同设置对应的mono源码选择和编译结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wjOPHgdT-1578308868516)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200105162036735.png)]

Unity的PlayerSetting里面Scripting Runtime Version选择.Net3.5的话,mono源码版本选择普通版本即可,编译生成普通mono.so。编译方法网上比较多:https://www.cnblogs.com/lijiajia/p/7822571.html

如果Scripting Runtime Version选择.Net4.x的话(unity2018开始已经将.Net3.5的选项标记为弃用了),此时mono源码版本要选择相应的mbe版本,编译会生成libmonobdwgc-2.0.so。

2 Linux环境搭建

如果用windows编译,比较麻烦,问题也千奇百怪(旧版本mono是这样的,网上也有很多教程提到),所以选择Linux下编译,大部分人估计都没装Linux系统,所以推荐windows下安装虚拟机即可,比较使用。

主要是下载VM和Ubuntu,关于这两步的操作,网上大把教程,在此就不赘述。有个教程比较详细,两个软件的安装都在里面:

https://blog.csdn.net/u013142781/article/details/50529030

其他需要的东西,在第6步正式编译时候会慢慢说。

3 安装mono平台

可以参考官网安装方法:https://www.mono-project.com/download/stable/#download-lin-ubuntu

3.1 下载mono资源库到本地

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3zcvqq2F-1578308868518)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200105144822639.png)]

运行截图里面的命令

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

即可下载,有进度显示,下载较慢。

有时候会有提示有些packages是自动下载的,而且现在已经不需要了,你可以去移除他们(当然不移除也没什么问题,反正也是没用的资源)移除命令:

sudo apt autoremove

3.2 安装mono资源库

安装命令:

sudo apt install mono-devel

安装过程有需要确认的地方输入:Y,(确保你的磁盘大小足够)

安装过程也去去下载一些关联资源,所以时间很久,网络不好可能会出现下图这种下载错误:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uizhyKov-1578308868519)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200105150602546.png)]

最后一行已经提示了,你可以运行apt-get update或者运行修复丢失的命令即:

apt-get install mono-devel --fix-missing

即可继续下载之前下载失败的资源

3.3 验证mono

可以输入版本号查询,发现已经有信息了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-apgGJoml-1578308868519)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200105152120915.png)]

如果还不放心的话,可以去验证官网那个链接的例子:

https://www.mono-project.com/docs/getting-started/mono-basics/

4 下载unity-mono源码

先去下载unity-2018.4-mbe的mono源码压缩包:https://github.com/Unity-Technologies/mono/tree/unity-2018.4-mbe

然后解压到虚拟机的某个文件夹,我的就直接放在Downloads下面了。

注意:

这里最好用命令去下载,这样会把项目关联的一些扩展文件也一起下载下来,不过很慢,而且不一定能下得动(有些地区网络就下不了,这方面不太懂,我在深圳就下载不了,就找了武汉的朋友用浏览器下载压缩包给我的)。手动下载压缩包的话,就下不到关联文件,这时需要挨个手动下载,不下载的话解压后的external文件夹是空的,编译不了,所以比较麻烦但没办法,关联的扩展文件下载地址:

https://github.com/Unity-Technologies/mono/tree/unity-2018.4-mbe/external

5 安装安卓NDK

一定要安装mono源码需要的ndk,不然等会编译会报错,查看mono源码需要的ndk版本,可以打开mono源码的external/buildscripts/build.pl查看

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TRoeYkCe-1578308868520)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200106185501504.png)]

5.1 下载NDK

ndk下载地址:

https://developer.android.google.cn/ndk/downloads/older_releases.html#ndk-13b-downloads

5.2 安装NDK

下载后,我这边就解压到了Home下面,然后需要配置ndk的环境变量:

sudo gedit ~/.bashrc

在文件末尾添加如下内容:

export ANDROID_NDK="/home/android-ndk-r13b"

export PATH=" A N D R O I D N D K : ANDROID_NDK: ANDROIDNDK:{PATH}"

保存退出,然后运行使之生效命令:

source ~/.bashrc

验证环境变量生效方法:

输入命令:$PATH,查看环境变量是否已经有刚才添加的ndk路径

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YfeDEpQo-1578308868520)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200105210751093.png)]

5.3 验证NDK

验证ndk安装成功方法:

运行命令:

ndk-build

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ufDnJDsh-1578308868520)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200106122349176.png)]

只要不是command not foundndk-build命令不存在,就表明Android-NDK安装并配置成功。

6 正式编译

主要就是编译build_runtime_android.sh文件,但是编译过程会有很多错误挡住,下面来重头开始编译一遍。

1.首先进入编译目录:mono2018.4mbe/mono-unity-2018.4-mbe/external/buildscripts,然后打开命令窗口,最好先将当前账户升级到root账户,不然有些需要权限的地方需要频繁输入密码,升级最高权限账户命令:sudo su

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KFysThMP-1578308868521)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200106123153140.png)]

2.设置root用户,执行命令:./build_runtime_android.sh,这时会看到说权限不够

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lFlBGKz9-1578308868521)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200105101056807.png)]

那么给该文件夹添加执行权限: chmod +x -R *,然后执行查看当前文件夹内容命令:ls,发现文件都变成绿色的了,就表示执行成功了(原本没有权限时候都是白色的)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j991OTNu-1578308868522)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200105101517892.png)]

3.然后继续执行命令:./build_runtime_android.sh

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rBovdYyX-1578308868522)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200105101952356.png)]

输入yes继续执行,会提示编译失败,截图如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jv4mGwm6-1578308868523)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200105102126438.png)]

在build.pl里面搜索“Failed to checkout mono build tools extra”的代码会发现在294行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yZjgWKwu-1578308868523)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200105110752737.png)]

分析那段代码意思是说要去下载一个“mono-build-tools-extra”的东西,但是这玩意网上已经找不到了,所以暂时修改这个checkout结果(有大佬知道怎么回事,欢迎留言指导!)

4.修改"$checkoutResult = 0;" 注意0后面加个分号

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KZvWomEd-1578308868524)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200105112436968.png)]

5.然后继续执行命令:./build_runtime_android.sh (没错,就是不断的修改报错,继续执行,直到成功…),会出现如下提示:failed to run bee

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bn3blVH1-1578308868524)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200105112715825.png)]

分析这个错误,大概意思是说:我们执行编译后,程序要跑一个bee.exe去下载build-deps,这个bee.exe是需要mono来驱动的,但是现在驱动失败了,所以我们要检查自己有没有装mono平台(官网描述:mono是一个软件平台,它允许开发者轻松地创建跨平台的应用程序)

6.检查mono,运行命令:mono --version,查询安装的mono的版本

如果查询不到,那么第3步去下载安装即可;

如果有查询到(Ubuntu中默认安装了一个mono,但可能能还不是最新的),但是还是有此错误,那么可能是mono版本或者安装有问题,少了一些文件,这时保险起见最好先移除现有mono,再按第3步去重新下载安装,卸载命令:

sudo apt-get –purge remove mono-runtime

sudo apt-get autoremove

7.安装完mono后,继续执行命令:./build_runtime_android.sh,执行后会出现如下界面(由于我原来的ndk版本不对,所以才有这个报错):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pMrq7J73-1578308868524)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200105194604911.png)]

提示是说指定路径下找不到android-ndk-r13b,就是说缺少相应的安卓ndk,那么我们去下载r13b的安卓ndk(可以用浏览器下载,一定要选人家要的r13b的版本),按照第5步就可以安装ndk了,

8.软链接。ndk弄好后,由于前面说的指定文件夹找不到ndk,现在ndk安装位置也不在那个位置,所以要链接过去,链接命令:

ln -s ndk根目录 前面报错提示的位置

然后会发现那个文件夹会生成如下这个带箭头的文件夹:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z6WfAaHb-1578308868525)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200106184910038.png)]

然后继续执行命令:./build_runtime_android.sh,之后会有一个报错提示:failing autogenning mono,意思是调用autogen.sh出错了,错误是在build.pl的1363行:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mHpCJSRT-1578308868525)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200105201351748.png)]

还有其他提示是找不到某个路径(忘记截图了),反正查询一番后需要在470行这里修改如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sDxBojSD-1578308868526)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200106170747808.png)]

9.继续执行命令:./build_runtime_android.sh,这次就顺利的编译成功了!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1Evak28D-1578308868526)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200105204652708.png)]

编译成功后生成的.so文件在:mono-unity-2018.4-mbe/builds/embedruntimes/android文件夹下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pjy3p1G1-1578308868527)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200106171739377.png)]

10.替换unity编辑器下的libmonobdwgc-2.0.so

unity编辑器需要替换的目录有两个:

一个Develop版的:Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Development\MonoLibs

一个Release版的:Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\MonoLibs)

其实就是你打包时候有没有勾选Development的问题:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Av6ewkD3-1578308868527)(C:\Users\szgla\AppData\Roaming\Typora\typora-user-images\image-20200106182159148.png)]

**切记:**替换前一定要先备份好MonoLibs文件夹。

然后将刚才编译生成的armv7a和x86里面的"libmonobdwgc-2.0.so"分别替换unity安装目录下对应的 “libmonobdwgc-2.0.so”,切记不要替换反了

切记:不要把生成的文件全部替换过去(libMonoPosixHelper.so不能替换),不然打包出来的apk启动直接报“Failed to load Mono”,用不了,全是泪啊。。。切记切记!

然后就可以打包测试一下自己生成的mono是否能用。

3-1578308868527)]

**切记:**替换前一定要先备份好MonoLibs文件夹。

然后将刚才编译生成的armv7a和x86里面的"libmonobdwgc-2.0.so"分别替换unity安装目录下对应的 “libmonobdwgc-2.0.so”,切记不要替换反了

切记:不要把生成的文件全部替换过去(libMonoPosixHelper.so不能替换),不然打包出来的apk启动直接报“Failed to load Mono”,用不了,全是泪啊。。。切记切记!

然后就可以打包测试一下自己生成的mono是否能用。

总之对于我这种Linux小白来说,编译过程还是相当艰难的,从安装虚拟机、vm到各种编译命令,百度了无数次,也万分感谢我同事路峰的热心指导和帮助,祝大家好运!

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值