编译mono5.3的步骤和坑

来源:互联网 发布:网络增值业务推广方案 编辑:程序博客网 时间:2024/06/05 20:58

编译mono是为了做unity3d游戏的dll加密

推荐在ubuntu下编译,windows上坑太多了而且搜不到几个有用的文章于是就放弃了

我在腾讯上架设的一个ubuntu16.04 64位的虚拟机

首先安装图形界面 说起了ubuntu的apt-get是一个很不错的东西,缺什么apt-get install xxx 然后输入y(yes)回车就ok

登录这个不用多说哈,然后给root用户添加一个固定密码,目前还木有安装图形化界面,都在终端操作

sudo passwd root

给root设置好密码之后呢开始装图形界面,我用的是gnome

首先在终端输入

sudo apt-get install gnome-session-flashback
然后y确认安装,装好之后呢切root用户,切的时候在终端su一下就ok

然后输入重启命令

reboot now

重启后就可以看到让人稀罕的图形界面了

然后输入用户名和密码登陆

    好了现在打开火狐浏览器

去mono的github下载相应的版本https://github.com/Unity-Technologies/mono

首先第一个坑:找不到准确与unity版本对应的mono

例如我的unity是5.3.4 mono版本却只有5.3 ,于是就拿5.3的编译

下载下来之后我们先解压,然后打开mono-unity-5.3/external/buildscripts中的build_runtime_android.sh


然后我们去下载r10e版的ndk切记要选r10e版本  ndk下载地址

等下载完了之后我们先把ndk解压出来

然后在终端输入

gedit .hashrc
然后在最下面加上自己ndk的路径

这里一定要填ANDROID_NDK_ROOT要不mono会找不到

之后在终端输入

source gedit .hashrc
即时生效我们所配置的变量,然后切到任意目录下测试下是否配置成功


然后我们通过终端安装所需的软件 autoconf automake libtool pkg-config  (输入sudo apt-get install softwarename即可)

安装完了之后,我们切入到unity-mono-5.3的文件夹

执行

./autogen.sh
来cheking下我们的mono中的文件和软件是否安装全了,如果提示没有xxx软件 就用apt-get install 安装

完成这一步之后在终端输入命令进入到builds文件夹

cd externalcd builds
然后把目录中的build_runtime_android.sh打开,引导一下ndk的路径,然后修改编译的版本(debug/正式)和编译的类型(armeabi-v7a/x86,编译的时候只要这两个)

首先我们来分析下这个代码的作用,这样后面遇到坑起码思绪不会特别乱

