前言

因为是车载安卓OS&FW工程师,所以工作中需要通过Android Studio进行源码编写并对安卓源码进行编译,因为刚刚从Web转过来做这个,遇到了很多坑,因此在这里记录一下。

下载安卓源码

我们都知道,安卓是一个开源项目,如果我们希望对安卓系统进行二次开发并编译,首先我们需要对安卓源码进行下载。

环境要求

如果我们希望构建安卓,需要参考Google官方给出的硬件要求。

首先,Google要求如果编译2.3以上版本的安卓系统,需要采用64位的环境。

此外,如果希望对代码进行检出,需要硬盘拥有至少250G的可用空间(实测当前我们公司的项目源码仓库在60G左右),如果需要对其进行编译,则需要另外150G。

其他方面,根据Google官方文档说明,其采用72核64G内存机器完整构建四十分钟,而内存相似的六核机器则需要三个小时,因此当我们进行编译时,最好采用多核心大内存的机器进行编译。

除此之外,在2021年6月以后,Google官方不再支持在Windows与MacOS上对安卓源码进行构建。Google官方推荐使用Ubuntu18.04进行构建。

在这里放出我们公司给每个人的电脑配置:CPU i7-10700(8H16T),内存32G,系统为Ubuntu 20.02 LTS。此环境下采用-j12(12线程编译)完整构建需要六小时左右。

Repo

Google采用Git对安卓源码进行管理,但是由于安卓模块众多,仓库错综复杂,仅靠Git工具并无法满足我们对安卓源码的管理需求,因此Google引入了Repo工具将多个Git仓库进行整合,并通过Gerrit进行代码质量审查。

因此,我们如果希望检出安卓源码,首先,我们需要安装Repo工具。

我们可以采用apt包管理直接对repo进行安装:

sudo apt-get install repo -y

当然,我们也可以采用Google官方提供的方法进行安装:

# 在主目录下创建bin目录并加入环境变量
mkdir ~/bin
PATH=~/bin:$PAT

# 通过curl下载repo工具并保存至bin目录同时赋予权限
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

初始化仓库

安装Repo工具后,我们需要对仓库环境进行初始化

  1. 首先,我们需要创建一个工作目录。这里建议将工作目录创建在大容量挂载磁盘以保证后续代码下载与编译拥有足够的空间。

    mkdir workspace
    cd workspace
  2. 配置Git工具

    # 如果没有Git工具,先安装
    sudo apt-get install git -y
    
    # 配置Git信息,包括用户名与邮箱
    git config --global user.name "username"
    git config --global user.email "name@example.com"
  3. 初始化repo仓库

    # 以下方式将直接检出最新版本的安卓源码
    repo init -u https://android.googlesource.com/platform/manifest
    
    # 或通过-b参数指定分支,具体分支名可以参考在线查看工具
    repo init -u https://android.googlesource.com/platform/manifest -b android-12.1.0_r8

同步源码与其他

当我们完成初始化后,只需要通过repo工具对源码进行同步即可:

repo sync

此过程根据网速不同时间不同,由于源码仓库极为庞大,所以还需耐心等待。

此外,如果遇到网络问题或者希望对官方源码仓库进行提交,请移步官方文档进行查阅。

在线查看安卓源码

如果我们只需要阅读安卓源码,或者获取最新的分支名,可以直接采用Google官方提供的源码阅读工具进行相关工作:Android Code Search

通过Android Studio编写安卓系统源码

一般,我们可以采用Vim、Visual Studio Code等文本编辑工具对安卓项目进行编写,但是,偷懒是人类的天性,我们希望使用更加便捷的工具对源码进行编写,比如idea,比如Android Studio。

我们可以发现,如果我们将同步好的代码仓库直接使用Android Studio打开,会出现大量无法引入,无法跳转,无法自动补齐的情况。这是因为如果我们希望Android Studio识别安卓源码的结构,需要一个类似于sln的总体配置文件,即ipr文件。

