假设源码根目录为
~/Android
1 环境搭建
1.1 安装openjdk-7-jdk
Android 5.1 用到的jdk不再是Oracle 的 jdk ,而是开源的 openjdk,在ubuntu安装好后,使用如下命令安装jdk:
$ sudo apt-get install openjdk-7-jdk
在/etc/profile 文件末尾加上:
JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64/ //jdk路径
PATH=$PATH:$HOME/bin:$JAVA_HOME/bin //jdk的bin目录
export JAVA_HOME
export PATH
1.2 安装编译依赖的软件
执行如下代码:
$ sudo apt-get install git gnupg flex bison gperf build-essential zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa- dri:i386 libgl1-mesa-dev g++-multilib mingw32 tofrodos python-markdown libxml2-utils xsltproc zlib1g-dev:i386 dpkg-dev
$ sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so
1.3 安装git
查看 git教程
1.4 安装repo
1.4.1 创建repo目录
$ mkdir ~/bin
$ PATH=~/bin:$PATH
1.4.2下载repo
repo download:
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
克隆下来后将git-repo中的repo文件拷贝到bin目录
$ cp git-repo/repo ~/bin/
修改repo文件,设置REPO_URL如下:
REPO_URL = 'git://aosp.tuna.tsinghua.edu.cn/android/git-repo'
1.5 配置Cache
使用如下命令配置cache:
$ sudo apt-get install ccache
$ source ~/.bashrc
2 下载源码
2.1 创建目录
$ mkdir ~/Android
2.2 初始化repo
$ cd ~/Android
$ repo init -u git://codeaurora.org/platform/manifest.git(下载最新源码)
或者下载指定版本
$ repo init -u git://aosp.tuna.tsinghua.edu.cn/android/platform/manifest -b android-5.1.1_r4
$ repo init -u git://aosp.tuna.tsinghua.edu.cn/android/platform/manifest -b android-6.0.1_r22
$ repo init -u git://aosp.tuna.tsinghua.edu.cn/android/platform/manifest -b android-n-preview-1
2.3 开始下载
$ repo sync -f
3 全编译
3.1 设置cache
$ cd ~/Android
$ prebuilts/misc/linux-x86/ccache/ccache -M 50G
3.2 初始化编译环境
$ source build/envsetup.sh
3.3 选择编译目标包
$ lunch
注:lunch 点击Enter后有很多种可选
3.4 编译
$ make -j4
注: 1.make后面可以更参数:如你的机器时双核,每核双线程的话,使用make -j4,这样速度更快,但编译时使用的内存也更多
2.make失败或停止后,可以使用make -k 继续编译
4 单模块编译
只要该目录下有mk文件就可以单编
注:mmm和mm命令必须在执行.build/envsetup.sh
或source build/envsetup.sh
之后才能使用,并且只编译发生变化的文件。如果要编译模块的所有文件,需要-B选项,例如mm -B。
4.1 make
这种方法适合第一次编译,会把依赖模块一并编译。它需要在全部源代码中找到编译模块的Android.mk文件,并检查依赖模块是否有修改,因此编译时间较长。使用这种方法,我们只需要搜索源码目录下的Android.mk文件,找到模块名LOCAL_PACKAGE_NAME,然后指定给make即可。
4.1.1 编译应用层
以编译Settings为例
$ make Settings
4.1.2 编译框架层和系统运行库源码
对于框架层和系统运行库,需要查看LOCAL_MODULE变量。以frameworks包中的源码为例,在终端中运行以下命令:
$ find frameworks/base/services/ -name Android.mk
注:该命令将搜索frameworks目录下所有的Android.mk文件
$ cat frameworks/base/services/Android.mk
$ make services
注:cat filename 一次显示整个文件
4.2 mmm
用于在源码根目录编译指定模块,参数为模块的相对路径。只能在第一次编译后使用。比如要编译Settings部分源码,需要在终端中执行以下命令:
$ mmm packages/apps/Settings/
4.3 mm
用于在模块根目录编译这个模块。只能在第一次编译后使用。例如要编译Settings部分源码,需要在终端中执行以下命令:
$ cd ~/Android/packages/apps/Settings/
$ mm
5 制作系统应用
一般厂商定制应用应放到~/Android/ventor/厂商名/ 路径下
注:该例子使用studio文件目录结构
5.1 编写mk文件 && 该项目导入了第三方jar包
导入第三方jar包其中关键在于LOCAL_STATIC_JAVA_LIBRARIES := xxxxx和LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := xxxxx:lily.jar这两句。
xxxxx为jar包的别名,可以随便取,只要与下面相对应就行。但是后面冒号后面的那个jar包名字就必须写你需要引入的jar包名字。jar包如果放在工程的根目录下,也就是与你要编译的app的src,res,Android.mk文件同级的目录。
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
#定义模块标签,build系统根据标签决定哪些模块需要安装
#user: 指该模块只在user版本下才编译
#eng: 指该模块只在eng版本下才编译
#tests: 指该模块只在tests版本下才编译
#optional:指该模块在所有版本下都编译
LOCAL_MODULE_TAGS := optional
# $(call all-java-files-under, <src>):获取指定目录下的所有java文件。
LOCAL_SRC_FILES := $(call all-java-files-under, src)
#使用指定目录下的manifest文件(如果不与mk文件在同一目录的话必须定义)
LOCAL_MANIFEST_FILE := src/main/AndroidManifest.xml
#资源文件目录,可选定义,不定义也没问题
LOCAL_RESOURCE_DIRS := $(LOCAL_PATH)/src/main/res
#模块名称,apk一般使用LOCAL_PACKAGE_NAME,其它使用LOCAL_MODULE
LOCAL_PACKAGE_NAME := overlay_SetupWizard
#如果导入第三方jar包才使用这句
#定义引用别名 xxxxx为jar包的别名,可以随便取,只要与下面相对应就行
LOCAL_STATIC_JAVA_LIBRARIES := xxxxx
#签署当前应用的证书名称
#用于指定签名时使用的KEY,如果不指定,默认使用testkey,LOCAL_CERTIFICATE可设置的值如下:
# LOCAL_CERTIFICATE:= platform
# LOCAL_CERTIFICATE:= shared
# LOCAL_CERTIFICATE:= media
#而在Android.mk中的这些配置,需要在APK源码的AndroidManifest.xml文件中的manifest节点添加如下内容:
# android:sharedUserId="android.uid.system"
# android:sharedUserId="android.uid.shared"
# android:sharedUserId="android.media"
#这些刚好与上面的mk文件里的配置对应上。
LOCAL_CERTIFICATE := platform
#以声明app需要放在/system/priv-app下
LOCAL_PRIVILEGED_MODULE := true
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
###############################################################
#如果jar包放在libs目录下,且libs与Android.mk文件是同级目录,则jar包路径如下
###############################################################
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := xxxxx:libs/3part.jar // 引用名:jar包名路径
include $(BUILD_MULTI_PREBUILT)
################################################################
5.2 单编看是否通过,如果通过会生成apk
apk路径如下:
~/Android/out/target/product/厂商名/system/priv-app/overlay_SetupWizard/overlay_SetupWizard.apk
5.3 修改device.mk增加自己的应用
注:如果想要在整编的时候把自己的应用编进去,需要此步骤
修改PRODUCT_PACKAGES,增加自己的模块
PRODUCT_PACKAGES += \
overlay_SetupWizard
6 替换原生应用
6.1 修改模块的Android.mk覆盖原生应用
在Android.mk中添加如下说明LOCAL_OVERRIDES_PACKAGES := SetupWizard
(目标packageName)
6.2 修改device.mk增加自己的应用
修改PRODUCT_PACKAGES,增加自己的模块
PRODUCT_PACKAGES += \
overlay_SetupWizard