unity-doc-编译mono热更

建议

  1. 最好切换到root用户进行
  2. 在图形界面进行的网络代理,最好还在图像界面进行命令操作。新开一个ssh控制可能代理没生效。

mono源码修改

下载mono源码

github mono源码地址 https://github.com/Unity-Technologies/mono

一定要下载对应unity版本的mono,不然更新会失败。

例如unity客户端版本unity2019.4.13f1c1下载2019.4 https://github.com/Unity-Technologies/mono/tree/unity-2019.4-mbe

1
2
3
4
5
cd ~
mkdir mono
cd mono
wget https://codeload.github.com/Unity-Technologies/mono/zip/refs/heads/unity-2019.4-mbe
unzip unity-2019.4-mbe

修改mono源码

在加载Assembly-CSharp.dll的地方判断如果加载的字节流名字是Assembly-CSharp.dll就加载你所存的dll,
把该dll的字节流换掉传入的Assembly-CSharp.dll的字节流(记得释放内存)

找到代码mono-unity-2019.4-mbe/mono/metadata/image.c函数mono_image_open_from_data_internal大概1520行左右并进行修改

image.c
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
static char* ReadStringFromFile(const char* pathName,int* size)
{
//g_message("ReadStringFromFile:dllPath(%s)\n", pathName);
FILE *file = fopen(pathName, "rb");
if (file == NULL) {
//g_message("ReadStringFromFile:dllPath(%s) not exists\n", pathName);
return 0;
}

fseek(file, 0, SEEK_END);
int length = ftell(file);
fseek(file, 0, SEEK_SET);
if (length < 0) {
fclose(file);
return 0;
}

*size = length;
char *outData = g_try_malloc(length);
int readLength = fread(outData, 1, length, file);
fclose(file);
if (readLength != length) {
g_free(outData);
return 0;
}

bool USE_DLL_ENCRYPT = true;
if(USE_DLL_ENCRYPT) {
// 使用dll加密
const int BYTE_MAX = 256;
const int AND_VALUE = 51;
const int MOD_VALUE = 33;

int i;
for(i = 0; i < length; i++) {
unsigned char value = *(outData + i);

if ((i & AND_VALUE) > 0) {
int addValue = i % MOD_VALUE;
int dValue = ((int)value - addValue + BYTE_MAX) % BYTE_MAX;
*(outData + i) = (unsigned char)dValue;
}
}
}

//g_message("ReadStringFromFile:dllPath(%s) exists\n", pathName);
return outData;
}


MonoImage *
mono_image_open_from_data_internal (char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status, gboolean refonly, gboolean metadata_only, const char *name)
{
bool USE_DLL_HOT = true;
if(USE_DLL_HOT) {
// 使用dll热更
int datasize = 0;
if (name != NULL && strstr(name, "Assembly-CSharp.dll")) {
// 强制要求程序包名都是:com.xxx.yyy
const char *_pack = strstr(name, "com.");
const char *_pfie = strstr(name, "-");
char _name[512];
memset(_name, 0, 512);
int _len0 = (int)(_pfie - _pack);
memcpy(_name, "/data/data/", 11); //_name = "/data/data/"
memcpy(_name + 11, _pack, _len0); //_name = "/data/data/com.xxx.yyy"
memcpy(_name + 11 + _len0, "/Assembly-CSharp.dll", 20); //_name = "/data/data/com.xxx.yyy/Assembly-CSharp.dll"
//g_message("mono_image_open_from_data_internal:in dllPath(%s) ================ \n", _name);

char *bytes = ReadStringFromFile(_name, &datasize);
if (datasize > 0) {
data = bytes;
data_len = datasize;
}

//g_message("mono_image_open_from_data_internal:in ReadStringfromFile end \n");
}

//g_message("mono_image_open_from_data_internal:out path(%s)\n", name);
}

MonoCLIImageInfo *iinfo;
MonoImage *image;
char *datac;

if (!data || !data_len) {
if (status)
*status = MONO_IMAGE_IMAGE_INVALID;
return NULL;
}

datac = data;
if (need_copy) {
datac = (char *)g_try_malloc (data_len);
if (!datac) {
if (status)
*status = MONO_IMAGE_ERROR_ERRNO;
return NULL;
}
memcpy (datac, data, data_len);
}

if (USE_DLL_HOT) {
// 使用dll热更
if (datasize > 0 && data != 0) {
// 释放读取到内存的dll临时内容
//g_message("mono_image_open_from_data_internal:free dll file info path(%s)\n", name);
g_free(data);
}
}

image = g_new0 (MonoImage, 1);
image->raw_data = datac;
image->raw_data_len = data_len;
image->raw_data_allocated = need_copy;
image->name = (name == NULL) ? g_strdup_printf ("data-%p", datac) : g_strdup(name);
iinfo = g_new0 (MonoCLIImageInfo, 1);
image->image_info = iinfo;
image->ref_only = refonly;
image->metadata_only = metadata_only;
image->ref_count = 1;

image = do_mono_image_load (image, status, TRUE, TRUE);
if (image == NULL)
return NULL;

return register_image (image);
}

