Transmission在Pandorabox(Openwrt)下的交叉编译
本文主要讲述Transmission在Pandorabox(Openwrt)下的交叉编译(基于mipsel架构),编译方式原始,非生成ipk安装包而是直接可运行的二进制执行文件,需要自己手动去链接。
不生成ipk安装包是我自己执行SDK时候没能运行成功make menuconfig,个人愚笨,未能解决。
相关参考:https://blog.whsir.com/post-1229.html
https://github.com/transmission/transmission/wiki/Building-Transmission
所列举的脚本文件已经放于GitHub上 :https://github.com/jsp1256/Transmission_cross_compile
以GitHub上的为最新参考。
一、环境准备
本机编译环境系统为:Ubuntu 16.04.3 LTS 64位。目标机所用系统为pandorabox 17.09,Linux kernel version:3.14.79
SDK:PandoraBox-SDK-ralink-mt7620_gcc-5.4.0_uClibc-1.0.x.Linux-x86_64.tar.xz
目前可用的下载地址:https://pandorabox.leoslion.top/pandorabox/17.11/PandoraBox-SDK-ralink-mt7620_gcc-5.4.0_uClibc-1.0.x.Linux-x86_64.tar.xz (感谢这位好心人)
编译机安装以下依赖,命令如下:
$ sudo apt-get install gcc build-essential automake autoconf m4 libtool
如果要编译nghttp2的依赖,请安装好python
$ sudo apt-get install python
准备流程如下:
新建一个目录用作编译目录,假定该目录为/home/$USER/build,(USER为你的用户名,如果不对请自行修改)
下载并解压好交叉编译工具,配置好相关的环境。
这里提供一个脚本
##prepare.sh ##version:1.1 #检测执行用户 USER=`whoami` #配置全局位置变量 if [ $USER = root ] then $USER_ROOT=/$USER else USER_ROOT=/home/$USER/ fi BUILD_ROOT=$USER_ROOT/build/ BUILD_ROOT_FINISHED=$BUILD_ROOT/finished/ CROSS_COMPILER_STAGING_DIR=$BUILD_ROOT/PandoraBoxSDK/staging_dir/ CROSS_COMPILER_ROOT=$CROSS_COMPILER_STAGING_DIR/toolchain-mipsel_24kec+dsp_gcc-5.4.0_uClibc-1.0.x/bin/ #创建编译工作目录 mkdir $BUILD_ROOT cd $BUILD_ROOT #下载PandoraBoxSDK,得到交叉编译工具链 wget -O PandoraBoxSDK.tar.xz https://pandorabox.leoslion.top/pandorabox/17.11/PandoraBox-SDK-ralink-mt7620_gcc-5.4.0_uClibc-1.0.x.Linux-x86_64.tar.xz tar -xf PandoraBoxSDK.tar.xz mv PandoraBox-SDK-ralink-mt7620_gcc-5.4.0_uClibc-1.0.x.Linux-x86_64 PandoraBoxSDK #写入交叉编译器环境变量到用户环境变量 echo export PATH=\$PATH:$CROSS_COMPILER_ROOT >> $USER_ROOT/.bashrc echo export STAGING_DIR=$CROSS_COMPILER_STAGING_DIR >> $USER_ROOT/.bashrc
在实际编译的时候记得确认用户目录是否正确,判断是否含有.bashrc即可,使用la命令
二、直接编译的部分
本部分依赖不过交叉编译,直接调用本机自带的编译器进行编译和安装。
下面提供标准的编译方法,需要请自行修改。
这里一个脚本,这些脚本具有使用顺序的,建议以我写的顺序依次运行
##compile.sh ##version:1.4 USER=`whoami` USER_ROOT=/$USER BUILD_ROOT=$USER_ROOT/build BUILD_ROOT_FINISHED=$BUILD_ROOT/finished/
#编译使用的线程数 THREAD=1 if [ $USER != root ] then echo 需要root权限执行编译 exit 1 fi mkdir $BUILD_ROOT #编译expat echo 开始编译expat cd $BUILD_ROOT wget http://down.whsir.com/downloads/expat-2.1.0.tar.gz tar zxf expat-2.1.0.tar.gz rm -f expat-2.1.0.tar.gz cd expat-2.1.0 ./configure make -j$THREAD make install cd $BUILD_ROOT mv expat-2.1.0 $BUILD_ROOT_FINISHED/expat-2.1.0 #编译XML-Parser echo 开始编译XML-Parser cd $BUILD_ROOT wget http://down.whsir.com/downloads/XML-Parser-2.44.tar.gz tar zxf XML-Parser-2.44.tar.gz rm -f XML-Parser-2.44.tar.gz cd XML-Parser-2.44 perl Makefile.PL make -j$THREAD make install cd $BUILD_ROOT mv XML-Parser-2.44 $BUILD_ROOT_FINISHED/XML-Parser-2.44 #编译intltool echo 开始编译intltool cd $BUILD_ROOT wget http://down.whsir.com/downloads/intltool-0.51.0.tar.gz tar zxf intltool-0.51.0.tar.gz rm -f intltool-0.51.0.tar.gz cd intltool-0.51.0 ./configure make -j$THREAD make install cd $BUILD_ROOT mv intltool-0.51.0 $BUILD_ROOT_FINISHED/intltool-0.51.0
清理用的脚本,当所有任务完成时候再运行
##compile_clean.sh ##version:1.2 USER=`whoami` USER_ROOT=/$USER BUILD_ROOT=$USER_ROOT/build BUILD_ROOT_FINISHED=$BUILD_ROOT/finished/ #是否执行反安装操作,默认不执行,写1执行 isuninstall=0 if [ $USER != root ] then echo 需要root权限执行清理操作 exit 1 fi if [ isuninstall = 1 ] then echo 执行反安装操作 cd $BUILD_ROOT_FINISHED/expat-2.1.0 make uninstall cd $BUILD_ROOT_FINISHED/XML-Parser-2.44 make uninstall cd $BUILD_ROOT_FINISHED/intltool-0.51.0 make uninstall fi rm -rf $BUILD_ROOT
三、交叉编译的部分
本部分依赖交叉编译,需要调用SDK的交叉编译工具链进行编译,请务必保证环境变量正确且能交叉编译器正常运行
这里提供一个脚本,这些脚本具有使用顺序的,建议以我写的顺序依次运行
##cross_compile.sh ##version:1.5 #检测执行用户 USER=`whoami`
#配置全局位置变量
if [ $USER = root ]
then
$USER_ROOT=/$USER
else USER_ROOT=/home/$USER/
fi BUILD_ROOT=$USER_ROOT/build/ BUILD_ROOT_FINISHED=$BUILD_ROOT/finished/ PACKAGE_DIR=$BUILD_ROOT/package CROSS_COMPILER_STAGING_DIR=$BUILD_ROOT/PandoraBoxSDK/staging_dir/ CROSS_COMPILER_ROOT=$CROSS_COMPILER_STAGING_DIR/toolchain-mipsel_24kec+dsp_gcc-5.4.0_uClibc-1.0.x/bin/ #编译线程数 THREAD=1 #该位置为编译安装位置,如需其他位置,请自行修改 PREFIX=$CROSS_COMPILER_STAGING_DIR/toolchain-mipsel_24kec+dsp_gcc-5.4.0_uClibc-1.0.x/usr/ PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig #PKG_CONFIG_PATH位置的声明 export PKG_CONFIG_PATH=$PKG_CONFIG_PATH #可选编译配置 #写1开启 libssh2=0 nghttp2=0 #编译zlib echo 开始编译zlib cd $BUILD_ROOT wget http://down.whsir.com/downloads/zlib-1.2.11.tar.gz tar zxf zlib-1.2.11.tar.gz rm -f zlib-1.2.11.tar.gz cd zlib-1.2.11 CC=mipsel-openwrt-linux-gcc ./configure --prefix=$PREFIX make -j$THREAD make install cp zlib.h $CROSS_COMPILER_STAGING_DIR/../include cp zconf.h $CROSS_COMPILER_STAGING_DIR/../include cd $BUILD_ROOT mv zlib-1.2.11 $BUILD_ROOT_FINISHED/zlib-1.2.11 #编译openssl echo 开始编译openssl cd $BUILD_ROOT wget https://www.openssl.org/source/openssl-1.1.0h.tar.gz tar zxf openssl-1.1.0h.tar.gz rm -f openssl-1.1.0h.tar.gz cd openssl-1.1.0h ./config no-asm --prefix=$PREFIX #因为原配置文件不能自动配置交叉编译环境,针对交叉编译器修正一些配置 echo 修正Makefile文件 sed -i 's/-m64//g' Makefile sed -i 's/CROSS_COMPILE= /CROSS_COMPILE=mipsel-openwrt-linux-/g' Makefile make -j$THREAD make install cd $BUILD_ROOT mv openssl-1.1.0h $BUILD_ROOT_FINISHED/openssl-1.1.0h #编译libevent echo 开始编译libevent cd $BUILD_ROOT wget http://down.whsir.com/downloads/libevent-2.1.8-stable.tar.gz tar zxf libevent-2.1.8-stable.tar.gz rm-f libevent-2.1.8-stable.tar.gz cd libevent-2.1.8-stable ./configure --host=mipsel-openwrt-linux --disable-samples --prefix=$PREFIX make -j$THREAD make install cd $BUILD_ROOT mv libevent-2.1.8-stable $BUILD_ROOT_FINISHED/libevent-2.1.8-stable #可选:编译libssh2 echo 检查是否编译libssh2 if [ $libssh2 = 1 ] then echo libssh2编译被激活,开始编译libssh2 cd $BUILD_ROOT wget https://www.libssh2.org/download/libssh2-1.8.0.tar.gz tar zxf libssh2-1.8.0.tar.gz rm -f libssh2-1.8.0.tar.gz cd libssh2-1.8.0 CFLAGS="-g -O3" ./configure --host=mipsel-openwrt-linux --prefix=$PREFIX --with-libssl-prefix=$PREFIX --with-libgcrypt-prefix=$PREFIX --with-libz-prefix=$PREFIX make -j$THREAD make install cd $BUILD_ROOT mv libssh2-1.8.0 $BUILD_ROOT_FINISHED/libssh2-1.8.0 else echo libssh2未配置编译,跳过 fi #可选:编译nghttp2 echo 检查是否编译nghttp2 if [ $nghttp2 = 1 ] then echo nghttp2编译被激活,开始编译nghttp2 cd $BUILD_ROOT wget https://github.com/nghttp2/nghttp2/releases/download/v1.32.0/nghttp2-1.32.0.tar.gz tar zxf nghttp2-1.32.0.tar.gz rm -f nghttp2-1.32.0.tar.gz cd nghttp2-1.32.0 CFLAGS="-g -O3" CXXFLAGS="-g -O3" ./configure --host=mipsel-openwrt-linux --prefix=$PREFIX --enable-lib-only make -j$THREAD make install cd $BUILD_ROOT mv nghttp2-1.32.0 $BUILD_ROOT_FINISHED/nghttp2-1.32.0 else echo nghttp2未配置编译,跳过 fi #编译libcurl echo 开始编译libcurl cd $BUILD_ROOT wget http://down.whsir.com/downloads/curl-7.54.0.tar.gz tar zxf curl-7.54.0.tar.gz rm -f curl-7.54.0.tar.gz cd curl-7.54.0
#根据上面可选编译执行的情况,如果选择了libcurl会自动加入libssh2和http2库文件支持 ./configure --host=mipsel-openwrt-linux --prefix=$PREFIX make -j$THREAD make install cd $BUILD_ROOT mv expat-2.1.0 $BUILD_ROOT_FINISHED/expat-2.1.0 #编译Transmission(本次的主角) echo 开始编译Transmission cd $BUILD_ROOT wget http://down.whsir.com/downloads/transmission-2.94.tar.xz tar xf transmission-2.94.tar.xz rm -f transmission-2.94.tar.xz cd transmission-2.94/libtransmission #修正原文件错误的定义,参考<sys/quota.h>修正 echo 依平台修正libtransmission下的platform-quota.c sed -i 's/spaceused = (int64_t) btodb(dq.dqb_curblocks);/spaceused = (int64_t) btodb(dq.dqb_curspace);/g' platform-quota.c cd .. #如果你编译的目标机处理能力不强,请加上--enable-lightweight参数 ./configure --host=mipsel-openwrt-linux --prefix=$PREFIX --enable-nls make -j$THREAD make install cd $BUILD_ROOT mv transmission-2.94 $BUILD_ROOT_FINISHED/transmission-2.94 echo 本脚本执行完成
清理用的脚本,切记当所有任务都完成后再运行,本清理脚本将清理构建目录下所有的文件(连编译器也不放过)
##cross_compile_clean.sh ##version:1.1 USER=`whoami` #配置全局位置变量 #cross_compile.sh使用的哪个用户本次依旧由那个用户调用执行 if [ $USER = root ] then $USER_ROOT=/$USER else USER_ROOT=/home/$USER/ fi BUILD_ROOT=$USER_ROOT/build BUILD_ROOT_FINISHED=$BUILD_ROOT/finished/ CROSS_COMPILER_STAGING_DIR=$BUILD_ROOT/PandoraBoxSDK/staging_dir/ CROSS_COMPILER_ROOT=$CROSS_COMPILER_STAGING_DIR/toolchain-mipsel_24kec+dsp_gcc-5.4.0_uClibc-1.0.x/bin/ rm -rf $BUILD_ROOT #清除环境变量 sed -i 's/export PATH=\$PATH:$CROSS_COMPILER_ROOT//g' .bashrc sed -i 's/export STAGING_DIR=$CROSS_COMPILER_STAGING_DIR//g' .bashrc echo 脚本执行完毕
至此,交叉编译结束,进入安装目录,能够看到编译生成的Transmission可执行文件,将其与相关的依赖库一并放入目标机,设置好即可运行。
四、安装部分
是不是想着要是一步到底最好?
这里提供一个脚本来实现程序打包,默认在build目录下生成一个package.tar.gz文件,配合相应的安装脚本使用。
##make_gzip.sh ##version:1.1 #Transmission Webui设置 #写1表示使用ronggang的webui,写0表示使用原版UI Webui=1 #curl,openssl复制设置 need_curl_openssl=0 #执行用户检测 USER=`whoami`
#配置全局位置变量
if [ $USER = root ]
then
$USER_ROOT=/$USER
else
USER_ROOT=/home/$USER/
fi USER_ROOT=/home/$USER/ BUILD_ROOT=$USER_ROOT/build/ BUILD_ROOT_FINISHED=$BUILD_ROOT/finished/ CROSS_COMPILER_STAGING_DIR=$BUILD_ROOT/PandoraBoxSDK/staging_dir/ CROSS_COMPILER_ROOT=$CROSS_COMPILER_STAGING_DIR/toolchain-mipsel_24kec+dsp_gcc-5.4.0_uClibc-1.0.x/bin/ #编译安装位置相关位置,如前面有修改,请修改下文部分 PREFIX=$CROSS_COMPILER_STAGING_DIR/toolchain-mipsel_24kec+dsp_gcc-5.4.0_uClibc-1.0.x/usr/ PREFIX_EXEC=$PREFIX/bin/ PREFIX_LIB=$PREFIX/lib/ PREFIX_SHARE=$PREFIX/share/ #打包目录位置 PACKAGE_DIR=$BUILD_ROOT/package PACKAGE_DIR_BIN=$BUILD_ROOT/package/bin PACKAGE_DIR_LIB=$BUILD_ROOT/package/lib PACKAGE_DIR_SHARE=$BUILD_ROOT/package/share #创建打包目录 mkdir $PACKAGE_DIR cd $PACKAGE_DIR #复制可执行二进制文件 mkdir $PACKAGE_DIR_BIN cd $PACKAGE_DIR_BIN cp $PREFIX_EXEC/transmission-create . cp $PREFIX_EXEC/transmission-edit . cp $PREFIX_EXEC/transmission-show. cp $PREFIX_EXEC/transmission-daemon . cp $PREFIX_EXEC/transmission-remote . if [ need_curl_openssl = 1 ] then cp $PREFIX_EXEC/curl cp $PREFIX_EXEC/curl-config cp $PREFIX_EXEC/openssl fi #复制相关依赖库 mkdir $PACKAGE_DIR_LIB cd $PACKAGE_DIR_LIB cp $PREFIX_LIB/libcrypto.so.1.1 . cp $PREFIX_LIB/libcurl.so.4.4.0 . cp $PREFIX_LIB/libevent-2.1.so.6.0.2 . cp $PREFIX_LIB/libevent_core-2.1.so.6.0.2 . cp $PREFIX_LIB/libevent_extra-2.1.so.6.0.2 . cp $PREFIX_LIB/libevent_openssl-2.1.so.6.0.2 . cp $PREFIX_LIB/libevent_openssl-2.1.so.6.0.2 . cp $PREFIX_LIB/libevent_pthreads-2.1.so.6.0.2 . #cp $PREFIX_LIB/libexpat.so.1.6.0 . cp $PREFIX_LIB/libssl.so.1.1 . cp $PREFIX_LIB/libz.so.1.2.11 . #复制share mkdir $PACKAGE_DIR_SHARE cd $PACKAGE_DIR_SHARE mkdir man cd man cp -R $PREFIX_SHARE/man/man1 . cd .. mkdir transmission cd transmission echo 检查是否使用新版UI,默认开启 if [ Webui = 1 ] then echo 使用新版UI wget https://github.com/ronggang/transmission-web-control/archive/v1.6.0-alpha.zip unzip v1.6.0-alpha.zip mv transmission-web-control-1.6.0-alpha/src/ web rm -f v1.6.0-alpha.zip rm -rf transmission-web-control-1.6.0-alpha/ else echo 使用原版UI cp -R $PREFIX_SHARE/transmission/web/ . fi #执行打包操作 cd $BUILD_ROOT tar -cvzpf package.tar.gz package
这里提供一个安装脚本,请将package.tar.gz放在与其相同的目录下
##install.sh ##version:1.1 #获取当前的绝对路径 basepath=$(cd `dirname $0`; pwd) #package的绝对路径 PACKAGE_DIR=$basepath/package #默认安装的位置,可自行修改 INSTALL_PATH=/usr INSTALL_EXECPATH=$INSTALL_PATH/bin/ INSTALL_LIBPATH=$INSTALL_PATH/lib/ INSTALL_SHAREPATH=$INSTALL_PATH/share/ ## tar zxf package.tar.gz cd package #创建软连接到程序目录,如果不需要软连接,请去除-s参数 ln -s $PACKAGE_DIR/bin/* $INSTALL_EXECPATH ln -s $PACKAGE_DIR/lib/* $INSTALL_LIBPATH ln -s $PACKAGE_DIR/share/* $INSTALL_SHAREPATH #链接指定版本的库文件 cd $INSTALL_LIBPATH ln -s -f $INSTALL_LIBPATH/libcurl.so.4.4.0 $INSTALL_LIBPATH/libcurl.so.4 ln -s -f $INSTALL_LIBPATH/libevent-2.1.so.6.0.2 $INSTALL_LIBPATH/libevent-2.1.so.6 ln -s -f $INSTALL_LIBPATH/libevent_core-2.1.so.6.0.2 $INSTALL_LIBPATH/libevent_core-2.1.so.6 ln -s -f $INSTALL_LIBPATH/libevent_extra-2.1.so.6.0.2 $INSTALL_LIBPATH/libevent_extra-2.1.so.6 ln -s -f $INSTALL_LIBPATH/libevent_openssl-2.1.so.6.0.2 $INSTALL_LIBPATH/libevent_openssl-2.1.so.6 ln -s -f $INSTALL_LIBPATH/libevent_pthreads-2.1.so.6.0.2 $INSTALL_LIBPATH/libevent_pthreads-2.1.so.6 #ln -s -f $INSTALL_LIBPATH/libexpat.so.1.6.0 $INSTALL_LIBPATH/libexpat.so.1 ln -s -f $INSTALL_LIBPATH/libssl.so.1.1 $INSTALL_LIBPATH/libssl.so.1 ln -s -f $INSTALL_LIBPATH/libz.so.1.2.11 $INSTALL_LIBPATH/libz.so.1 ln -s -f $INSTALL_LIBPATH/libz.so.1.2.11 $INSTALL_LIBPATH/libz.so #修改系统内核配置文件,解决UDP转发缓存区设置失败 echo \#transmission add >> /etc/sysctl.conf echo net.core.rmem_max = 4194304 >> /etc/sysctl.conf echo net.core.wmem_max = 1048576 >> /etc/sysctl.conf
运行完成之后,命令行直接输入transmission-daemon即可运行了
五、资源整合
写了这么多脚本,一个个分开执行会有点麻烦,干脆就弄个汇总的直接来调度它们,但是,本机编译环境因为需要用到root权限所以没有写入该shell脚本中,请先执行,否则后续会报错。
##start.sh ##version:1.3 echo 准备环境 sh prepare.sh res=$? if [ res = 0 ] then echo 环境准备完成 else echo 环境准备失败 exit 1 fi echo 开始交叉编译 sh cross_compile.sh res=$? if[ res = 0 ] then echo 交叉编译完成 else echo 交叉编译失败 exit 1 fi echo 打包程序到package.tar.gz sh make_gzip.sh res=$? if [ res = 0 ] then echo 打包完成 else echo 打包失败 exit 1 fi
最后的安装脚本可没法整合,交叉编译最后一步要到目标机上运行