#!/bin/bash# NB! Prereq : ANDROID_NDK_ROOT=/usr/local/android-ndk-xxx or similar# Todo: set appropriate ARM flags for hard floatsexport ANDROID_PLATFORM=android-9//这里引导下ndk-r10e的版本路径,如果不引导的话就会报下面的错export ANDROID_NDK_ROOT=/home/android-ndk-r10eGCC_PREFIX=arm-linux-androideabi-//gcc的版本要>=4.8,不然编译会提示找不到gcc或者c无法创建程序及GCC_VERSION=4.8//编译完成导出的路径OUTDIR=builds/embedruntimes/androidCWD="$(pwd)"PREFIX="$CWD/builds/android"//build代码路径BUILDSCRIPTSDIR=external/buildscripts//会把ndk的路径存到envsetup.sh里,如果这个文件丢失可以手动建一个,里面放入export ANDROID_NDK_ROOT=/home/android-ndk-r10e即可perl ${BUILDSCRIPTSDIR}/PrepareAndroidSDK.pl -ndk=r10e -env=envsetup.sh && source envsetup.sh//根据ndk路径验证ndk是否存在NDK_ROOT=`cd $ANDROID_NDK_ROOT && pwd`if [ ! -f $NDK_ROOT/GNUmakefile ]; thenecho "Failed to locate Android NDK; is ANDROID_NDK_ROOT correctly set?" //未能找到ANDROID_NDK_ROOT..... 正是对应前面的引导路径exit 1fi//检查所处的环境HOST_ENV=`uname -s`case "$HOST_ENV" in    Darwin)        HOST_ENV=darwin        ;;    Linux)        HOST_ENV=linux        ;;    CYGWIN*|*_NT-*)        HOST_ENV=windows        ;;*)echo "Failed to locate supported host environment; HOST_ENV = $HOST_ENV ..."exit 1;;esacPLATFORM_ROOT=$NDK_ROOT/platforms/$ANDROID_PLATFORM/arch-armTOOLCHAIN=$NDK_ROOT/toolchains/$GCC_PREFIX$GCC_VERSION/prebuilt/$HOST_ENV//当我们运行这个类后,会自己调起build_runtime_android_x86.shif [ ! -d $TOOLCHAIN ]; thenTOOLCHAIN=${TOOLCHAIN}-x86if [ ! -d $TOOLCHAIN ]; thenTOOLCHAIN=${TOOLCHAIN}_64fifiif [ ! -a $TOOLCHAIN -o ! -a $PLATFORM_ROOT ]; thenNDK_NAME=`basename $NDK_ROOT`echo "Failed to locate toolchain/platform; $NDK_NAME | $HOST_ENV | $GCC_PREFIX$GCC_VERSION | $ANDROID_PLATFORM"exit 1fi//这里要改掉//原代码为 KRAIT_PATCH_PATH="${CWD}/../../android_krait_signal_handler/build" //改为 KRAIT_PATCH_PATH="${CWD}/android_krait_signal_handler/build" //然后这个文件夹就在mono的根目录下了,不过这个是自动从git上下载的,如果电脑没有安装git,还要再apt-get install gitKRAIT_PATCH_PATH="${CWD}/../../android_krait_signal_handler/build"PATH="$TOOLCHAIN/bin:$PATH"CC="$TOOLCHAIN/bin/${GCC_PREFIX}gcc --sysroot=$PLATFORM_ROOT"CXX="$TOOLCHAIN/bin/${GCC_PREFIX}g++ --sysroot=$PLATFORM_ROOT"CPP="$TOOLCHAIN/bin/${GCC_PREFIX}cpp"CXXCPP="$TOOLCHAIN/bin/${GCC_PREFIX}cpp"CPATH="$PLATFORM_ROOT/usr/include"LD=$TOOLCHAIN/bin/${GCC_PREFIX}ldAS=$TOOLCHAIN/bin/${GCC_PREFIX}asAR=$TOOLCHAIN/bin/${GCC_PREFIX}arRANLIB=$TOOLCHAIN/bin/${GCC_PREFIX}ranlibSTRIP=$TOOLCHAIN/bin/${GCC_PREFIX}stripCFLAGS="\-DANDROID -DPLATFORM_ANDROID -DLINUX -D__linux__ \-DHAVE_USR_INCLUDE_MALLOC_H -DPAGE_SIZE=0x1000 \-D_POSIX_PATH_MAX=256 -DS_IWRITE=S_IWUSR \-DHAVE_PTHREAD_MUTEX_TIMEDLOCK \-fpic -g -funwind-tables \    //这里需要把g改成02-ffunction-sections -fdata-sections"CXXFLAGS=$CFLAGSCPPFLAGS=$CFLAGSLDFLAGS="\-Wl,--wrap,sigaction \-L${KRAIT_PATCH_PATH}/obj/local/armeabi -lkrait-signal-handler \-Wl,--no-undefined \-Wl,--gc-sections \-Wl,-rpath-link=$PLATFORM_ROOT/usr/lib \-ldl -lm -llog -lc"CONFIG_OPTS="\--prefix=$PREFIX \--cache-file=android_cross.cache \--host=arm-eabi-linux \--disable-mcs-build \--disable-parallel-mark \--disable-shared-handles \--with-sigaltstack=no \--with-tls=pthread \--with-glib=embedded \--enable-nls=no \mono_cv_uscore=yes"if [ ${UNITY_THISISABUILDMACHINE:+1} ]; then        echo "Erasing builds folder to make sure we start with a clean slate"        rm -rf buildsfifunction clean_build_krait_patch{//从git上现在krait-signal-handler       local KRAIT_PATCH_REPO="git://github.com/Unity-Technologies/krait-signal-handler.git"       if [ ${UNITY_THISISABUILDMACHINE:+1} ]; then               echo "Trusting TC to have cloned krait patch repository for us"       elif [ -d "$KRAIT_PATCH_PATH" ]; then               echo "Krait patch repository already cloned" //如果存在,就提示已经克隆下来了       else               git clone --branch "master" "$KRAIT_PATCH_REPO" "$KRAIT_PATCH_PATH"       fi       (cd "$KRAIT_PATCH_PATH" && ./build.pl)}function clean_build{make clean && make distcleanrm android_cross.cachepushd eglibautoreconf -ipopdautoreconf -i./configure $CONFIG_OPTS \PATH="$PATH" CC="$CC" CXX="$CXX" CPP="$CPP" CXXCPP="$CXXCPP" \CFLAGS="$CFLAGS $1" CPPFLAGS="$CPPFLAGS $1" CXXFLAGS="$CXXFLAGS $1" LDFLAGS="$LDFLAGS $2" \LD=$LD AR=$AR AS=$AS RANLIB=$RANLIB STRIP=$STRIP CPATH="$CPATH"if [ "$?" -ne "0" ]; then echo "Configure FAILED!" //编译失败,., 会显示出产生的错误exit 1fimake && echo "Build SUCCESS!" || exit 1 //编译成功之后会在mono根目录的build目录下生成somkdir -p $3cp mono/mini/.libs/libmono.a $3cp mono/mini/.libs/libmono.so $3}CCFLAGS_ARMv5_CPU="-DARM_FPU_NONE=1 -march=armv5te -mtune=xscale -msoft-float"CCFLAGS_ARMv6_VFP="-DARM_FPU_VFP=1  -march=armv6 -mtune=xscale -msoft-float -mfloat-abi=softfp -mfpu=vfp -DHAVE_ARMV6=1"CCFLAGS_ARMv7_VFP="-DARM_FPU_VFP=1  -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -DHAVE_ARMV6=1"LDFLAGS_ARMv5=""LDFLAGS_ARMv7="-Wl,--fix-cortex-a8"rm -rf $OUTDIRclean_build_krait_patch//这里要注释掉,否则编译速度会慢很多,而且我们只是需要armv7a和x86版本的so//clean_build "$CCFLAGS_ARMv5_CPU" "$LDFLAGS_ARMv5" "$OUTDIR/armv5"//clean_build "$CCFLAGS_ARMv6_VFP" "$LDFLAGS_ARMv5" "$OUTDIR/armv6_vfp"clean_build "$CCFLAGS_ARMv7_VFP" "$LDFLAGS_ARMv7" "$OUTDIR/armv7a"# works only with ndk-r6b and latersource ${BUILDSCRIPTSDIR}/build_runtime_android_x86.sh dontcleanNUM_LIBS_BUILT=`ls -AlR $OUTDIR | grep libmono | wc -l`if [ $NUM_LIBS_BUILT -eq 8 ]; thenecho "Android STATIC/SHARED libraries are found here: $OUTDIR"elseecho "Build failed? Android STATIC/SHARED library cannot be found... Found $NUM_LIBS_BUILT libs under $OUTDIR"ls -Al $OUTDIRexit 1fi