因此,我们需要在一切工作开始之间,编译一个ipr项目文件以供Android Studio识别。

  1. 首先,我们需要对编译环境进行准备,请参考下一主题“编译安卓源码”进行配置。

  2. 进行编译前的准备工作

    # 进入repo仓库中的android目录
    cd android
    
    # 链接系统环境设置
    source build/envsetup.sh
  3. 选择编译项目

    # 如果你并不知道需要对哪个项目进行编译,可以采用以下命令,然后根据返回的列表选择。如果你并不知道如何选择,选择第一个即可。
    lunch
    
    # 如果你知道待编译项目的项目名,则可以直接将项目名填入
    lunch project-name
    
    # 或选择项目名对应的序号
    lunch 1
  4. 编译idegen生成安卓项目ipr

    # 编译IDEGEN
    make idegen -j4
  5. 执行生成的脚本

    # 执行IDE生成
    sudo development/tools/idegen/idegen.sh
    
    # 如果出现Java版本报错,则可能在su模式下java版本与要求不符,可尝试以下命令,或安装要求的Java版本并替换原Java版本
    . development/tools/idegen/idegen.sh
  6. 最后,我们使用Android Studio打开在安卓源码目录下的android.ipr项目,此过程在index中可能会十分缓慢,如果无法忍受可以将一下代码加入iml文件:

    <excludeFolder url="file://$MODULE_DIR$/./external/emma"/>
    <excludeFolder url="file://$MODULE_DIR$/./external/jdiff"/>
    <excludeFolder url="file://$MODULE_DIR$/out/eclipse"/>
    <excludeFolder url="file://$MODULE_DIR$/.repo"/>
    <excludeFolder url="file://$MODULE_DIR$/external/bluetooth"/>
    <excludeFolder url="file://$MODULE_DIR$/external/chromium"/>
    <excludeFolder url="file://$MODULE_DIR$/external/icu4c"/>
    <excludeFolder url="file://$MODULE_DIR$/external/webkit"/>
    <excludeFolder url="file://$MODULE_DIR$/frameworks/base/docs"/>
    <excludeFolder url="file://$MODULE_DIR$/out/host"/>
    <excludeFolder url="file://$MODULE_DIR$/out/target/common/docs"/>
    <excludeFolder url="file://$MODULE_DIR$/out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates"/>
    <excludeFolder url="file://$MODULE_DIR$/out/target/product"/>
    <excludeFolder url="file://$MODULE_DIR$/prebuilt"/>
    <excludeFolder url="file://$MODULE_DIR$/./external/emma" />
    <excludeFolder url="file://$MODULE_DIR$/./external/jdiff" />
    <excludeFolder url="file://$MODULE_DIR$/out/eclipse" />
    <excludeFolder url="file://$MODULE_DIR$/.repo" />
    <excludeFolder url="file://$MODULE_DIR$/external/bluetooth" />
    <excludeFolder url="file://$MODULE_DIR$/external/chromium" />
    <excludeFolder url="file://$MODULE_DIR$/external/icu4c" />
    <excludeFolder url="file://$MODULE_DIR$/external/webkit" />
    <excludeFolder url="file://$MODULE_DIR$/frameworks/base/docs" />
    <excludeFolder url="file://$MODULE_DIR$/out/host" />
    <excludeFolder url="file://$MODULE_DIR$/out/target/common/docs" />
    <excludeFolder url="file://$MODULE_DIR$/out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates" />
    <excludeFolder url="file://$MODULE_DIR$/out/target/product" />
    <excludeFolder url="file://$MODULE_DIR$/prebuilt" />
    <excludeFolder url="file://$MODULE_DIR$/art" />
    <excludeFolder url="file://$MODULE_DIR$/bionic" />
    <excludeFolder url="file://$MODULE_DIR$/bootable" />
    <excludeFolder url="file://$MODULE_DIR$/build" />
    <excludeFolder url="file://$MODULE_DIR$/cts" />
    <excludeFolder url="file://$MODULE_DIR$/dalvik" />
    <excludeFolder url="file://$MODULE_DIR$/developers" />
    <excludeFolder url="file://$MODULE_DIR$/development" />
    <excludeFolder url="file://$MODULE_DIR$/device" />
    <excludeFolder url="file://$MODULE_DIR$/docs" />
    <excludeFolder url="file://$MODULE_DIR$/external" />
    <excludeFolder url="file://$MODULE_DIR$/hardware" />
    <excludeFolder url="file://$MODULE_DIR$/kernel" />
    <excludeFolder url="file://$MODULE_DIR$/libcore" />
    <excludeFolder url="file://$MODULE_DIR$/libnativehelper" />
    <excludeFolder url="file://$MODULE_DIR$/out" />
    <excludeFolder url="file://$MODULE_DIR$/pdk" />
    <excludeFolder url="file://$MODULE_DIR$/platform_testing" />
    <excludeFolder url="file://$MODULE_DIR$/prebuilts" />
    <excludeFolder url="file://$MODULE_DIR$/sdk" />
    <excludeFolder url="file://$MODULE_DIR$/system" />
    <excludeFolder url="file://$MODULE_DIR$/test" />
    <excludeFolder url="file://$MODULE_DIR$/toolchain" />
    <excludeFolder url="file://$MODULE_DIR$/tools" />
    <excludeFolder url="file://$MODULE_DIR$/.repo" />

