前言
因为各种各样的原因把日用的FreeBSD换成了Arch Linux最近想给手头的闲置手机做SalifishOS的适配,在这之前要验证Android Base的可用性。该手机有CM13.0的官方支持,而在Arch Linux下编译屡屡报错,于是有了本文
查找问题
发现报错
在Arch Linux上编译到一半的我研究发现,报错集中在以下三个方面:
- Python文件语法错误
- 脚本和函数错误
- 带LC字样的C编译错误
追溯本源
Python问题很好解决,Google的程序员不会傻到语法写错都发出去。这些Python文件报错的主要原因几乎全部是Python3与Python2的不兼容
函数错误也是一样。问题在于bash与zsh语法仅部分兼容。因此编译前一定进入bash
脚本错误就有点困难了,因为我们并不知道出问题的是哪个脚本还是Makefile。因此纠错时需要遍历整个源码树寻找错误。不过幸好我遇上的只有Jack的错误。
C编译错误是最奇妙的。解决方案是设置LC_ALL环境变量为C。来源在这里
失败的尝试
折腾了4个小时,尝试过把shebang里的python尽数替换为python2、使用2to3转换Python脚本,最终仍然会报错;使用python2来替换python的可执行文件,也是不可以的。我的系统里有很多用Python3写的软件。
最终因为AUR里的python2-protobuf包无法安装,一切在Arch上编译的方案都被我否决了…
正确的解决方案
问题似乎出在Arch Linux上。最新的软件包似乎不能兼容几年前的编译工具链。因此我安装了一个Ubuntu 16.04。
获取源码树的教程很多文章里都有涉及,这里就不写出来了。
安装编译依赖
sudo apt-get install openjdk-8-jdk git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip maven
# Ubuntu 16.04的仓库里含有Repo工具,但似乎已经不能用了,需要手动安装
降级repo
以上是《失败的尝试》
解决上述问题,将repo切换到旧版本即可。
方法:repo init结束后,进入 .repo/repo 目录,使用 git 切换到旧的提交。我推荐2018年的最后一个提交
git checkout a26c49ead4d4b1fdd71d91ebf997079f7acefc99
# 这个提交在2018-12-12 08:34:28 UTC创建
开始编译前准备
(一定要在bash里配置!)
设置环境
为了确保python脚本执行的是python2,避免一些奇怪的问题,我们需要进入Python虚拟环境。
sudo apt install virtualenv
virtualenv ~/cm-13 #可以随便改,但是建议使用类似cm-13这样的标识
. ~/cm-13/bin/activate #要和上一步对应
然后进入源码树的根目录,使用envsetup.sh来设置环境变量、引入编译函数
. build/envsetup.sh
export LC_ALL=C #重要!
下载设备源码树
仅对官方支持的设备有效!
breakfast nx510j #请把nx510j替换成自己的设备
对于Vendor(厂商驱动),Lineage(以及CM)官方支持的方法是从已经root的原版ROM手机里提取Vendor。我的手机已经刷过别的OS,因此不可以。
当然还有别的方法。比如使用TheMuppets提取好的Vendor。在 项目根目录/.repo/local_manifests/roomservice.xml 添加
<project path="vendor/zte" remote="github" name="TheMuppets/proprietary_vendor_zte" revision="cm-13.0" />
<!-- 根据自己的情况修改,有必要请进入TheMuppets的GitHub主页查看仓库名称和分支 -->
修正Jack编译服务器脚本中的错误
(惭愧,报错的时候我一直以为这个Jack是JACK音频服务器)
jack 和 jack-admin 脚本使用了cURL来和Jack服务器沟通,但使用了错误的curl参数,Google也懒得管已经弃用的东西,就得我们这些用户自己修咯。
编辑 prebuilts/sdk/tools/jack ,将 --no-proxy 改成 --noproxy
- HTTP_CODE=$(curl --fail --silent --data @- --output "$JACK_EXIT" --write-out %{http_code} --connect-timeout 10 --no-proxy 127.0.0.1:$SERVER_PORT_SERVICE http://127.0.0.1:$SERVER_PORT_SERVICE/jack <<< "+ $JACK_OUT $JACK_ERR $JACK_CLI")
+ HTTP_CODE=$(curl --fail --silent --data @- --output "$JACK_EXIT" --write-out %{http_code} --connect-timeout 10 --noproxy 127.0.0.1:$SERVER_PORT_SERVICE http://127.0.0.1:$SERVER_PORT_SERVICE/jack <<< "+ $JACK_OUT $JACK_ERR $JACK_CLI")
编辑 prebuilts/sdk/tools/jack-admin ,将 --no-proxy 改成 --noproxy
- HTTP_CODE=$(curl --fail --silent --output $JACK_EXIT --write-out %{http_code} --connect-timeout 5 --no-proxy 127.0.0.1:$SERVER_PORT_ADMIN http://127.0.0.1:$SERVER_PORT_ADMIN/$CMD)
+ HTTP_CODE=$(curl --fail --silent --output $JACK_EXIT --write-out %{http_code} --connect-timeout 5 --noproxy 127.0.0.1:$SERVER_PORT_ADMIN http://127.0.0.1:$SERVER_PORT_ADMIN/$CMD)
开始编译
个人比较推荐 -j 的参数用4倍物理核心数(大部分cpu,4倍物理核心就是2倍逻辑核心)编译,当然你如果拿不准也可以用 mka 自动设定 -j 的参数(mka设定的是逻辑核心的个数)。
# 手动指定
croot
make -j16 bacon
# mka
mka bacon
看到类似这样的文字就成功了,像我一样电脑不太好的话,编译很费时间。
刷入设备
cout
#一个函数,快速切换到已经用lunch(breakfast函数中自带lunch的引用)设置编译时环境的编译出口
sudo $(which fastboot) flashall -t nx510j
#不知道为什么,不使用root的话platform-tool就无法连接到手机
后记
这次试编译总共废了我两天时间,到现在也没有结束。折腾时间的主要在于修改出错的Python文件、编译Python和OpenSSL等Python问题。不过切换到Ubuntu总归比在Arch下编译方便得多。这次编译让我认识到了当时的应用应该在当时的环境下运行。