主要参考文章 http://blog.csdn.net/huutu/article/details/50829828
1.安装虚拟机 VirtualBox
2.在虚拟机中安装 Ubuntu ,我安装的是Kylin版
3.安装Git sudo apt-get install git
4.克隆Unity3D Mono源代码 地址 https://github.com/Unity-Technologies/mono.git
5.切换Git分支为你安装的Unity3D对应版本的Mono,我目前用的是5.5
6.Windows中安装WinSCP,以便与虚拟机中Ubuntu互传文件
7.VirtualBox的网络连接方式为桥接网络,主机和虚拟机才能在一个IP段中
8.Ubuntu中安装openssh-server,以便WinSCP能以SFTP协议连接Ubuntu
9.Ubuntu中安装各种软件,根据参考博文为:
- * autoconf
- * automake
- * bison
- * gcc
- * gettext
- * glib >= 2.0
- * libtool
- * make
- * perl
10.把mono源码目录中的external/buildscript/build_runtime_android.sh文件拷贝到mono源码根目录中
11.修改 build_runtime_android.sh Line 113 ,改为:(cd "$KRAIT_PATCH_PATH" && perl ./build.pl)
12.开始编译,根目录执行脚本./build_runtime_android.sh
13.提示ANDROID_NDK_TOOL环境变量设置错误 NDK安装出问题,这一步卡了很久,后来我尝试在ROOT账户下编译,这一步就过去了
14.Ubuntu用ROOT账户登录系统,默认是关闭的,命令行下执行sudo passwd root,设置Root 密码,
15.Root直接登录Ubuntu 编辑/etc/lightdm/lightdm.conf文件,重启Ubuntu,用Root登录
[SeatDefaults]
greeter-session=unity-greeter
user-session=ubuntu
greeter-show-manual-login=true
16.重复12步,报C complier no work
17.编译过程会Git下载android_krait_signal_handler项目,我的下载/home/MyName/文件夹下
18.修改android_krait_signal_handler/jni/Application.mk文件中的TOOLCHAIN_VERSION := clang3.6为TOOLCHAIN_VERSION := 4.8
19.成功
20.编译Release版libmono.so 修改所有的 build_runtime_android.sh 和 build_runtime_android_x86.sh 找到 -fpic -g 去掉 -g
21.打出的so在mono下 builds/embedruntimes/android
22.修改 libmono.so ,增加解密函数,找到 mono/metadata/image.c 这个文件中mono_image_open_from_data_with_name函数
1 mono_image_open_from_data_with_name (char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status, gboolean refonly, const char *name) 2 3 { 4 5 MonoCLIImageInfo *iinfo; 6 7 MonoImage *image; 8 9 char *datac; 10 11 /* 加入 Decrypt */ 12 13 if(name != NULL) 14 15 { 16 17 if(strstr(name,"Assembly-CSharp.dll")){ 18 19 data[0]-=1; //这里注意对应自己的加密方式进行修改。这里是对第一个字节 -1 ,对应加密算法是 +1; 20 21 } 22 23 } 24 25 ……………… 26 27 ……………… 28 29 }
23.替换掉Unity3D中的libmono.so文件,在C:Program FilesUnityEditorDataPlaybackEnginesAndroidPlayerVariationsmono下
24.加密Assembly-CSharp.dll 在Unity3d中导出Android Studio工程之后,对 Assembly-CSharp.dll 进行加密,Unity3d提供了Android工程导出完毕的回调,在这个回调中对Assembly-CSharp.dll加密
BuildPostprocessor.cs :
1 using UnityEngine; 2 using UnityEditor; 3 using UnityEditor.Callbacks; 4 using System.IO; 5 6 public class BuildPostprocessor 7 { 8 [PostProcessBuildAttribute(1)] 9 public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) 10 { 11 if (target == BuildTarget.Android && (!pathToBuiltProject.EndsWith(".apk"))) 12 { 13 Debug.Log("target: " + target.ToString()); 14 Debug.Log("pathToBuiltProject: " + pathToBuiltProject); 15 Debug.Log("productName: " + PlayerSettings.productName); 16 17 string dllPath = pathToBuiltProject + "/" + PlayerSettings.productName + "/" + "src/main/assets/bin/Data/Managed/Assembly-CSharp.dll"; 18 19 if (File.Exists(dllPath)) 20 { 21 //加密 Assembly-CSharp.dll; 22 Debug.Log("Encrypt assets/bin/Data/Managed/Assembly-CSharp.dll Start"); 23 24 byte[] bytes = File.ReadAllBytes(dllPath); 25 bytes[0] += 1; 26 File.WriteAllBytes(dllPath, bytes); 27 28 } 29 else 30 { 31 Debug.LogError(dllPath+ " Not Found!!"); 32 } 33 } 34 } 35 }
25.测试成功