docker编译grpc docker编译安卓源码_Android


前段时间在medium看到一篇 automotive 通过OBD-II方式同步汽车数据的文章,因服务器已有 android 6.0.1 源码环境,就想着用docker方式来搭建多套共存编译环境,此文章为编译过程小记(同时适用多版本android源码编译)。

1、前言

2017年3月,谷歌发布了google基于AOSP的汽车平台:Automotive,专为车载信息娱乐(IVI)设计。与 Android Auto不同的是:这是一个完整的Android操作系统,并完全在汽车的硬件上运行,而不像后者是采用映射的方式显示在汽车中控大屏上。

Android Automotive 近几年一直发展得不温不火,已量产车型好像只有沃尔沃旗下的独立纯电动高端品牌Polestar 2搭载了此系统,去年的 Google I/O 2019 谷歌也是强推了一把 AAOS,但传统车厂的跟进肯定没那么快,毕竟整体生态的建立与发展是需要应用开发者的支持才行。

2、编译

虽然暂时还没机会试驾Polestar 2,但程序员们可以通过编译 automotive 源码的方式来体验下这个新系统(以下编译过程在 Ubuntu 18.04 LTS 版本上进行)!

  • 先安装依赖

首先,我们需要安装构建所需的工具和软件包:


~$ sudo apt-get install android-tools-adb bc bison build-essential curl flex g++-multilib gcc-multilib git gnupg gperf imagemagick libncurses5 lib32ncurses5-dev lib32readline-dev lib32z1-dev liblz4-tool libncurses5-dev libsdl1.2-dev libssl-dev libwxgtk3.0-gtk3-dev libxml2 libxml2-utils lzop openjdk-8-jdk pngcrush python rsync schedtool squashfs-tools xsltproc yasm zip zlib1g-dev
~$ curl https://storage.googleapis.com/git-repo-downloads/repo > /tmp/repo
~$ chmod a+x /tmp/repo
~$ sudo mv /tmp/repo /usr/bin/repo


  • 获取源代码

Automotive源代码是Android开放源代码项目(AOSP)的一部分。该仓库包含构建 Android Automotive 所需的全部代码。每次Google发布新的Android版本时,AOSP也会更新。本文拉取的是 android 11 的 r9 版本:


~$ mkdir android
~$ cd android
~/android$ repo init --depth 1 -u https://android.googlesource.com/platform/manifest -b android-11.0.0_r9
~/android$ repo sync -j8


根据网速差不要 5 小时左右,下载代码大概 100G 左右,编译后大概在 220G 左右,各位同学留足磁盘空间!

  • 编译Android Automotive

运行如下命令开始构建(和普通AOSP构建步骤相同,只是 lunch 参数不同):


~/android$ source build/envsetup.sh
~/android$ lunch aosp_car_x86_64-userdebug
~/android$ m


编译大概2个小时(i7 8核的时间,供参考),然后就可以愉快地打开模块器了:


~/android$ emulator


docker编译grpc docker编译安卓源码_docker编译grpc_02

Automotive 主界面,是不是有点太简洁了?!


docker编译grpc docker编译安卓源码_docker_03

支持的应用还是有点少啊

3、Docker容器

写到这里,差不多一篇《Automotive编译小记》已完成,不想了解docker的同学可以默默关闭本页面了,哈哈!如果你有如下需求:

  1. 想在一台机器内下载、编译不同android版本的AOSP源码
  2. 想学习下docker容器技术

那我们就接着往下看吧!

docker-aosp

因为编译 automotive 前,服务器上已经有一份android 6.0.1 源码,且 6.0.1 源码编译环境依赖的软件和 automotive android 11.0 不同,就想起后台最近用起来的docker容器技术,google一搜索,就发现了 docker-aosp 这个项目。

编译过程非常简单:


mkdir nougat ; cd nougat
export AOSP_VOL=$PWD
curl -O https://raw.githubusercontent.com/kylemanna/docker-aosp/master/tests/build-nougat.sh
bash ./build-nougat.sh


上述脚本的功能解析如下:

  1. git clone docker-aosp 到指定目录(假设为:/home/xxx/docker-aosp)
  2. 创建一个目录(假设为:/home/xxx/nougat),docker-aosp会在这个目录下创建 aosp / ccache 目录(同时映射到docker的 /aosp 及 /tmp/ccache目录)
  3. 把 docker-aosp 项目 tests 目录下的对应 android 版本的脚本(7.0 => build-nougat.sh)复制过来
  4. 切换到 su 用户:sudo su (docker容器需要 root 权限)
  5. 设置环境变量 AOSP_VOL 为当前目录(不设置则默认 ~/aosp-root 目录)
  6. 设置环境变量 AOSP_BIN 为 /home/xxx/docker-aosp/utils/aosp (可选,目的是可调试这个脚本)
  7. 执行:bash ./build-nougat.sh,调用后会下载 7.0 源码并编译(第一个 if 后的语句)
