windows下使用msys2编译unity mono
发表于2017-05-22
第一步:准备工作
1.下载安装msys2
1). 下载地址:http://msys2.github.io/
2). 如果win32:选在下载:msys2_i686_xxxxxxxx.exe
如果win64:选择下载:msys2_x86_64.xxxxxxxx.exe
3).下载完毕后,就直接安装,一路下一步就可以了。
安装好之后,最好在Windows上设置环境变量HOME={msys2安装目录}/home/Administor
这个HOME环境变量在后面会经常用到.
4).运行msys2_shell.cmd
5).更新包和核心系统.输入命令:pacman -Syu
6).关闭Msys2,执行autorebase.bat.
7).重新启动Msys2,对当前系统的所有包进行更新,执行命令:pacman -Su
8).一些pacman的命令:
安装指定包:
pacman -S ..
查询服务器源上的所有包:
pacman -Sl
删除指定包:
pacman -R
9).安装一些必须的工具和包:
pacman -S git make autoconf automake libtool gcc perl zip pkg-config bison
10).如果在上面更新和下载包的时候,老是断开,下载太慢,那么就可以修改源地址.
打开目录:etcpacman.d 发现3个叫mirrorlist的文件.扩展名对应msys,mingw32,mingw64
可以对着三个文件进行修改.
具体可以到地址:http://www.cnblogs.com/pasuka/p/4204427.html
2.下载mono源码:
1).地址:https://github.com/Unity-Technologies/mono
2).在页面上选择Branch,对应Unity版本.我这里选择的Unity5.4 搜索分支的时候使用unity-5.4
3).下载完毕后,我这里直接把源码解压到了$HOME目录.
4).我这里的目录是mono-unity-5.4
3.根据你下载的Mono源码来选择NDK版本.
1).进入mono-unity-5.4/external/buildscripts/build_runtime_android.sh中.在前面几行代码中找到:
perl ${BUILDSCRIPTSDIR}/PrepareAndroidSDK.pl -ndk=r10e -env=envsetup.sh && source envsetup.sh
这样,我就根据他的默认,选择ndk版本为:r10e.
2).然后就是在网上搜索,我是在网盘搜索中找到的.根据你的系选择不同的安装文件:
如果win32:android-ndk-r10e-windows-x86.exe
如果win64:android-ndk-r10e-windows-x86_64.exe
3).下载完毕后,我也直接把它解压到$HOME目录.目录名字: android-ndk-r10e
第二步:修改各种代码中的路径和配置信息.
1).编辑文件:./external/buildscripts/build_runtime_android.sh.
a).在第一行增加一句:export ANDROID_NDK_ROOT=${HOME}/android-ndk-r10e
b).修改KRAIT_PATCH_PATH的定义: KRAIT_PATCH_PATH="${CWD}/external/android_krait_signal_handler"
c).搜索: CCFLAGS_ARMv5_CPU,CCFLAGS_ARMv6_VFP两个变量,把所有关于这两个变量的代码都注释掉.
因为我们只编译针对ARMv7的库,v5,v6都不需要编译了.
d).这里需要注意下,在.sh文件中注释都是用#,而不是双斜杠//.
2).编辑文件:./external/buildscripts/PrepareAndroidSDK.pm
a).查找字符串:(lc $^O eq 'cygwin') 找到判断当前环境的代码:
sub GetAndroidSDK()
{
...
elsif(lc $^O eq 'cygwin')
{
$HOST_ENV = "windows";
$TMP = $ENV{"TMP"};
$HOME = $ENV{"HOME"};
}
...
}
b).增加关于msys的判断.修改为一下代码:
sub GetAndroidSDK()
{
...
elsif(lc $^O eq 'cygwin')
{
$HOST_ENV = "windows";
$TMP = $ENV{"TMP"};
$HOME = $ENV{"HOME"};
}
elsif(lc $^O eq 'msys') //这里增加了msys的判断
{
$HOST_ENV = "windows";
$TMP = $ENV{"TMP"};
$HOME = $ENV{"HOME"};
}
...
}
c).搜索字符串:android-sdk_auto-
找到行: $ENV{$SDK_ROOT_ENV} = catfile($HOME, "android-sdk_auto");
把_auto去掉修改为:
找到行: $ENV{$SDK_ROOT_ENV} = catfile($HOME, "android-sdk");
d).搜索字符串:android-ndk_auto-
找到行:$ENV{$NDK_ROOT_ENV} = catfile($HOME, "android-ndk_auto-" . $ndk);
把_auto去掉修改为:
找到行:$ENV{$NDK_ROOT_ENV} = catfile($HOME, "android-ndk-" . $ndk);
3).把当前目录切换到mono源码的根目录mono-unity-5.4中.
执行脚本:./external/buildscripts/build_runtime_android.sh.
这个脚本执行肯定会出错.
那么既然肯定出错,我们为什么要执行呢?
因为我们需要使用它来下载:android_krait_signal_handler
他被下载到我们之前设置的目录: ./external/buildscripts/ 之下.
4). android_krait_signal_handler作用是为编译android库的一些预备编译工作.
当一个新鲜下载的原装库,能不能直接编译成功呢? 当然...........不行.
在这里你就能感受到这个世界的满满的恶意!!!!!
5).编辑文件:external/android_krait_signal_handler/build.pl
a). 找到第一行 #!/usr/bin/env perl -w
去掉env字符修改为: #!/usr/bin/perl -w
b). 找到行:PrepareAndroidSDK::GetAndroidSDK(undef, undef, "r10e");
这里默认是r10a,就不用修改了,如果是其他就需要重新根据选择ndk版本来设置.
c). 在函数sub ZipIt中找到代码:
system("mkdir -p build/temp/include") && die("Failed to create temp directory.");
//上面的代码意义:创建目录:build/temp/include.
仿照上面的代码,在其下一行中增加代码:
system("mkdir -p obj/local/armeabi/objs/krait-signal-handler") && die("Failed to create obj directory.");
//用于创建目录 obj/local/armeabi/objs/krait-signal-handler
//我这里比较奇怪,如果不创建这些目录,会导致编译是失败.
//很扯的是,即使加上创建目录,也要执行两次perl build.pl才会成功,第一次肯定会失败.
6). 编辑文件:external/android_krait_signal_handler/PrepareAndroidSDK.pm
a).查找字符串:(lc $^O eq 'cygwin') 找到判断当前环境的代码:
sub GetAndroidSDK()
{
...
elsif(lc $^O eq 'cygwin')
{
$HOST_ENV = "windows";
$TMP = $ENV{"TMP"};
$HOME = $ENV{"HOME"};
}
...
}
b).增加关于msys的判断.修改为一下代码:
sub GetAndroidSDK()
{
...
elsif(lc $^O eq 'cygwin')
{
$HOST_ENV = "windows";
$TMP = $ENV{"TMP"};
$HOME = $ENV{"HOME"};
}
elsif(lc $^O eq 'msys')
{
$HOST_ENV = "windows";
$TMP = $ENV{"TMP"};
$HOME = $ENV{"HOME"};
}
...
}
c).搜索字符串:android-sdk_auto-
找到行: $ENV{$SDK_ROOT_ENV} = catfile($HOME, "android-sdk_auto");
把_auto去掉修改为:
找到行: $ENV{$SDK_ROOT_ENV} = catfile($HOME, "android-sdk");
d).搜索字符串:android-ndk_auto-
找到行:$ENV{$NDK_ROOT_ENV} = catfile($HOME, "android-ndk_auto-" . $ndk);
把_auto去掉修改为:
找到行:$ENV{$NDK_ROOT_ENV} = catfile($HOME, "android-ndk-" . $ndk);
7).修改文件:./external/android_krait_signal_handler/jni/Application.mk
找到行: NDK_TOOLCHAIN_VERSION := clang3.6
进行注释: #NDK_TOOLCHAIN_VERSION := clang3.6
因为我们使用NDK的当前默认工具集,不需要特别指定.
8).进入目录./external/android_krait_signal_handler/ 执行命令:
perl build.pl
第一次编译肯定失败.好奇怪,也有可能是我机器的原因.
第二次编译就通过了.OK,这样我们就进入下一步了.
第三步:进入到目录mono-unity-5.4中,执行命令:
.external/buildscripts/build_runtime_android.sh
然后就是漫长的等待.直到出现错误,基本上缺少某个库,通过pacman命令安装所需的库即可.
如果出现configure: error: C compiler cannot create executables:
应该是因为krait_signal_handler这个库没编译好.继续回过头来执行perl build.pl来编译.看具体出错在哪里.
编译结果在目录:./builds/embedruntimes/android 中.
有两个目录armv7a,x86
这里编译的是debug版本.