编译Android源代码建议使用Linux或者Mac系统,在虚拟机上或者其他不支持的系统(如Windows)上编译Android系统也是可能的。Google内部针对Android系统的编译和测试工作大多是在Ubuntu LTS(14.04)上进行。本文是在Ubuntu16.04版本下进行的。

1.编译环境准备

python 2.X

CNU Make 3.81 -- 3.82

Git 1.7以上版本

安装 JDK

JDK版本要求:

Android版本编译要求的JDK版本
AOSP的Android主线OpenJDK 8
Android 5.x至android 6.0OpenJDK 7  
Android 2.3.x至Android 4.4.xOracle JDK 6
Android 1.5至Android 2.2.xOracle JDK 5

目前Android系统已经将java环境切换到了OpenJDK。并要求为Java 8及以上版本。(针对Kitkat Android 4.4.x 以上版本 )

sudo apt-get update

sudo apt-get install openjdk-8-jdk

本文编译的是Android 4.0.1版本,使用的JDK 6。由于版权原因,好像目前不能直接通过命令 sudo apt-get install sun-java6-jdk 安装JDK 6了。

JDK 6下载地址:

https://www.oracle.com/java/technologies/javase-java-archive-javase6-downloads.html

       OpenJDK7下载地址:

       https://codeload.github.com/awh/openjdk7/zip/master (源码)

       https://codeload.github.com/ikeji/openjdk7-jdk/zip/master

       OpenJDK7官方编译帮助文档

       openJDK-7.tar.gz   (编译Android6.0源码需要的java工具包openJDK7,已经编译好的版本。包括有jdk和jre)

如果系统上安装了多个Java版本。运行下面的命令设置默认的Java:

sudo update-alternatives --config java

键入一个数字以选择Java版本。

并通过运行以下命令设置默认Java编译器:

sudo update-alternatives --config javac 

选择成功后进行如下环境变量配置:

## home 目录下
vim .bashrc

##在 .bashrc文件下添加如下
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64  ## 这里要注意目录要换成自己解压的jdk 目录
export JRE_HOME=${JAVA_HOME}/jre  
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib  
export PATH=${JAVA_HOME}/bin:$PATH  

所需依赖:

安装所需的程序包 :

##Ubuntu 14.04下所需依赖:
sudo apt-get install 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 lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip

Ubuntu 16.04保险起见使用下面的依赖,Ubuntu 16.04需要的依赖和Ubuntu 14.04所需要的依赖是不同的。

sudo apt-get install -y git flex bison gperf build-essential libncurses5-dev:i386 
sudo apt-get install libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-dev g++-multilib 
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 lib32z-dev ccache
sudo apt-get install libgl1-mesa-dev libxml2-utils xsltproc unzip m4

2.下载 repo 工具:

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

如果上面的地址无法访问,试下面这个: 

curl http://android.googlesource.com/repo > ~/bin/repo

## 如果上述 URL 都不可访问,可以用下面的:
## curl -sSL  'https://gerrit-googlesource.proxy.ustclug.org/git-repo/+/master/repo?format=TEXT' |base64 -d > ~/bin/repo

3.下载源码(这里提供两种方式)

1.使用每月更新的初始化包(推荐)

由于首次同步需要下载约 30GB 数据,过程中任何网络故障都可能造成同步失败,强烈建议使用初始化包进行初始化。下载 https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar,下载完成后记得根据 checksum.txt 的内容校验一下。由于所有代码都是从隐藏的 .repo 目录中 checkout 出来的,所以只保留了 .repo 目录,下载后解压再repo sync 一遍即可得到完整的目录。

使用方法如下:

wget -c https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar # 下载初始化包
tar xf aosp-latest.tar
cd AOSP    ## 解压得到的 AOSP 工程目录
## 这时 ls 的话什么也看不到,因为只有一个隐藏的 .repo 目录
## repo init -u https://android.googlesource.com/platform/manifest -b android-4.0.1_r1 (选择版本同步)
repo sync  ## 通常同步一遍即可得到完整目录
## 或 repo sync -l 仅checkout代码

此后,每次只需运行 repo sync 即可保持同步。强烈建议保持每天同步,并尽量选择凌晨等低峰时间

查看所有分支

cd .repo/manifests
git branch -a

如果想切换到其它分支可以重新执行

repo init -b android-6.0.1_r63
repo sync

2.传统初始化方法

建立工作目录:

mkdir WORKING_DIRECTORY
cd WORKING_DIRECTORY

初始化仓库:

repo init -u https://android.googlesource.com/platform/manifest
## repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest (也可以)

上述命令会要求Repo下载最新的Android源代码,也就是master分支,如果想下载其他指定分支