编译mono源码

unity 2019.4

ubuntu20.04(Mac parallels)

准备工作
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# mac下载mono 
https://codeload.github.com/Unity-Technologies/mono/zip/refs/heads/unity-2019.4-mbe
# 到主干把bdwgc里面的内容全部down下来然后复制到mono目录mono-unity-2019.4-mbe/external/bdwgc
# 到主干把bdwgc/libatomic_ops里面的内容全部down下来然后复制到mono-unity-2019.4-mbe/external/bdwgc/libatomic_ops

# 切换到root
su root
# 拷贝整理后的mono到 ubuntu 虚拟机

# 安装依赖
apt-get install -y git
apt-get install -y autoconf
apt-get install -y libtool
apt-get install -y automake
apt-get install -y build-essential
apt-get install -y gettext
apt-get install -y cmake
apt-get install -y curl
apt-get install -y libtool-bin
apt-get install -y libncurses*

# 安装python3
# 默认已经安装
python3 --version
whereis python3
ln -s /usr/bin/python3 /usr/bin/python

# 安装openssl
# https://www.openssl.org/source/
wget https://www.openssl.org/source/openssl-3.0.0.tar.gz
tar xzvf openssl-3.0.0.tar.gz
cd openssl-3.0.0
./Configure
make
make install

# 执行 autogen.sh
cd /root/mono/mono-unity-2019.4-mbe/
sh autogen.sh

# 运行结果
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating doc/Makefile
config.status: creating src/Makefile
config.status: creating tests/Makefile
config.status: creating pkgconfig/atomic_ops.pc
config.status: creating pkgconfig/atomic_ops-uninstalled.pc
config.status: creating src/config.h
config.status: src/config.h is unchanged
config.status: executing depfiles commands
config.status: executing libtool commands
config.status: executing default commands

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: system zlib
BTLS: yes (x86_64)


