相关资料

清华大学开源软件镜像站 https://mirrors.tuna.tsinghua.edu.cn/help/AOSP/
官方源码下载文档https://source.android.com/setup/downloading
repo命令参考资料 https://source.android.com/setup/using-repo.html

下载android 源码

首先下载repo 工具

mkdir ~/bin
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

下载初始化包

wget -c https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar # 下载初始化包
tar xf aosp-latest.tar
cd AOSP   # 解压得到的 AOSP 工程目录
# 这时 ls 的话什么也看不到,因为只有一个隐藏的 .repo 目录
repo sync # 正常同步一遍即可得到完整目录
# 或 repo sync -l 仅checkout代码

需要安装python环境和git环境,需要注意一下之前下载repo使用工作站的方式死活访问不了无法同步代码(中科大和清华镜像),隔了一天就可以访问了,有点迷,还是使用每月初始化包解决问题,解压之后配置repo环境变量,然后在解压出来的aosp源码里面切换分支 repo init -b android-6.0.1_r81,可以检查一下.repo里面的 manifest文件是否成功修改,然后回到源码目录执行 repo sync

常用命令

  • 查看某个目录的大小 du -sh aosp/

  • 想查看当前可用的Android源码分支和版本,也可以在下载好的Android源码根目录下执行如下命令

$ cd .repo/manifests
$ git branch -a | cut -d / -f 3
或者

$ git --git-dir .repo/manifests/.git/ branch -a
  • 如果你想切换到其他Android分支,只需要重新执行 repo init 和 repo sync 即可
$ repo init -b android-4.2.2_r1 
$ repo sync
  • 查看android分支版本号也就是可切换的分支(在aosp源码目录)

git --git-dir .repo/manifests/.git/ branch -a

  • 安卓源码目录切换分支
repo init -b android-5.1.1_r1
repo sync (not needed if your local copy is up to date)
repo start android-5.1.1_r1 --all 
  • repo 版本切换以android-6.0.1_r8为例
 repo init -u https://android.googlesource.com/platform/manifest

 repo sync 之后

 这样初始化之后,相当于下载了全部的分支,

 本想编译源码烧录到手机Nexus 5,编译时才发现找不到aosp_hammerhead_userdebug,毕竟nexus5明确不支持android-7.0

 那么如何切换成自己想要的分支

 #查看可切换的分支 (推荐)
 cd .repo/manifests 
 git branch -a | cut -d / -f 3 
 #回到源码根目录
 repo start android-6.0.1_r8 --all  
 查看当前的分支 
 repo branches
  • 完成后,查看当前的分支repo branches

如果本地版本库中的源代码有一些改动,执行repo sync命令后,会出现如下提示

build/: discarding 1 commits
dalvik/: discarding 2 commits
kernel/: discarding 6 commits
packages/apps/Calendar/: discarding 1 commits
packages/apps/Contacts/: discarding 2 commits
packages/apps/Mms/: discarding 1 commits
packages/apps/Music/: discarding 1 commits
packages/apps/Phone/: discarding 1 commits
vendor/embinux/support-tools/: discarding 1 commits
  • 这时就需要如下命令
repo forall -c git reset --hard
repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-7.0.0_r1
repo sync

或者


repo forall -c git reset --hard
repo forall -c git checkout android-5.1.1_r1
repo sync
最后再执行
repo start android-5.1.1_r1 --all 

开始编译android源码

  • 下载依赖包

    sudo apt-get install libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-dev g++-multilib 
    sudo apt-get install -y git flex bison gperf build-essential libncurses5-dev:i386 
    sudo apt-get install tofrodos python-markdown libxml2-utils xsltproc zlib1g-dev:i386 
    sudo apt-get install dpkg-dev libsdl1.2-dev libesd0-dev
    sudo apt-get install git-core gnupg flex bison gperf build-essential  
    sudo apt-get install zip curl zlib1g-dev gcc-multilib g++-multilib 
    sudo apt-get install libc6-dev-i386 
    sudo apt-get install lib32ncurses5-dev x11proto-core-dev libx11-dev 
    sudo apt-get install libgl1-mesa-dev libxml2-utils xsltproc unzip m4
    sudo apt-get install lib32z-dev ccache
  • 确保上述过程完成后,接下来我们需要初始化编译环境(需要在源码根目录执行)
    source build/envsetup.sh