repo init -u https://android.googlesource.com/platform/manifest -b android-4.0.1_r1

同步Android源代码

repo sync

4.编译源码 

建立完编译环境,并且下载好源代码之后,就可以正式开始编译了。

如果你使用的第一种下载源码方式进入AOSP文件夹下:进入源码目录初始化编译环境

source build/envsetup.sh

选择目标

lunch full-eng

设置编译目标为full-eng,表示对所有的移动设备,Android模拟器有效,并打开所有的调试选项。如果只执行lunch命令,会出现对应的选项。

 

最后开始编译

## 充分利用cpu资源,也可以使用make选项“-jN”。N值取决于开发机的CPU数、每颗CPU的核心数以及每个核心的线程数
make -j4

编译成功后会出现如下界面,当时忘记截图了,所以用一下别人编译成功的图片(大致如下):

 

5.启动Android模拟器

Android 4.0.1版本启动模拟器和其他的Android版本不一样,当时编译成功后直接执行命令

emulator &

发现根本找不到这个命令,刚开始没有弄明白,在网上找了一些帖子 ,发现还要编译模拟器。下面是如何编译出SDK。

## 执行envsetup.sh  
. build/envsetup.sh  
## 选择SDk对应产品。(如果通过“lunch“没有出现”sdk“这个种类的产品也没有关系,可以直接输入下面的命令)
lunch sdk-eng  
## 最后,使用以下命令进行SDK编译:
make sdk

编译完成后工作目录里增加了一个log文件 v8.log

现在执行下列命令启动模拟器:

## xxx是你的用户名
cd out/host/linux-x86/sdk/android-sdk_eng.xxx_linux-x86/tools 
## 
./android list targets 
##
./android create avd -t 1 -n ics  
## 启动模拟器
./emulator -avd ics  

启动成功如下图:

还有几个很有用的命令。

make -k ## 继续编译
m  ## 编译完整的Android源代码
mm  ## 此命令必须进入指定的工程的目录进行编译
mmm  ## 可以在任何一级目录编译任意指定的工程

6.编译过程报错整理 

Android 4.0.1版本是很久之前的版本了,感觉目前使用的人也很少,编译这个版本纯粹是因为最初试水之后没有成功不甘心,非要给它编译出来。幸运的是遇到的这些编译错误都解决了,也是很欣慰。

(1)make版本过高

       build/core/main.mk:43: *  You are using version 4.1 of make.
       build/core/main.mk:44: *  Android can only be built by version 3.81.

解决:https://blog.csdn.net/daoliting5268/article/details/84503064  替换make版本

(2)

       *** missing separator
       dalvik/CleanSpec.mk:47: *** missing separator. Stop.

解决:不要在 . build/envsetup.sh 的窗口执行, 在新的 shell 窗口执行 (估计是一些环境变量原因)