编译安卓源码

完成了对安卓源码的下载后,我们可以对安卓源码进行编译。

环境准备

首先,我们需要安装编译源码所需要的软件,包括:

sudo apt-get install \
libx11-dev:i386 \
libreadline6-dev:i386 \
libncurses5-dev:i386 \
tofrodos \
zlib1g-dev:i386 \
dpkg-dev \
libsdl1.2-dev \
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 \
libgl1-mesa-dev \
libxml2-utils \
xsltproc \
unzip \
m4 \
lib32z-dev \
ccache \
libssl-dev

其中,libesd0-dev不包括在默认仓库中,我们需要在apt仓库中添加:

sudo vim /etc/apt/sources.list

#在末尾加入下方配置
deb http://kr.archive.ubuntu.com/ubuntu/ xenial main universe
deb-src http://kr.archive.ubuntu.com/ubuntu/ xenial main universe

#保存后退出
sudo apt update
sudo apt install libesd0-dev

此外,libncurses5-dev可能也无法安装,需要将最新的版本6.2库文件复制一份作为版本5的库来处理:

cd /usr/lib/x86_64-linux-gnu 
sudo cp libncurses.so.6 libncurses.so.5
sudo cp libtinfo.so.6 libtinfo.so.5

编译准备

然后,进行编译的准备工作,具体于上节编译idegen一致:

# 进入repo仓库中的android目录
cd android

# 链接系统环境设置
source build/envsetup.sh

# 如果你并不知道需要对哪个项目进行编译,可以采用以下命令,然后根据返回的列表选择。如果你并不知道如何选择,选择第一个即可。
lunch

# 如果你知道待编译项目的项目名,则可以直接将项目名填入
lunch project-name

# 或选择项目名对应的序号
lunch 1

编译内核

我们需要在整编之前对安卓内核kernel,即bootimage进行编译

# 编译Kernel,后面的-j参数为线程数,可以参考自己CPU超线程数进行修改
make bootimage -j16

整编

最后,我们只需要通过make对安卓进行整编即可

make -j16

经过漫长的等待,最后编译的结果将会保存在android/out目录下。

本篇内容为原创内容,采用CC BY-NC-SA 4.0协议许可
2022-07-26 22:48
UtopiaXC
于大连


尽管如此,世界依旧美丽