misty@ubuntu:~/bin/aosp$ source build/envsetup.sh
including device/asus/deb/vendorsetup.sh
including device/asus/flo/vendorsetup.sh
including device/asus/fugu/vendorsetup.sh
including device/generic/mini-emulator-arm64/vendorsetup.sh
including device/generic/mini-emulator-armv7-a-neon/vendorsetup.sh
including device/generic/mini-emulator-mips/vendorsetup.sh
including device/generic/mini-emulator-x86_64/vendorsetup.sh
including device/generic/mini-emulator-x86/vendorsetup.sh
including device/htc/flounder/vendorsetup.sh
including device/huawei/angler/vendorsetup.sh
including device/lge/bullhead/vendorsetup.sh
including device/lge/hammerhead/vendorsetup.sh
including device/moto/shamu/vendorsetup.sh
including sdk/bash_completion/adb.bash

不难发现该命令只是引入了其他执行脚本,该命令执行成功后,我们会得到了一些有用的命令,比如最下面要用到的lunch命令.

编译源码

  • 初始化编译环境之后,就进入源码编译阶段.这个阶段又包括两个阶段:选择编译目标和执行编译.

    选择编译目标

lunch aosp_arm64-eng

misty@ubuntu:~/bin/aosp$ lunch aosp_arm64-eng

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=6.0.1
TARGET_PRODUCT=aosp_arm64
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm64
TARGET_ARCH_VARIANT=armv8-a
TARGET_CPU_VARIANT=generic
TARGET_2ND_ARCH=arm
TARGET_2ND_ARCH_VARIANT=armv7-a-neon
TARGET_2ND_CPU_VARIANT=cortex-a15
HOST_ARCH=x86_64
HOST_OS=linux
HOST_OS_EXTRA=Linux-4.18.0-20-generic-x86_64-with-Ubuntu-18.04-bionic
HOST_BUILD_TYPE=release
BUILD_ID=MOI10E
OUT_DIR=out
============================================

编译目标的格式:BUILD-BUILDTYPE,比如上面的aosp_arm-eng的BUILD是aosp_arm,BUILDTYPE是eng.

  • 什么是Build
    • BUILD指的是特定功能的组合的特定名称,即表示编译出的镜像可以运行在什么环境.其中,aosp(Android Open Source Project)代表Android开源项目;arm表示系统是运行在arm架构的处理器上,arm64则是指64位arm架构;处理器,x86则表示x86架构的处理器;此外,还有一些单词代表了特定的Nexus设备,下面是常用的设备代码和编译目标,更

参考官方文档:https://source.android.com/source/running.html

Android源代码编译命令m/mm/mmm/make分析

执行编译

  • make clean 先清除上次编译的缓存
  • make -j8

需要注意的是,参与编译的线程并不是越多越好,通常是根据你机器cup的核心来确定:core*2,即当前cpu的核心的2倍.比如,我现在的笔记本是双核四线程的,因此根据公式,最快速的编译可以make -j8.
(通过cat /proc/cpuinfo查看相关cpu信息)

便可以编译完成.看到### make completed successfully (01:18:45(hh:mm:ss)) ###表示你编译成功了.

运行模拟器

  • 在编译完成之后,就可以通过以下命令运行Android虚拟机了,命令如下:
source build/envsetup.sh
lunch  [选择刚刚设置的目标版本]
emulator
  • 如果你是在编译完后立刻运行虚拟机,由于我们之前已经执行过source及lunch命令了,因此现在你只需要执行命令就可以运行虚拟机:
    emulator

  • 如果你在使用lunch命令时选择的是aosp_arm-eng,那么在执行不带参数的emualtor命令时,Linux Kernel默认使用的是/source/prebuilds/qemu-kernel/arm/kernel-qemu目录下的kernel-qemu文件;而android镜像文件则是默认使用source/out/target/product/generic目录下的system.img,userdata.img和ramdisk.img,也就是我们刚刚编译出来的镜像文件.

  • 上面我在使用lunch命令时选择的是aosp_arm64-eng,因此linux默认使用的/source/prebuilds/qemu-kernel/arm64/kernel-qemu下的kernel-qemu,而其他文件则是使用的source/out/target/product/generic64目录下的system.img,userdata.img和ramdisk.img.当然,emulator指令允许你通过参数制定使用不同的文件,具体用法可以通过emulator --help查看

