美文网首页程序员
Mono Android编译步骤

Mono Android编译步骤

作者: 骆驼骑士 | 来源:发表于2020-05-23 15:12 被阅读0次

    本文简要描述在Linux下进行交叉编译Unity 2017.4版本的Android Mono库(libmono.so文件).

    编译环境

    编译环境 centos7.2_CHS_64
    GCC版本 4.8

    Mono版本: Unity_2017.4
    源码地址: https://github.com/Unity-Technologies/mono/tree/unity-2017.4
    源码下载地址: git clone -b unity-2017.4 https://github.com/Unity-Technologies/mono.git

    目录说明: (具体的后续会说明)

    • /root/tmp/mono-android/mono_unity_2017_4/mono // mono源码目录
    • /root/tmp/mono-android/android_ndk/android-ndk-r10e // NDK r10e目录
    • /root/tmp/mono-android/android_ndk/android-ndk-r13b // NDK r13b目录
    • /root/tmp/mono-android/android_krait_signal_handler // krait_signal_handler库目录

    编译Android mono

    在mono根目录运行:

    /external/buildscripts/build_runtime_android.sh
    

    在运行之前, 需要设置一下NDK.

    设置Android NDK

    首先需要说明的是, 在mono的编译脚本里是有自动下载NDK的功能, 由 /external/buildscripts/PrepareAndroidSDK.pm 实现下载不同NDK版本的功能, 但是该脚本经常会出现重复下载的问题, 所以这里是将自动下载的功能给注释掉了, 自己去Android官网下载NDK, 然后将路径定义到环境变量里.

    但在下载NDK之前, 我们必须去知道这个版本的mono需要的ndk版本是多少, 判断的办法有两种:

    1. 直接运行build_runtime_android.sh脚本, 让它去尝试下载, 打印日志里会打印出来它去下载的url地址和ndk版本号
    2. 查看build_runtime_android.sh脚本里, 直接看ndk的版本号, 自己去官网下载对应的ndk版本即可.

    例如在build_runtime_android.sh脚本的最前面, 查看ndk版本后, 将这一行注释掉, 则不会去自动下载ndk:

    #perl ${BUILDSCRIPTSDIR}/PrepareAndroidSDK.pl -ndk=r10e -env=envsetup.sh && source envsetup.sh
    

    可以看到这里需要的ndk版本是 r10e

    这里我们去android官网下去下载ndk版本即可.

    Android NDK版本: r10e
    NDK下载地址: https://dl.google.com/android/repository/android-ndk-r10e-linux-x86.zip
    注意这里不需要64位的版本(但Android官网页面上只有64位的版本下载)

    然后将下载的ndk解压到某个目录, 设置ANDROID_NDK_ROOT环境变量

    export ANDROID_NDK_ROOT=/root/tmp/mono-android/android_ndk/android-ndk-r10e
    

    单独手动编译 android_krait_signal_handler

    mono的编译需要依赖android_krait_signal_handler 这个库, 在其build_runtime_android.sh脚本里会自动去github上下载这个库的代码:

    local KRAIT_PATCH_REPO="<git://github.com/Unity-Technologies/krait-signal-handler.git>"
    

    我们可以自己去下载这个库, 也可以运行 build_runtime_android.sh 让它去下载, 但是它下载完成以后, 在编译这个库的时候是会报错的, 因此需要手动的去修改其中的 build.pl 文件.

    build.pl文件默认会下载到目录对应mono根目录的:

    ../../android_krait_signal_handler
    

    这个文件有两个问题:

    1. 第一行需要修改为本机上的perl路径, 例如我的机器修改为
    #!/usr/bin/perl -w
    
    1. 编译这个库经常需要的并不是编译mono的ndk版本, 例如这里编译mono需要r10e, 但编译android_krait_signal_handler库需要的是r13b
    sub BuildAndroid
    {
        PrepareAndroidSDK::GetAndroidSDK(undef, undef, "r13b");
        system('$ANDROID_NDK_ROOT/ndk-build clean');
        system('$ANDROID_NDK_ROOT/ndk-build');
    }
    

    虽然脚本会去下载Android NDK r13b, 但是因为我们之前设置的 ANDROID_NDK_ROOT 环境变量为r10e的路径, 因此它每次运行的时候都会去重复下载, 并且下载完成依然会使用环境变量里的ndk-build去编译, 版本不对, 所以这个库经常是无法编译成功的, 而导致mono也无法进入编译过程.

    这里我选择的办法是, 手动去官方下载r13b的NDK, 然后手动的去使用r13b的ndk-build去先把这个库给编译好, 然后再使用 build.pl 去打zip包即可.

    NDK r13e的官网下载地址: https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip
    放置到我本机的目录: /root/tmp/mono-android/android_ndk/android-ndk-r13b

    然后再android_krait_signal_handler的build目录(/root/tmp/mono-android/android_krait_signal_handler/build)运行:

    /root/tmp/mono-android/android_ndk/android-ndk-r13b/ndk-build clean
    /root/tmp/mono-android/android_ndk/android-ndk-r13b/ndk-build
    

    如果编译成功, 则可以使用build.pl去打zip包了.

    这里将build.pl的脚本修改一下, 注释掉BuildAndroid函数(因为我们已经自己build好了), 只保留 ZipIt 函数:

    #BuildAndroid();
    ZipIt();
    

    然后在该目录运行一下:

    perl build.pl
    

    正常情况下, 会显示打包成功.

    安装依赖库

    在编译的过程中, 可能会提示缺少一些库, 在这个过程里一般是提示缺少什么就安装什么, 例如我的机器上安装如下的一些库:

    yum install autoconf automake libtool pkg-config
    yum install glib2-devel
    yum install pkgconfig glib2
    yum install libtool bison
    yum install cmake
    yum install libc6-dev
    yum install ld-linux.so.2(yum install glibc)
    yum install zlib
    

    在编译失败的时候查看 config.log 文件, 即可查看具体的错误信息, 一般情况下都是缺少某些库.

    这里有时候会出现奇怪的一个错误就是:

    arm-linux-androideabi-gcc: error: unrecognized option '-V'
    
    
    arm-linux-androideabi-gcc: error: unrecognized option '-qversion'
    

    这里应该是脚本的问题, 因为 arm-linux-androideabi-gcc 查看版本的参数只支持 -v 和 --version, 而不支持 -V, -qversion, 因此这里需要手动修改一下configure脚本:

    #for ac_option in --version -v -V -qversion; do
    for ac_option in --version -v; do
      { { ac_try="$ac_compiler $ac_option >&5"
    case "(($ac_try" in
      *\"* | *\\`* | *\\\\*) ac_try_echo=\$ac_try;;
      *) ac_try_echo=$ac_try;;
    

    将-V -qversion的参数给去掉, 只保留 -v -version

    开始编译:

    依然是在mono根目录运行:

    /external/buildscripts/build_runtime_android.sh
    

    如果没有问题, 则可以看到编译成功, 已经编译好的so文件:

    Build SUCCESS!
    Android STATIC/SHARED libraries are found here: builds/embedruntimes/android
    

    编译好的文件在目录:

    • builds
      • embedruntimes
        • android
          • armv5
          • armv6_vfp
          • armv7a
          • x86

    每个架构下都有编译好的静态库和动态库文件:

    • libmono.a
    • libmono.so

    这里对应的放置到Android的lib目录下即可:

    • lib/armeabi 放置 ARM v5 TE或更高版本(这里对应的armv5或armv6_vfp)
    • lib/armeabi-v7 放置 ARM v7a
    • lib/x86 放置 x86

    NOTE ATTRIBUTES

    Created Date: 2018-07-13 01:44:14
    Last Evernote Update Date: 2020-05-23 07:10:28

    相关文章

      网友评论

        本文标题:Mono Android编译步骤

        本文链接:https://www.haomeiwen.com/subject/lvtlahtx.html