
摘要本文介绍一套用于编译 AOSP 源码的 Docker 环境安装脚本工程。工程以aosp_docker_env_install.sh为入口自动完成 apt 源替换、基础工具安装、Docker 安装与基础镜像构建并调用set_swap.sh扩充 swap 以避免编译时被 OOM 杀掉。镜像构建由Dockerfile.base_ubuntu_1804-v0.5配合install/sources.list阿里源与install/ubuntu_install_core.sh安装编译依赖、OpenJDK 8、Python 及 repo 工具完成。此外还提供run_docker.py脚本用于在宿主机上便捷地创建、启动并进入带目录映射与端口映射的编译容器README.md则给出完整的安装与使用说明。本篇文章主要介绍用于编译 AOSP 代码的 Docker 环境安装脚本工程工程文件树如下所示├── aosp_docker_env_install.sh // env install script ├── Dockerfile.base_ubuntu_1804-v0.5 // docker build dockerfile ├── install // docker build file │ ├── sources.list // modify docker sources list file │ └── ubuntu_install_core.sh // docker install file ├── README.md // readme file ├── run_docker.py // host docker script └── set_swap.sh // host swap modify for android build fail整体架构与流程整个工程围绕「宿主机准备 → 构建基础镜像 → 运行编译容器」三个阶段展开各脚本之间的调用关系如下宿主机 Ubuntu 18.04aosp_docker_env_install.sh替换 apt 源install/sources.list安装基础工具build-essential / vim / curl安装 Dockerget.docker.com 阿里镜像构建基础镜像Dockerfile.base_ubuntu_1804-v0.5ubuntu_install_core.sh编译依赖 / OpenJDK 8 / Python / reposet_swap.sh扩充 4G swap镜像 ubuntu:1804.baserun_docker.py创建或进入容器AOSP 编译容器目录映射 端口映射从职责划分看各文件的分工如下镜像构建侧宿主机侧aosp_docker_env_install.sh一键安装入口set_swap.shswap 扩容run_docker.py容器管理Dockerfile.base_ubuntu_1804-v0.5install/sources.listinstall/ubuntu_install_core.shaosp_docker_env_install.sh: env install script#!/bin/bash # content: this shell script install the docker tools # modify apt src mv /etc/apt/sources.list /etc/apt/sources.list-$(date %Y%m%d-%H%M%S) \ cp ./install/sources.list /etc/apt/sources.list # install basic software tool apt-get update apt install -y --no-install-recommends build-essential \ vim \ curl # config no certificate, this can be remove if the company network 1 # do not have the certificate issue echo insecure ~/.curlrc echo check_certificate off ~/.wgetrc git config --global http.sslVerify false export CURL_CA_BUNDLE # install docker curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun # build docker image sudo docker build -t ubuntu:1804.base -f Dockerfile.base_ubuntu_1804-v0.5 . # add host swap for android build fail error ./set_swap.shDockerfile.base_ubuntu_1804-v0.5: Docker build dockerfile# Pull base image From ubuntu:18.04 LABEL maintainer ARG DEBIAN_FRONTENDnoninteractive COPY install/sources.list /install/sources.list COPY install/ubuntu_install_core.sh /install/ubuntu_install_core.sh RUN bash /install/ubuntu_install_core.sh # Set environment variables. ENV HOME /root # Define working directory. WORKDIR /root # Define default command. CMD [bash]sources.listmodify docker sources list file#添加阿里源 deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverseubuntu_install_core.shDocker install file#!/bin/bash # content: this shell script install the unbuntu base tools of android # modify apt src mv /etc/apt/sources.list /etc/apt/sources.list-$(date %Y%m%d-%H%M%S) \ cp /install/sources.list /etc/apt/sources.list # install basic software tool apt-get update apt install -y --no-install-recommends build-essential \ software-properties-common \ vim \ curl \ ssh \ exuberant-ctags \ subversion \ cmake \ wget \ unzip \ zip \ git \ make \ g \ apt-utils \ tzdata \ net-tools \ inetutils-ping \ rsync # install openjdk apt-get install -y --no-install-recommends openjdk-8-jdk #python ln -s /usr/bin/python3 /usr/bin/python # config no certificate, this can be remove if the company network 1 # do not have the certificate issue echo insecure ~/.curlrc echo check_certificate off ~/.wgetrc git config --global http.sslVerify false export CURL_CA_BUNDLE export PYTHONHTTPSVERIFY0 # repo mkdir ~/bin PATH~/bin:$PATH curl https://storage.googleapis.com/git-repo-downloads/repo ~/bin/repo chmod ax ~/bin/repoREADME.md readme fileAOSP Env SetupThis folder contains the scripts for AOSP Docker environment setup and a Python script for Docker usage.### File list. ├── aosp_docker_env_install.sh // env install script ├── Dockerfile.base_ubuntu_1804-v0.5 // docker build dockerfile ├── install // docker build file │ ├── sources.list // modify docker sources list file │ └── ubuntu_install_core.sh // docker install file ├── README.md // readme file ├── run_docker.py // host docker script └── set_swap.sh // host swap modify for android build fail ### AOSP Docker Build Env Installsudo ./aosp_docker_env_install.sh### Base Docker Image * [ubuntu:18.04](https://registry.hub.docker.com/u/library/ubuntu/) ### Installation Install [Docker](https://www.docker.com/) from the official website, or follow the [Docker installation guide](https://www.runoob.com/docker/ubuntu-docker-install.html) on runoob.com. ### Build sudo docker build -t [docker image tag ] -f [dockerfile] . eg: sudo docker build -t ubuntu:1804.base -f Dockerfile.base_ubuntu_1804 . ### Usagesudo docker run -it ubuntu:1804.base /bin/bash### Python Script: run_docker.pypython3 run_docker.py -husage: run_docker.py [-h] [–cname CNAME] [–iname INAME] [–sdir SDIR] [–ddir DDIR] [–list] [–port PORT]optional arguments:-h, --help show this help message and exit–cname CNAME, -c CNAMEContainer name–iname INAME, -i INAMEDocker images–sdir SDIR, -s SDIR shared dir–ddir DDIR, -d DDIR Docker mount dir about share dir–list, -l list images and containers now–port PORT, -p PORT map host port to docker porteg:python3 run_docker.py -c android-v0.1 -i ubuntu:1804.base## run_docker.pyhost Docker scriptimport argparseimport osimport sysimport subprocessdef main():print(ARGS)if ARGS.list:listcontainer_cmd_str “echo ‘Images:’ sudo docker images echo ‘containers:’ sudo docker ps -a”os.system(listcontainer_cmd_str)elif ARGS.cname and ARGS.cname and ARGS.sdir and ARGS.ddir:container_num_cmd_str “sudo docker ps -a | grep “{}”|wc -l”.format(FLAGS.cname)print(container_num_cmd_str : , container_num_cmd_str)num subprocess.check_output(container_num_cmd_str, shellTrue).decode(‘utf-8’).strip()print(containers num: , num)if num ‘0’:run_cmd_str “sudo docker run -it -p {} --name {} -v {}:{} {} /bin/bash”.format(FLAGS.port, FLAGS.cname, FLAGS.sdir, FLAGS.ddir, FLAGS.iname)print(run_cmd_str : , run_cmd_str)os.system(run_cmd_str)else:start_exec_cmd_str “sudo docker start {} sudo docker exec -ti {} /bin/bash”.format(FLAGS.cname, FLAGS.cname)print(start_exec_cmd_str : , start_exec_cmd_str)os.system(start_exec_cmd_str)else:print(“Bad command !!!”)ifname ‘main’:parser argparse.ArgumentParser()parser.add_argument(‘–cname’, ‘-c’, typestr, help‘Container name ‘)parser.add_argument(’–iname’, ‘-i’, typestr, help‘Docker images ‘)parser.add_argument(’–sdir’, ‘-s’, typestr, default‘/mnt/dev/’, help‘shared dir ‘)parser.add_argument(’–ddir’, ‘-d’, typestr, default‘/home/’, help‘Docker mount dir about share dir ‘)parser.add_argument(’–list’, ‘-l’, action“store_true”, defaultFalse, help list images and containers now)parser.add_argument(‘–port’, ‘-p’, help‘map host port to docker port’)FLAGS, unparsed parser.parse_known_args() ARGS parser.parse_args() main()run_docker.py 的核心逻辑是一个「先查后建」的分支判断容器已存在则启动并进入不存在则新建容器。 mermaid flowchart TD A[解析命令行参数] -- B{是否指定 --list} B --|是| C[打印镜像与容器列表] B --|否| D{cname / sdir / ddir 是否齐全} D --|否| E[输出 Bad command] D --|是| F[统计同名容器数量] F -- G{数量是否为 0} G --|是| H[docker run 新建容器br/挂载目录 端口映射] G --|否| I[docker start docker execbr/进入已有容器] H -- J[进入容器 bash] I -- Jset_swap.sh: host swap modify for Android build fail#!/bin/bash # 建立swap文件 # # android源码编译错误ninja failed with: signal: killed # # 查看目前swap free -m # 建立swap文件,大小4G dd if/dev/zero of/var/swapfile bs1024 count4000000 # 启用虚拟内存,将swap文件设置为swap分区文件 mkswap /var/swapfile #注意insecure permissions 0644, 0600 suggested. chmod 600 /var/swapfile # 激活swap,启用分区交换文件 swapon /var/swapfile # 停用虚拟内存 #swapoff /var/swapfile # 查看内存和虚拟内存 free -m # 开机启用swap echo /var/swapfile swap swap defaults 0 0 /etc/fstab # 查看目前swap free -mset_swap.sh的执行顺序如下核心目的是在物理内存不足时用 swap 兜底避免编译进程被内核 OOM 杀掉。free -m 查看当前 swapdd 创建 4G swapfilemkswap 格式化为 swap 分区文件chmod 600 修正权限swapon 激活 swapfree -m 确认生效写入 /etc/fstab 实现开机自动挂载再次 free -m 校验