利用Docker编译mokee android

Android编译环境的搭建一向不太统一,官方只提供了Ubuntu的搭建方式,Fedora,Archlinux,MacOS的用户大多需要自己摸索编译环境。

Docker虚拟机相比裸机编译,最大的优势就是所有平台方法统一,无论本来的操作系统是什么,配置方法都是一样。

相比于其他虚拟机的方式,轻量级的Docker能够最大限度的利用系统资源,实编译时间与裸机编译差距不大。

1. 硬件需求

本机硬件:i7-7700HD,8G,5400HDD

完整编译米4(cancro)代码和生成文件大约113G,编译过程大概需要227分钟。

完整编译米6(sagit)代码和生成文件大约160G,完整编译时间大约310分钟。

2. 代码同步

下载repo

魔趣使用的repo是自己修改过的,墙内就可以下载mokee代码。github地址:https://github.com/MoKee/git-repo ,压缩包下载地址:repo。

解压后把里面的repo复制到~/bin目录下。

更新repo自己

$ ~/bin/repo selfupdate

同步mokee源码

$ ~/bin/repo init -u https://github.com/MoKee/android -b mkp --depth 1 --platform=auto
$ export MK_AOSP_REMOTE=tuna
$ ~/bin/repo sync

同步的过程非常漫长,而且因为网络不稳定,有中断的可能,repo sync命令可能需要做一些防打断的措施:

$ mysystemnothiscommand;  while [ $? -ne 0 ]; do ~/bin/repo sync --current-branch --force-broken --no-clone-bundle ; done

这里的环境变量MK_AOSP_REMOTE指定了清华的镜像源。其他选项如下:

$ export MK_AOSP_REMOTE=caf (高通镜像)
$ export MK_AOSP_REMOTE=ustc (中国科学技术大学镜像)
$ export MK_AOSP_REMOTE=tuna (清华大学镜像)
$ export MK_AOSP_REMOTE=aosp (Google镜像)

3. 完整编译

这里提供两个方法,archlinux下裸机编译速度会更快一些,缺点是比较复杂,要改动系统文件,方法和别的平台不同用。

另一个是Docker编译,只用输入一行命令,前提是本机已经装上了Docker。

3.1 archlinux下裸机编译

archlinux的包和ubuntu不太一样,需要做点修改:

$ sudo ln -s /usr/bin/python2 /usr/local/bin/python
$ sudo ln -s /usr/lib/libncursesw.so /usr/lib/libtinfo.so.5
$ sudo ln -s /usr/lib/libncurses.so /usr/lib/libncurses.so.5

进入源码目录执行:

$ . build/envsetup.sh
$ lunch mk_cancro-userdebug
$ mka bacon

小米3和小米4的设备名称都是cancro,如果是小米6,就把上面的cancro改成sagit。

首次lunch的时候会同步小米4设备相关的代码,所以如果和之前的步骤不连续,需要再次声明镜像地址,避免repo又去拉Google仓库:

$ export MK_AOSP_REMOTE=tuna

3.2 docker中编译

docker的安装方法请自行求助于搜索引擎。

编译前进入android源码目录编译小米6:

$ docker run --rm -v ${PWD}:/android chenchacha/aosp:latest bash -c "MK_AOSP_REMOTE=tuna; cd /android; . build/envsetup.sh; lunch mk_sagit-userdebug; mka bacon"

sagit是小米6的代号,其他系统请根据设备名称替换。

如果遇到这样的报错:

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

这是Docker没有启动,用systemctl启动docker:

$ systemctl start docker

如果本地没有chenchacha/aosp镜像,docker会在编译前下载。

如果代码是新的,执行lunch的时候也会下载代码,这里用MK_AOSP_REMOTE=tuna指定了清华的镜像源。从其他的镜像地址同步源码可以自行替换。

4. 增量编译

声明生成OTA包的位置:

$ export MK_OTA_TARGET_PATH=~/Templates/MoKee/ota/target
$ export MK_OTA_INPUT=~/Templates/MoKee/ota/target
$ export MK_OTA_EXTRA=~/Templates/MoKee/ota/patch

生成增量包:

$ ota_all UNOFFICIAL dumpling

5. Bug fix

5.1

执行repo sync的时候遇到类似这样的错误:

 repo sync 