Now type `make' to compile




# 运行结果
=== configuring in external/bdwgc (/root/mono/mono-unity-2019.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: system zlib
BTLS: yes (x86_64)


Now type `make' to compile
# 说明大部分条件已准备好,但是缺失 bdwgc 配置文件,实际 bdwgc 目录是空的。
# 到主干把bdwgc里面的内容全部down下来然后复制进去
cd /root/mono/mono-unity-2019.4-mbe/external/bdwgc
cp -r /root/mono/bdwgc/* ./
# 到主干把bdwgc/libatomic_ops里面的内容全部down下来然后复制进去对应目录
cd libatomic_ops/
cp -r /root/mono/libatomic_ops/* ./

# 安装 mono 如果翻墙了还是太慢,可以重启在试试
# 方法1,速度特别慢,能翻墙推荐
make get-monolite-latest

# 方法2,apt下载 mono-devel 建议使用
# https://www.mono-project.com/download/stable/#download-lin-ubuntu
# Add the Mono repository to your system
apt install gnupg ca-certificates
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb https://download.mono-project.com/repo/ubuntu stable-focal main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list
apt update
# Install Mono
apt install -y mono-devel
# 测试
mono --version
第1次编译
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cd /root/mono/mono-unity-2019.4-mbe/
sh external/buildscripts/build_runtime_android.sh

# 结果
##### ExitCode
134
##### Output
No usable version of the libssl was found
Aborted (core dumped)
[E] DAG generator driver failed: mono --debug bee.exe build --beemode=ToCreateBuildGraph --root-artifacts-path=artifacts --bee-driver-buildprogramroot=.
*** Tundra build failed to setup error (0.38 seconds), 0 items updated

Retry running bee... 10
>>> No external mono found. Trusting a new enough mono is in your PATH.

>>> Building autoconf, texinfo, automake, and libtool if needed...

>>> Android Platform = android-16
>>> Android NDK Version = r16b
>>> Android NDK Destination = /root/mono/mono-unity-2019.4-mbe/external/buildscripts/artifacts/Stevedore/android-ndk-linux-x86_64/android-ndk-r16b

Android NDK not found
Failed building mono for armv7a
第2次编译
1
2
3
4
5
6
7
8
9
10
11
12
13
sh external/buildscripts/build_runtime_android.sh

# 结果
Cloning into '/root/mono/mono-unity-2019.4-mbe/../../android_krait_signal_handler/build'...
fatal: unable to connect to github.com:
github.com[0: ::1]: errno=Connection refused
github.com[1: 127.0.0.1]: errno=Connection refused

failing cloning Krait patch at /root/mono/mono-unity-2019.4-mbe/external/buildscripts/build.pl line 860.
Failed building mono for armv7a

# 设置git
git config --global url."https://".insteadOf git://
第3次编译
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sh external/buildscripts/build_runtime_android.sh

# 结果
**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/mono-unity-2019.4-mbe/external/buildscripts/build.pl line 1264.
Failed building mono for armv7a

# 将usr/bin目录下的libtool、libtoolize两个文件copy到下面的路径(无则新建)
# mono/external/buildscripts/artifacts/Stevedore/built-tools/bin/
cd /root/mono/mono-unity-2019.4-mbe/external/buildscripts/artifacts/Stevedore
mkdir -p built-tools/bin
cd built-tools/bin
cp /usr/bin/libtool ./
cp /use/bin/libtoolize ./
第4次编译
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
sh external/buildscripts/build_runtime_android.sh

# 结果
Making all in samples
make[2]: Entering directory '/root/mono/mono-unity-2019.4-mbe/samples'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/root/mono/mono-unity-2019.4-mbe/samples'
Making all in msvc
make[2]: Entering directory '/root/mono/mono-unity-2019.4-mbe/msvc'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/root/mono/mono-unity-2019.4-mbe/msvc'
Making all in acceptance-tests
make[2]: Entering directory '/root/mono/mono-unity-2019.4-mbe/acceptance-tests'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/root/mono/mono-unity-2019.4-mbe/acceptance-tests'
Making all in llvm
make[2]: Entering directory '/root/mono/mono-unity-2019.4-mbe/llvm'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/root/mono/mono-unity-2019.4-mbe/llvm'
make[2]: Entering directory '/root/mono/mono-unity-2019.4-mbe'
make[2]: Leaving directory '/root/mono/mono-unity-2019.4-mbe'
make[1]: Leaving directory '/root/mono/mono-unity-2019.4-mbe'
>>> 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/mono-unity-2019.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/mono-unity-2019.4-mbe/builds/versions-android-x86.txt
>>> Skipping unit tests

# 编译成功
# 查看生存的库文件
ll builds/embedruntimes/android/armv7a/

drwxr-xr-x 2 root root 4096 Oct 27 00:34 ./
drwxr-xr-x 4 root root 4096 Oct 27 00:38 ../
-rwxr-xr-x 1 root root 16185168 Oct 27 00:34 libmonobdwgc-2.0.so*
-rwxr-xr-x 1 root root 915872 Oct 27 00:34 libMonoPosixHelper.so*
-rwxr-xr-x 1 root root 17898252 Oct 27 00:34 libmonosgen-2.0.so*
debug剥离

正常编译完成的libmonobdwgc-2.0.so文件里面包含的debug信息,所以都是比较大,需要进行strip处理

1
./external/buildscripts/artifacts/Stevedore/android-ndk-linux-x86_64/android-ndk-r16b/toolchains/arm-linux-androideabi-clang/bin/arm-linux-androideabi-strip ./builds/embedruntimes/android/armv7a/libmonobdwgc-2.0.so

unity 2020.3

下载地址:https://codeload.github.com/Unity-Technologies/mono/zip/refs/heads/unity-2020.3-mbe
git地址:https://github.com/Unity-Technologies/mono/tree/2020.3.35f1

ubuntu20.04 (Mac parallels)

准备工作
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

# mac下载mono
https://codeload.github.com/Unity-Technologies/mono/zip/refs/heads/unity-2020.3-mbe
# 到主干把bdwgc里面的内容全部down下来然后复制到mono目录mono-unity-2020.3-mbe/external/bdwgc
https://github.com/Unity-Technologies/bdwgc/tree/75d26f1f022af169645baf33ad776eafa285563e
# 到主干把bdwgc/libatomic_ops里面的内容全部down下来然后复制到mono-unity-2020.3-mbe/external/bdwgc/libatomic_ops
https://github.com/Unity-Technologies/libatomic_ops/tree/7e44a3b8dcf457207d6394e4e52e327189155e4f

# 切换到root
su root
# 拷贝整理后的mono到 ubuntu 虚拟机

# 安装依赖
apt-get install -y git
apt-get install -y autoconf
apt-get install -y libtool
apt-get install -y automake
apt-get install -y build-essential
apt-get install -y gettext
apt-get install -y cmake
apt-get install -y curl
apt-get install -y libtool-bin
apt-get install -y libncurses*

# 安装python3
# 默认已经安装
python3 --version
whereis python3
ln -s /usr/bin/python3 /usr/bin/python

# 安装openssl
# https://www.openssl.org/source/
wget https://www.openssl.org/source/openssl-3.0.0.tar.gz
tar xzvf openssl-3.0.0.tar.gz
cd openssl-3.0.0
./Configure
make
make install

# 执行 autogen.sh
cd /root/mono/mono-unity-2020.3-mbe/
sh autogen.sh

# 运行结果
config.status: executing default commands

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: system zlib
BTLS: yes (x86_64)


Now type `make' to compile

# 安装 mono
# https://www.mono-project.com/download/stable/#download-lin-ubuntu
# Add the Mono repository to your system
apt install gnupg ca-certificates

apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF

echo "deb https://download.mono-project.com/repo/ubuntu stable-focal main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list

apt update
# Install Mono
apt install -y mono-devel
第1次编译
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cd /root/mono/mono-unity-2020.3-mbe/
sh external/buildscripts/build_runtime_android.sh

# 运行结果
>>> Android Platform = android-16
>>> Android NDK Version = r16b
>>> Android NDK Destination = /root/mono/mono-unity-2020.3-mbe/external/buildscripts/artifacts/Stevedore/android-ndk-linux-x86_64/android-ndk-r16b

Android NDK not found
Failed building mono for armv7a

# ndk处理
# https://github.com/android/ndk/wiki/Unsupported-Downloads
# https://dl.google.com/android/repository/android-ndk-r16b-linux-x86_64.zip
cd /root/mono/mono-unity-2020.3-mbe/external/buildscripts/artifacts/Stevedore/android-ndk-linux-x86_64
cp -r /media/psf/Home/data/project/android-ndk-r16b/ ./
第2次编译
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sh external/buildscripts/build_runtime_android.sh

# 运行结果
Cloning into '/root/mono/mono-unity-2020.3-mbe/../../android_krait_signal_handler/build'...
fatal: unable to access 'https://github.com/Unity-Technologies/krait-signal-handler.git/': Failed to connect to github.com port 443: Connection refused
failing cloning Krait patch at /root/mono/mono-unity-2020.3-mbe/external/buildscripts/build.pl line 843.
Failed building mono for armv7a

# 官网下载 krait
# https://github.com/Unity-Technologies/krait-signal-handler
# 下载到 /root/ 目录
# 文件夹改名为build
# 创建目录 android_krait_signal_handler
# 复制 build 到 android_krait_signal_handler
# 完成后目录 ~/android_krait_signal_handler/build
# 注释 external/buildscripts/build.pl line 843.
可能出现错误
1
2
3
4
5
6
7
error while loading shared libraries: libncurses.so.5

# 缺少32位的库
sudo apt install apt-file
sudo apt-file update
sudo apt-file find libncurses.so.5
sudo apt install libncurses5
第3次编译
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sh external/buildscripts/build_runtime_android.sh

# 结果
**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/mono-unity-2020.3-mbe/external/buildscripts/build.pl line 1268.
Failed building mono for armv7a

# 将usr/bin目录下的libtool、libtoolize两个文件copy到下面的路径(无则新建)
# mono/external/buildscripts/artifacts/Stevedore/built-tools/bin/
cd /root/mono/mono-unity-2020.3-mbe/external/buildscripts/artifacts/Stevedore
mkdir -p built-tools/bin
cd built-tools/bin
cp /usr/bin/libtool ./
cp /usr/bin/libtoolize ./
第4次编译
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
sh external/buildscripts/build_runtime_android.sh

# 结果
Making all in llvm
make[2]: Entering directory '/root/mono/mono-unity-2020.3-mbe/llvm'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/root/mono/mono-unity-2020.3-mbe/llvm'
make[2]: Entering directory '/root/mono/mono-unity-2020.3-mbe'
make[2]: Leaving directory '/root/mono/mono-unity-2020.3-mbe'
make[1]: Leaving directory '/root/mono/mono-unity-2020.3-mbe'
>>> Skipping make install. We don't need to run this step when building the runtime on non-desktop platforms.
>>> Creating artifact...
>>> Creating embedruntimes directory : /root/mono/mono-unity-2020.3-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/mono-unity-2020.3-mbe/builds/versions-android-x86.txt
>>> Skipping unit tests

# 编译成功
# 查看生存的库文件
ll builds/embedruntimes/android/armv7a/

drwxr-xr-x 2 root root 4096 Oct 27 00:34 ./
drwxr-xr-x 4 root root 4096 Oct 27 00:38 ../
-rwxr-xr-x 1 root root 16185168 Oct 27 00:34 libmonobdwgc-2.0.so*
-rwxr-xr-x 1 root root 915872 Oct 27 00:34 libMonoPosixHelper.so*
-rwxr-xr-x 1 root root 17898252 Oct 27 00:34 libmonosgen-2.0.so*
debug剥离

正常编译完成的libmonobdwgc-2.0.so文件里面包含的debug信息,所以都是比较大,需要进行strip处理

1
./external/buildscripts/artifacts/Stevedore/android-ndk-linux-x86_64/android-ndk-r16b/toolchains/arm-linux-androideabi-clang/bin/arm-linux-androideabi-strip ./builds/embedruntimes/android/armv7a/libmonobdwgc-2.0.so

测试

java测试代码

AppUtils.java
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
package com.hahafox;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;

import com.unity3d.player.UnityPlayer;

public class AppUtils {
/**
* 获得包名
*
* @return:包名
*/
public static String GetPackageName() {
return UnityPlayer.currentActivity.getPackageName();
}