#!/bin/bash
#
# Test script file that maps itself into a docker container and runs
#
# Example invocation:
#
# $ AOSP_VOL=$PWD/build ./build-nougat.sh
#
set -ex

if [ "$1" = "docker" ]; then
    TEST_BRANCH=${TEST_BRANCH:-android-7.0.0_r14}
    TEST_URL=${TEST_URL:-https://android.googlesource.com/platform/manifest}

    cpus=$(grep ^processor /proc/cpuinfo | wc -l)

    repo init --depth 1 -u "$TEST_URL" -b "$TEST_BRANCH"

    # Use default sync '-j' value embedded in manifest file to be polite
    repo sync

    prebuilts/misc/linux-x86/ccache/ccache -M 10G

    source build/envsetup.sh
    lunch aosp_arm-eng
    make -j $cpus
else
    aosp_url="https://raw.githubusercontent.com/kylemanna/docker-aosp/master/utils/aosp"
    args="bash run.sh docker"
    export AOSP_EXTRA_ARGS="-v $(cd $(dirname $0) && pwd -P)/$(basename $0):/usr/local/bin/run.sh:ro"
    export AOSP_IMAGE="kylemanna/aosp:7.0-nougat"

    #
    # Try to invoke the aosp wrapper with the following priority:
    #
    # 1. If AOSP_BIN is set, use that
    # 2. If aosp is found in the shell $PATH
    # 3. Grab it from the web
    #
    if [ -n "$AOSP_BIN" ]; then
        $AOSP_BIN $args
    elif [ -x "../utils/aosp" ]; then
        ../utils/aosp $args
    elif [ -n "$(type -P aosp)" ]; then
        aosp $args
    else
        if [ -n "$(type -P curl)" ]; then
            bash <(curl -s $aosp_url) $args
        elif [ -n "$(type -P wget)" ]; then
            bash <(wget -q $aosp_url -O -) $args
        else
            echo "Unable to run the aosp binary"
        fi
    fi
fi


适配 automotive

因为这个项目最高只测试到了 android 7.0,所以对项目做了如下适配:

  1. 改动源码根目录下的 Dockerfile,将系统切换为 ubuntu 18.04 LTS 版本
  2. 在 tests 目录加入适配文件:build-automotive.sh
  3. 将 TEST_BRANCH 改为想编译的 android 版本,如:android-11.0.0_r17
  4. 将 AOSP_IMAGE 改为:kylemanna/aosp:10.0-automotive
  5. 在源码根目录执行:sudo docker build -t kylemanna/aosp:10.0-automotive .(因为原作者提交的最新 tag为 7.0-naugat,所以需要自行生成本地镜像)
  6. 再按照 docker-aosp 的步骤设置好 AOSP_VOL/BIN并可以开始愉快地拉代码并编译 automotive 了

如有问题,可参考作者 fork 的 docker-aosp 仓库,里面已经适配好了 android 8.1.0 oreo及 10.0 的 automotive 编译,同时加入了编译X11支持及自动启动模拟器的功能。

为google设备编译ROM

为 google 设备编译 ROM 其实和编译 AOSP 源码没有太大的区别,只不过要找好版本及对应的 vendor 驱动即可。比如要为 Pixel 2 XL 编译 8.1.0 版本,在 android 提供的设备版本号页面找到设备及对应版本的 build number:

代号、标记和 Build 号 | Android 开源项目 | Android Open Source Projectsource.android.google.cn

docker编译grpc docker编译安卓源码_docker源码编译 linux_04


从上图可以看到,Pixel 2 XL 支持的 android 8.1.0 最后的版本为 android-8.1.0_r40,build NO 为:OPM4.171019.021.R1,再到 android 设备驱动下载页面下载对应驱动文件即可:

https://developers.google.com/android/driversdevelopers.google.com


docker编译grpc docker编译安卓源码_docker编译grpc_05


下载得到两个 tgz 文件,放在 aosp 目录并执行,会将厂商闭源的驱动文件释放在 vendor 目录,lunch 选择对应的设备的代码再编译,即可得到可刷入手机的 img 文件,这些步骤笔者就不再赘述了。