1. 程式人生 > >Android 原始碼環境搭建及編譯

Android 原始碼環境搭建及編譯

假設原始碼根目錄為~/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.shsource 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