/**
* 重启app
* */
public static void Reboot() {
ContextWrapper ctx = UnityPlayer.currentActivity;
Intent intent = ctx.getBaseContext().getPackageManager().getLaunchIntentForPackage(ctx.getBaseContext().getPackageName());
PendingIntent restartIntent = PendingIntent.getActivity(ctx.getApplicationContext(), 0, intent,PendingIntent.FLAG_ONE_SHOT);
AlarmManager mgr = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent); // 1秒钟后重启应用
System.exit(0);
}
}

unity测试代码

TestDll.cs
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
using UnityEngine.UI;

public class TestDll : MonoBehaviour
{
private AndroidJavaClass _jc;
private string _pakcageName;
private string _dllPath;

public Text textInfo;
public Text textDebug;

private void Start()
{
_jc = new AndroidJavaClass("com.hahafox.AppUtils");
_pakcageName = _jc.CallStatic<string>("GetPackageName", new object[0]);
_dllPath = "/data/data/" + _pakcageName + "/Assembly-CSharp.dll";
var sb = new StringBuilder();
sb.AppendLine("初始化完成");
sb.AppendLine(string.Format("当前包名:{0}", _pakcageName));
sb.AppendLine(string.Format("DLL存储地址:{0}", _dllPath));
textInfo.text = sb.ToString();
}

public void OnDownButtonClick()
{
Debug.LogError("OnDownButtonClick");
StartCoroutine(DoDllDown());
}

public IEnumerator DoDllDown()
{
using (var www = new WWW("http://nginx1.hahafox.com/Assembly-CSharp.dll"))
{
yield return www;

File.WriteAllBytes(_dllPath, www.bytes);
textInfo.text = "下载DLL完成";
}
}

public void OnCleanButtonClick()
{
Debug.LogError("OnCleanButtonClick");

File.Delete(_dllPath);
textInfo.text = "删除DLL完成";
}

public void OnRebootButtonClick()
{
Debug.LogError("OnRebootButtonClick");
_jc.CallStatic("Reboot", new object[0]);
}

public void OnDebugButtonClick()
{
string tip = "OnDebugButtonClick 哈哈 我是原代码 ??????";
// string tip = "OnDebugButtonClick 哈哈 我是热更代码 ========";
textDebug.text = tip;
Debug.LogError(tip);
}
}

效果图

界面布局图

热更前运行效果图

热更后运行效果图

参考链接

Unity github https://github.com/Unity-Technologies
Ubuntu18.04下编译mono-unity-2019.2-mbe https://blog.csdn.net/ArmyShen/article/details/105102733
Unity Android DLL 热更 http://www.jhonge.com/Home/Single2/1044
Unity5.3.2 dll热更 https://blog.csdn.net/huutu/article/details/58184031
Unity2018.4编译mono https://networm.me/2020/05/10/unity-2018.4-compile-mono/
Mono 官方 https://www.mono-project.com/docs/compiling-mono/linux/