(3)

      Checking build tools versions...
      build/core/main.mk:527: hardware/qcom/sdm845/Android.mk: No such file or directory
      build/core/main.mk:527: hardware/qcom/sm8150/Android.mk: No such file or directory
      make: *** No rule to make target `hardware/qcom/sm8150/Android.mk'. Stop.

解决:将sdm845/和sm8150/这两个文件夹全部删掉

(4)

      Can't locate Switch.pm in @INC (you may need to install the Switch module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.22.1 /usr/local/share/perl/5.22.1 /usr/lib/x86_64-linux-gnu/perl5/5.22 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.22 /usr/share/perl/5.22 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base .) at external/webkit/Source/WebCore/make-hash-tools.pl line 23.
BEGIN failed--compilation aborted at external/webkit/Source/WebCore/make-hash-tools.pl line 23.
Can't locate Switch.pm in @INC (you may need to install the Switch module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.22.1 /usr/local/share/perl/5.22.1 /usr/lib/x86_64-linux-gnu/perl5/5.22 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.22 /usr/share/perl/5.22 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base .) at external/webkit/Source/WebCore/make-hash-tools.pl line 23.
BEGIN failed--compilation aborted at external/webkit/Source/WebCore/make-hash-tools.pl line 23.
make: *** [out/target/product/generic/obj/STATIC_LIBRARIES/libwebcore_intermediates/Source/WebCore/platform/ColorData.cpp] Error 2
make: *** Waiting for unfinished jobs....
make: *** [out/target/product/generic/obj/STATIC_LIBRARIES/libwebcore_intermediates/Source/WebCore/html/DocTypeStrings.cpp] Error 2
target Generated: libwebcore <= external/webkit/Source/WebCore/html/parser/HTMLEntityNames.in

解决:安装perl的switch库:

sudo apt-get install libswitch-perl

(5)

      dalvik/vm/native/dalvik_system_Zygote.cpp: In function ‘int setrlimitsFromArray(ArrayObject*)’:
      dalvik/vm/native/dalvik_system_Zygote.cpp:193:19: error: aggregate ‘setrlimitsFromArray(ArrayObject*)::rlimit rlim’ has incomplete type and cannot be defined
     struct rlimit rlim;
                   ^
      dalvik/vm/native/dalvik_system_Zygote.cpp:216:43: error: ‘setrlimit’ was not declared in this scope
               err = setrlimit(contents[0], &rlim);
                                           ^
      make: *** [out/host/linux-x86/obj/SHARED_LIBRARIES/libdvm_intermediates/native/dalvik_system_Zygote.o] Error 1
      make: *** Waiting for unfinished jobs....

解决:添加头文件#include <sys/resource.h> 到以下文件
           dalvik/vm/native/dalvik_system_Zygote.cpp

(6)

      make: *** [out/host/linux-x86/obj/EXECUTABLES/emugen_intermediates/main.o] error 1

解决:需要在  development/tools/emulator/opengl/host/tools/emugen/main.cpp

            在声明中增加一条头文件声明   #include <getopt.h>

(7)

      frameworks/base/include/utils/KeyedVector.h:193:31: error: ‘indexOfKey’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]

解决:在 development/tools/emulator/opengl/Android.mk

           增加  '-fpermissive' 到25行:
           EMUGL_COMMON_CFLAGS := -DWITH_GLES2 -fpermissive

(8)

       make: *** [out/host/linux-x86/obj/EXECUTABLES/aapt_intermediates/AaptAssets.o] Error 1

解决:  frameworks/base/tools/aapt/Android.mk

         在第31行增加:

         LOCAL_CFLAGS += -Wno-format-y2k -fpermissive

(9)

      make: *** [out/host/linux-x86/obj/STATIC_LIBRARIES/libutils_intermediates/AssetManager.o] Error 1

解决:在 frameworks/base/libs/utils/Android.mk

           在第60行后面增加-fpermissive:   

           LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS) -fpermissive

(10)

      make: *** [out/host/linux-x86/obj/EXECUTABLES/grxmlcompile_intermediates/grxmlcompile.o] Error 1

解决:

cd external/srec
##复制拷贝下面的命令到终端:
wget "https://github.com/CyanogenMod/android_external_srec/commit/4d7ae7b79eda47e489669fbbe1f91ec501d42fb2.diff"
patch -p1 < 4d7ae7b79eda47e489669fbbe1f91ec501d42fb2.diff
rm -f 4d7ae7b79eda47e489669fbbe1f91ec501d42fb2.diff

(11)

host Executable: emulator_renderer (out/host/linux-x86/obj/EXECUTABLES/emulator_renderer_intermediates/emulator_renderer)
/usr/bin/ld: out/host/linux-x86/obj/EXECUTABLES/emulator_renderer_intermediates/main.o: undefined reference to symbol 'XInitThreads'
//usr/lib/i386-linux-gnu/libX11.so.6: error adding symbols: DSO missing from command line
collect2: ld returned 1 exit status
make: *** [out/host/linux-x86/obj/EXECUTABLES/emulator_renderer_intermediates/emulator_renderer] Error 1

解决:修改development/tools/emulator/opengl/host/renderer/Android.mk文件

           添加一行:LOCAL_LDLIBS += -lX11  注意最好是复制过去,右边的容易写错

(12)

   make: *** [out/host/linux-x86/obj/EXECUTABLES/obbtool_intermediates/Main.o] error 1

 解决:系统gcc版本高,在配置环境的时候,gcc安装了高到版本,所以gcc版本太高导致,需要降低gcc版本。

sudo apt-get install gcc-4.4 gcc-4.4-multilib g++-4.4 g++-4.4-multilib

https://blog.csdn.net/wu11zhike/article/details/83865549    ubuntu 16.04 gcc高低版本切换 

(13)

/usr/bin/ld: cannot find -lGL
host Java: hosttestlib (out/host/common/obj/JAVA_LIBRARIES/hosttestlib_intermediates/classes)
/usr/bin/ld: cannot find -lGL
/usr/bin/ld: cannot find -lGL
collect2: ld returned 1 exit status
collect2: make: *** [out/host/linux-x86/obj/lib/libGLES_V2_translator.so] Error 1
ld returned 1 exit status
make: *** Waiting for unfinished jobs....
collect2: ld returned 1 exit status
make: *** [out/host/linux-x86/obj/lib/libGLES_CM_translator.so] Error 1
make: *** [out/host/linux-x86/obj/lib/libEGL_translator.so] Error 1

解决:

sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1.2.0 /usr/lib/libGL.so

目前记得的就这些,要是想起来还会继续添加。
 

 

 

 


 

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