在x86的文章中只去掉-g就ok

CFLAGS="\-DANDROID -DPLATFORM_ANDROID -DLINUX -D__linux__ \-DHAVE_USR_INCLUDE_MALLOC_H -DPAGE_SIZE=0x1000 \-D_POSIX_PATH_MAX=256 -DS_IWRITE=S_IWUSR \-DHAVE_PTHREAD_MUTEX_TIMEDLOCK \-fpic -g \   //-g去掉-ffunction-sections -fdata-sections"

然后打开PrepareAndroidSDK.pm,修改掉里头的验证,如果不改的话,会出现mono识别不出来r10e版的ndk从而编译一次下载一次炒鸡麻烦!!



我们需要把这个改成

my @curr_arr=split(/\-|\s/,$current);  这样mono就认得r10e版本的ndk了

之后把build_runtime_android.sh拽到终端运行,如果提示xxx permission就先输入sudo然后在把文件拽过去运行

然后打开我们后面git下载的目录


替换完了之后,我们打开build.pl


如果直接运行可能会报这两个错

第一是

BEGIN failed--compilation aborted at external/buildscripts/PrepareAndroidSDK.pl line 10./usr/bin/env: perl -w: No such file or directory
第二是
checking whether the C compiler works... noconfigure: error: in `/root/unity/mono-unity-5.3':configure: error: C compiler cannot create executablesSee `config.log' for more detailsConfigure FAILED!
第二应该是大部分人遇到的问题

所以要在这里修改好

如果没有别的意外,到最后便可以看到Build Success!

怎么加密我就不多说了老司机都懂!, 萌新们,可以看下雨凇和陆泽西以及Macgou的帖子

陆泽西重新编译Mono加密dll

雨凇Mono加密教程

U3D加密记事

Unity加密记事1

U3D加密记事2

U3D加密记事3