编译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 external
cd 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 floats
export ANDROID_PLATFORM=android-9
//这里引导下ndk-r10e的版本路径,如果不引导的话就会报下面的错
export ANDROID_NDK_ROOT=/home/android-ndk-r10e
GCC_PREFIX=arm-linux-androideabi-
//gcc的版本要>=4.8,不然编译会提示找不到gcc或者c无法创建程序及
GCC_VERSION=4.8
//编译完成导出的路径
OUTDIR=builds/embedruntimes/android
CWD="$(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 ]; then
echo "Failed to locate Android NDK; is ANDROID_NDK_ROOT correctly set?" //未能找到ANDROID_NDK_ROOT..... 正是对应前面的引导路径
exit 1
fi
//检查所处的环境
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
;;
esac
PLATFORM_ROOT=$NDK_ROOT/platforms/$ANDROID_PLATFORM/arch-arm
TOOLCHAIN=$NDK_ROOT/toolchains/$GCC_PREFIX$GCC_VERSION/prebuilt/$HOST_ENV
//当我们运行这个类后,会自己调起build_runtime_android_x86.sh
if [ ! -d $TOOLCHAIN ]; then
TOOLCHAIN=${TOOLCHAIN}-x86
if [ ! -d $TOOLCHAIN ]; then
TOOLCHAIN=${TOOLCHAIN}_64
fi
fi
if [ ! -a $TOOLCHAIN -o ! -a $PLATFORM_ROOT ]; then
NDK_NAME=`basename $NDK_ROOT`
echo "Failed to locate toolchain/platform; $NDK_NAME | $HOST_ENV | $GCC_PREFIX$GCC_VERSION | $ANDROID_PLATFORM"
exit 1
fi
//这里要改掉
//原代码为 KRAIT_PATCH_PATH="${CWD}/../../android_krait_signal_handler/build"
//改为 KRAIT_PATCH_PATH="${CWD}/android_krait_signal_handler/build"
//然后这个文件夹就在mono的根目录下了,不过这个是自动从git上下载的,如果电脑没有安装git,还要再apt-get install git
KRAIT_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}ld
AS=$TOOLCHAIN/bin/${GCC_PREFIX}as
AR=$TOOLCHAIN/bin/${GCC_PREFIX}ar
RANLIB=$TOOLCHAIN/bin/${GCC_PREFIX}ranlib
STRIP=$TOOLCHAIN/bin/${GCC_PREFIX}strip
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 -funwind-tables \ //这里需要把g改成02
-ffunction-sections -fdata-sections"
CXXFLAGS=$CFLAGS
CPPFLAGS=$CFLAGS
LDFLAGS="\
-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 builds
fi
function 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 distclean
rm android_cross.cache
pushd eglib
autoreconf -i
popd
autoreconf -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 1
fi
make && echo "Build SUCCESS!" || exit 1 //编译成功之后会在mono根目录的build目录下生成so
mkdir -p $3
cp mono/mini/.libs/libmono.a $3
cp 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 $OUTDIR
clean_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 later
source ${BUILDSCRIPTSDIR}/build_runtime_android_x86.sh dontclean
NUM_LIBS_BUILT=`ls -AlR $OUTDIR | grep libmono | wc -l`
if [ $NUM_LIBS_BUILT -eq 8 ]; then
echo "Android STATIC/SHARED libraries are found here: $OUTDIR"
else
echo "Build failed? Android STATIC/SHARED library cannot be found... Found $NUM_LIBS_BUILT libs under $OUTDIR"
ls -Al $OUTDIR
exit 1
fi
在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... no
configure: error: in `/root/unity/mono-unity-5.3':
configure: error: C compiler cannot create executables
See `config.log' for more details
Configure FAILED!
第二应该是大部分人遇到的问题
如果没有别的意外,到最后便可以看到Build Success!
怎么加密我就不多说了老司机都懂!, 萌新们,可以看下雨凇和陆泽西以及Macgou的帖子
陆泽西重新编译Mono加密dll
雨凇Mono加密教程
U3D加密记事
Unity加密记事1
U3D加密记事2
U3D加密记事3