编译android6 源码出现问题

  • 要求open-jdk7,切换java版本即可
    
    Your version is: java version "1.8.0_211" Java(TM) SE Runtime Environment (build 1.8.0_211-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode).
    The required version is: "1.7.x"

Please follow the machine setup instructions at
https://source.android.com/source/initializing.html


build/core/main.mk:171: *** stop。 停止。

make failed to build some targets (7 seconds)

java版本问题解决方案

首先在终端输入以下命令来搜索当前系统的JDK版本 `sudo apt-cache search openjdk`

misty@ubuntu:~/bin/aosp$ sudo apt-get install openjdk-7-jdk
正在读取软件包列表... 完成
正在分析软件包的依赖关系树       
正在读取状态信息... 完成       
没有可用的软件包 openjdk-7-jdk,但是它被其它的软件包引用了。
这可能意味着这个缺失的软件包可能已被废弃,
或者只能在其他发布源中找到

原因ubuntu18不再自带open-jdk7的版本,需要从官网下载安装

openjdk-7-jdk

openjdk-7-jre

openjdk-7-jre-headless

libjpeg62-turbo

libfontconfig1

fontconfig-config

#在一个空的文件夹下执行(下载速度很慢,实际下载过程需要vpn)
wget http://ftp.jp.debian.org/debian/pool/main/o/openjdk-7/openjdk-7-jdk_7u161-2.6.12-1_amd64.deb
wget http://ftp.jp.debian.org/debian/pool/main/o/openjdk-7/openjdk-7-jre_7u161-2.6.12-1_amd64.deb
wget http://ftp.jp.debian.org/debian/pool/main/o/openjdk-7/openjdk-7-jre-headless_7u161-2.6.12-1_amd64.deb
wget http://ftp.jp.debian.org/debian/pool/main/libj/libjpeg-turbo/libjpeg62-turbo_1.5.2-2+b1_amd64.deb
wget http://ftp.jp.debian.org/debian/pool/main/f/fontconfig/libfontconfig1_2.13.1-2_amd64.deb
wget http://ftp.jp.debian.org/debian/pool/main/f/fontconfig/fontconfig-config_2.13.1-2_all.deb

# 安装deb
dpkg -i *.deb

# 安装完成后找到其安装路径
dpkg -L openjdk-7-jdk 

# (可跳过)实际安装到这一步失败了,但是安装了部分包,执行下一步操作sudo apt --fix-broken install解决

sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-7-jdk

# 如果出现依赖或错误,可以修正
apt --fix-broken install

# 配置多版本
 sudo update-alternatives --install /usr/lib/java java /usr/lib/jvm/java-8-openjdk-amd64/bin/ 300

# 如果有多个版本的jdk 安装完成后设置默认java版本

sudo update-alternatives --config java
sudo update-alternatives --config javac
或者直接指定  
update-java-alternatives --list
update-java-alternatives -s java-1.7.0-openjdk-amd64

# 效果:
misty@ubuntu:~/MyFile/jdk7$ java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-8u212-b03-0ubuntu1.18.04.1-b03)
OpenJDK 64-Bit Server VM (build 25.212-b03, mixed mode)
misty@ubuntu:~/MyFile/jdk7$ sudo update-alternatives --config java
有 2 个候选项可用于替换 java (提供 /usr/bin/java)。

  选择       路径                                          优先级  状态
------------------------------------------------------------
* 0            /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java   1081      自动模式
  1            /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java   1071      手动模式
  2            /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java   1081      手动模式

要维持当前值[*]请按<回车键>,或者键入选择的编号:1
update-alternatives: 使用 /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java 来在手动模式中提供 /usr/bin/java (java)
misty@ubuntu:~/MyFile/jdk7$ sudo update-alternatives --config javac
链接组 javac (提供 /usr/bin/javac)中只有一个候选项:/usr/lib/jvm/java-7-openjdk-amd64/bin/javac
无需配置。