remote: Total 0 (delta 0), reused 0 (delta 0), pack-reused 0        
Traceback (most recent call last):
  File "/home/xxx/Workspace/android/mokee/source/.repo/repo/main.py", line 547, in 
    _Main(sys.argv[1:])
  File "/home/xxx/Workspace/android/mokee/source/.repo/repo/main.py", line 522, in _Main
    result = repo._Run(argv) or 0
  File "/home/xxx/Workspace/android/mokee/source/.repo/repo/main.py", line 184, in _Run
    result = cmd.Execute(copts, cargs)
  File "/home/xxx/Workspace/android/mokee/source/.repo/repo/subcmds/sync.py", line 753, in Execute
    if mp.HasChanges:
  File "/home/xxx/Workspace/android/mokee/source/.repo/repo/project.py", line 3076, in HasChanges
    elif self._revlist(not_rev(HEAD), revid):
  File "/home/xxx/Workspace/android/mokee/source/.repo/repo/project.py", line 2619, in _revlist
    return self.work_git.rev_list(*a, **kw)
  File "/home/xxx/Workspace/android/mokee/source/.repo/repo/project.py", line 2819, in rev_list
    (self._project.name, str(args), p.stderr))
error.GitError: manifests rev-list ('^HEAD', u'cba7c060ce06d8befa686c1033d1b5cc8639960c', '--'): error: Could not read 291f1cf611067e09f35494ca5190a88def84ed2d
fatal: revision walk setup failed

这是mokee的manifests变基之后扔了提交导致的。

进入.repo目录,删除下面的manifests目录,重新下载,并把本地分支关联到相应的版本:

$ git https://github.com/MoKee/android.git manifests
$ cd manifests
$ git checkout -b default origin/mkp

5.2

Fetching project platform/external/spirv-llvm
Exception in thread Thread-471:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/home/xxx/Workspace/android/mokee/source/.repo/repo/subcmds/sync.py", line 282, in _FetchProjectList
    success = self._FetchHelper(opt, project, *args, **kwargs)
  File "/home/xxx/Workspace/android/mokee/source/.repo/repo/subcmds/sync.py", line 327, in _FetchHelper
    prune=opt.prune)
  File "/home/xxx/Workspace/android/mokee/source/.repo/repo/project.py", line 1261, in Sync_NetworkHalf
    self._InitGitDir(force_sync=force_sync)
  File "/home/xxx/Workspace/android/mokee/source/.repo/repo/project.py", line 2366, in _InitGitDir
    raise e
GitError: --force-sync not enabled; cannot overwrite a local work tree. If you're comfortable with the possibility of losing the work tree's git metadata, use `repo sync --force-sync external/libpng` to proceed.

这样的错误是xml换了目录名或者库地址。按控制台提示,repo sync的时候加上--force-sync参数:

$ repo sync --force-sync

5.3

编译的过程中有以下报错:

   ERROR: signapk.jar failed: return code 1

ninja: build stopped: subcommand failed.
13:44:04 ninja failed with: exit status 1

往前面还能看到出错的点:

  running:  java -Xmx2048m -Djava.library.path=/home/xxxxcorg.bouncycastle.cms.CMSException: data processing exception: java.io.IOException: No space left on device

以及这样的报错:

FAILED: /home/xxxx/Workspace/android/mokee/source/out/target/product/sagit/mk_sagit-ota-eng.chenchacha.zip 

用IO监控看了看,发现这是/tmp目录太小,打包的时候空间不够导致的。

所以把/tmp目录大小改为10G:

$ mount -o remount,size=10G /tmp/

打包不再报错。

5.4

TWRP刷机的时候报错,显示类似错误:

wrong firmware
...
abort(), ERROR:7

这种错误一般称之为底包不对。我这里应该是小米6的MIUI升级导致TrustZone版本不对,可以去找老一点的稳定版MIUI线刷更新底包,也可以强行刷机。

解压zip文件, 编辑META-INF/com/google/android/updater-script,把其中的abort()函数删除,重新打包成zip。

再用adb刷上去即可。

强行刷机的系统TrustZone异常,指纹不能用,需要后期继续开发。

参考文献

https://bbs.mokeedev.com/t/topic/21

https://bbs.mokeedev.com/t/topic/627

https://bbs.mokeedev.com/t/topic/7806

转载于:https://my.oschina.net/chenchacha/blog/3011667

你可能感兴趣的:(利用Docker编译mokee android)