# 查看当前的Java版本
misty@ubuntu:~/MyFile/jdk7$ java -version
java version "1.7.0_161"
OpenJDK Runtime Environment (IcedTea 2.6.12) (7u161-2.6.12-1)
OpenJDK 64-Bit Server VM (build 24.161-b01, mixed mode)

安装open-jdk8

    $ sudo apt-get update
    $ sudo apt-get install openjdk-8-jdk
    如果在安装过程中遇到错误,可以使用命令

    sudo apt-get -f install

卸载 open-jdk8

sudo apt-get purge  openjdk-8-jdk
sudo apt-get purge  openjdk-8-jre

完全卸载 
sudo apt-get purge openjdk-8*  

安装oracle-java

下载解压到指定目录,配置环境变量即可

 vim /etc/profile   

 export JAVA_HOME=/home/misty/MyFile/jdk1.8.0_211

 export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

export PATH=$PATH:$JAVA_HOME/bin:

回到源码根目录(repo start android-6.0.1_r8 --all )出现如下问题无法同步,并且编译也出现问题

如果直接执行repo start 切换了分支但是 .repo/manifest/default.xml的代码还是老版本的

misty@ubuntu:~/bin/aosp$ repo branches
*  android-6.0.1_r81         | in all projects
misty@ubuntu:~/bin/aosp$ repo sync
fatal: 'android-6.0.1_r81' does not appear to be a git repository
fatal: 无法读取远程仓库。

请确认您有正确的访问权限并且仓库存在。

^Caborted by user
misty@ubuntu:~/bin/aosp$ sudo repo sync

... A new repo command ( 1.25) is available.
... You should upgrade soon:

    cp /home/misty/bin/aosp/.repo/repo/repo /usr/bin/repo

fatal: 'android-6.0.1_r81' does not appear to be a git repository
fatal: 无法读取远程仓库。

请确认您有正确的访问权限并且仓库存在。
^Caborted by user

aidl_language_y_h 异常

  • 某些输入文件使用了未经检查或不安全的操作
touch out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_y.hpp
echo '#ifndef 'aidl_language_y_h > out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_y.h
echo '#define 'aidl_language_y_h >> out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_y.h
cat out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_y.hpp >> out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_y.h
echo '#endif' >> out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_y.h
注: 某些输入文件使用了未经检查或不安全的操作。
注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。
注: 某些输入文件使用了未经检查或不安全的操作。
注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。

需要环境支持 `export LC_ALL=C` 然后编译即可

本地化配置问题

Error when build LineageOS: “make: *** [ninja_wrapper] Error 1”
或者 out/host/linux-x86/obj/EXECUTABLES/rsg-generator_intermediates/spec.cpp' failed

解决办法:在 bashrc 中添加下面这句话`export LC_ALL=C //去除所有本地化的设置`或者直接在当前的终端输入临时生效

编译Android6.0错误

  • make: *** [out/host/linux-x86/obj/lib/libart.so] Error 1

out/host/linux-x86/obj/SHARED_LIBRARIES/libart_intermediates/arch/x86_64/quick_entrypoints_x86_64.o:function art_quick_deoptimize: error: unsupported reloc 42
clang: error: linker command failed with exit code 1 (use -v to see invocation)
build/core/host_shared_library_internal.mk:51: recipe for target 'out/host/linux-x86/obj/lib/libart.so' failed
make: *** [out/host/linux-x86/obj/lib/libart.so] Error 1
#### make failed to build some targets (01:00:25 (hh:mm:ss)) ####
  • 原因:clang编译器导致的问题,目前可行的修改方法时在art/build/Android.common_build.mk ,中将host 默认编辑器使用clang关掉,找到WITHOUT_HOST_CLANG
    关闭clang即可,然后回到源码目录重新编译
Host.
ART_HOST_CLANG := false
ifneq ($(WITHOUT_HOST_CLANG),true)
  # By default, host builds use clang for better warnings.
  ART_HOST_CLANG := false
endif