1. 程式人生 > >Android 編譯命令

Android 編譯命令

一、引言

先看下面幾條指令,相信編譯過Android原始碼的人都再熟悉不過的。

source setenv.sh
lunch
make -j12

記得最初剛接觸Android時,同事告訴我用上面的指令就可以編譯Android原始碼,指令雖短但過幾天就記不全或者忘記順序,每次編譯時還需要看看自己的雲筆記,冰冷的指令總是難以讓我記憶。後來我決定認真研究下這個指令的含義。知其然還需知其所以然,這樣能更深層次的理解並記憶,才能與自身的知識體系建立強連線,或許還有意外收穫,果然如此,接下來跟大家分享一下在研究上述幾條指令含義的過程中,深入瞭解到的Android Build(編譯)系統。

二、編譯命令

準備好編譯環境後,編譯Android原始碼的第一步是 source build/envsetup.sh,其中source命令就是用於執行shell指令碼命令,功能等價於”.”,因此該命令也等價於. build/envsetup.sh。在檔案envsetup.sh聲明瞭當前會話終端可用的命令,這裡需要注意的是當前會話終端,也就意味著每次新開啟一個終端都必須再一次執行這些指令。起初並不理解為什麼新開的終端不能直接執行make指令,到這裡總算明白了。

接下來,解釋一下本文開頭的引用的命令:

source setenv.sh  //初始化編譯環境,包括後面的lunch和make指令
lunch  //指定此次編譯的目標裝置以及編譯型別
make  -j12 //開始編譯,預設為編譯整個系統,其中-j12代表的是編譯的job數量為12。

所有的編譯命令都在envsetup.sh檔案能找到相對應的function,比如上述的命令lunchmake,在檔案一定能找到

function lunch(){
    ...
}

function make(){
    ...
}

source envsetup.sh,需要cd到setenv.sh檔案所在路徑執行,路徑可能在build/envsetup.sh,或者integrate/envsetup.sh,再或者不排除有些廠商會封裝自己的.sh指令碼,但核心思路是一致的。

具體實現這裡就不展開說明,下面精煉地總結了一下各個指令用法和功效。

2.1 程式碼編譯

編譯指令解釋
m 在原始碼樹的根目錄執行編譯
mm 編譯當前路徑下所有模組,但不包含依賴
mmm [module_path] 編譯指定路徑下所有模組,但不包含依賴
mma 編譯當前路徑下所有模組,且包含依賴
mmma [module_path] 編譯指定路徑下所有模組,且包含依賴
make [module_name] 無引數,則表示編譯整個Android程式碼

下面列舉部分模組的編譯指令:

模組make命令mmm命令
init make init mmm system/core/init
zygote make app_process mmm frameworks/base/cmds/app_process
system_server make services mmm frameworks/base/services
java framework make framework mmm frameworks/base
framework資源 make framework-res mmm frameworks/base/core/res
jni framework make libandroid_runtime mmm frameworks/base/core/jni
binder make libbinder mmm frameworks/native/libs/binder

上述mmm命令同樣適用於mm/mma/mmma,編譯系統採用的是增量編譯,只會編譯發生變化的目標檔案。當需要重新編譯所有的相關模組,則需要編譯命令後增加引數-B,比如make -B [module_name],或者 mm -B [module_path]。

Tips:

  • 對於m、mm、mmm、mma、mmma這些命令的實現都是通過make方式來完成的。
  • mmm/mm編譯的效率很高,而make/mma/mmma編譯較緩慢;
  • make/mma/mmma編譯時會把所有的依賴模組一同編譯,但mmm/mm不會;
  • 建議:首次編譯時採用make/mma/mmma編譯;當依賴模組已經編譯過的情況,則使用mmm/mm編譯。

2.2 程式碼搜尋

搜尋指令解釋
cgrep 所有C/C++檔案執行搜尋操作
jgrep 所有Java檔案執行搜尋操作
ggrep 所有Gradle檔案執行搜尋操作
mangrep [keyword] 所有AndroidManifest.xml檔案執行搜尋操作
mgrep [keyword] 所有Android.mk檔案執行搜尋操作
sepgrep [keyword] 所有sepolicy檔案執行搜尋操作
resgrep [keyword] 所有本地res/*.xml檔案執行搜尋操作
sgrep [keyword] 所有資原始檔執行搜尋操作

上述指令用法最終實現方式都是基於grep指令,各個指令用法格式:

xgrep [keyword]  //x代表的是上表的搜尋指令

例如,搜尋所有AndroidManifest.xml檔案中的launcher關鍵字所在檔案的具體位置,指令

mangrep launcher

再如,搜尋所有Java程式碼中包含zygote所在檔案

jgrep zygote

又如,搜尋所有system_app的selinux許可權資訊

sepgrep system_app

Tips: Android原始碼非常龐大,直接採用grep來搜尋程式碼,不僅方法笨拙、浪費時間,而且搜尋出很多無意義的混淆結果。根據具體需求,來選擇合適的程式碼搜尋指令,能節省程式碼搜尋時間,提高搜尋結果的精準度,方便定位目的碼。

2.3 導航指令

導航指令解釋
croot 切換至Android根目錄
cproj 切換至工程的根目錄
godir [filename] 跳轉到包含某個檔案的目錄

Tips: 當每次修改完某個檔案後需要編譯時,執行cproj後會跳轉到當前模組的根目錄,也就是Android.mk檔案所在目錄,然後再執行mm指令,即可編譯目標模組;當進入原始碼層級很深後,需要返回到根目錄,使用croot一條指令完成;另外cd - 指令可用於快速切換至上次目錄。

2.4 資訊查詢

查詢指令解釋
hmm 查詢所有的指令help資訊
findmakefile 查詢當前目錄所在工程的Android.mk檔案路徑
print_lunch_menu 查詢lunch可選的product
printconfig 查詢各項編譯變數值
gettop 查詢Android原始碼的根目錄
gettargetarch 獲取TARGET_ARCH值

2.5 其他指令

上述只是列舉比較常用的指令,還有其他指令,而且不同的build編譯系統,支援的指令可能會存在一些差異,當忘記這些編譯指令,可以通過執行hmm,查詢指令的幫助資訊。

最後再列舉兩個比較常用的指令:

  • make clean:執行清理操作,等價於 rm -rf out/
  • make update-api:更新API,在framework API改動後需執行該指令,Api記錄在目錄frameworks/base/api

三、編譯系統

Android 編譯系統是Android原始碼的一部分,用於編譯Android系統,Android SDK以及相關文件。該編譯系統是由Make檔案、Shell以及Python指令碼共同組成,其中最為重要的便是Make檔案。關於編譯系統可參考 理解 Android Build 系統

3.1 Makefile分類

整個Build系統的Make檔案分為三大類:

  • 系統核心的Make檔案:定義了Build系統的框架,檔案全部位於路徑/build/core,其他Make檔案都是基於該框架編寫的;
  • 針對產品的Make檔案:定義了具體某個型號手機的Make檔案,檔案路徑位於/device,該目錄下往往又以公司名和產品名劃分兩個子級目錄,比如/device/qcom/msm8916
  • 針對模組的Make檔案:整個系統分為各個獨立的模組,每個模組都一個專門的Make檔案,名稱統一為”Android.mk”,該檔案定義了當前模組的編譯方式。Build系統會掃描整個原始碼樹中名為”Android.mk”的問題,並執行相應模組的編譯工作。

3.2 編譯產物

經過make編譯後的產物,都位於/out目錄,該目錄下主要關注下面幾個目錄:

  • /out/host:Android開發工具的產物,包含SDK各種工具,比如adb,dex2oat,aapt等。
  • /out/target/common:通用的一些編譯產物,包含Java應用程式碼和Java庫;
  • /out/target/product/[product_name]:針對特定裝置的編譯產物以及平臺相關C/C++程式碼和二進位制檔案;

在/out/target/product/[product_name]目錄下,有幾個重量級的映象檔案:

  • system.img:掛載為根分割槽,主要包含Android OS的系統檔案;
  • ramdisk.img:主要包含init.rc檔案和配置檔案等;
  • userdata.img:被掛載在/data,主要包含使用者以及應用程式相關的資料;

當然還有boot.img,reocovery.img等映象檔案,這裡就不介紹了。

3.3 Android.mk解析

在原始碼樹中每一個模組的所有檔案通常都相應有一個自己的資料夾,在該模組的根目錄下有一個名稱為“Android.mk” 的檔案。編譯系統正是以模組為單位進行編譯,每個模組都有唯一的模組名,一個模組可以有依賴多個其他模組,模組間的依賴關係就是通過模組名來引用的。也就是說當模組需要依賴一個jar包或者apk時,必須先將jar包或apk定義為一個模組,然後再依賴相應的模組。

對於Android.mk檔案,通常都是以下面兩行

LOCAL_PATH := $(call my-dir)  //設定當編譯路徑為當前資料夾所在路徑
include $(CLEAR_VARS)  //清空編譯環境的變數(由其他模組設定過的變數)

為方便模組編譯,編譯系統設定了很多的編譯環境變數,如下:

  • LOCAL_SRC_FILES:當前模組包含的所有原始碼檔案;
  • LOCAL_MODULE:當前模組的名稱(具有唯一性);
  • LOCAL_PACKAGE_NAME:當前APK應用的名稱(具有唯一性);
  • LOCAL_C_INCLUDES:C/C++所需的標頭檔案路徑;
  • LOCAL_STATIC_LIBRARIES:當前模組在靜態連結時需要的庫名;
  • LOCAL_SHARED_LIBRARIES:當前模組在執行時依賴的動態庫名;
  • LOCAL_STATIC_JAVA_LIBRARIES:當前模組依賴的Java靜態庫;
  • LOCAL_JAVA_LIBRARIES:當前模組依賴的Java共享庫;
  • LOCAL_CERTIFICATE:簽署當前應用的證書名稱,比如platform。
  • LOCAL_MODULE_TAGS:當前模組所包含的標籤,可以包含多標籤,可能值為debgu,eng,user,development或optional(預設值)

針對這些環境變數,編譯系統還定義了一些便捷函式,如下:

  • $(call my-dir):獲取當前資料夾路徑;
  • $(call all-java-files-under, ):獲取指定目錄下的所有Java檔案;
  • $(call all-c-files-under, ):獲取指定目錄下的所有C檔案;
  • $(call all-Iaidl-files-under, ) :獲取指定目錄下的所有AIDL檔案;
  • $(call all-makefiles-under, ):獲取指定目錄下的所有Make檔案;

示例:

  LOCAL_PATH := $(call my-dir)
  include $(CLEAR_VARS)

  # 獲取所有子目錄中的Java檔案
  LOCAL_SRC_FILES := $(call all-subdir-java-files)

  # 當前模組依賴的動態Java庫名稱
  LOCAL_JAVA_LIBRARIES := com.gityuan.lib

  # 當前模組的名稱
  LOCAL_MODULE := demo

  # 將當前模組編譯成一個靜態的Java庫
  include $(BUILD_STATIC_JAVA_LIBRARY)

轉自:http://www.weibo.com/gityuan?is_hot=1

相關推薦

理解Android編譯命令

一、引言 關於Android Build系統,這個話題很早就打算整理下,遲遲沒有下筆,決定跟大家分享下。先看下面幾條指令,相信編譯過Android原始碼的人都再熟悉不過的。 source setenv.sh lunch make -j12 記得最初剛接觸An

Android 編譯命令

一、引言 先看下面幾條指令,相信編譯過Android原始碼的人都再熟悉不過的。 source setenv.sh lunch make -j12 記得最初剛接觸Android時,同事告訴我用上面的指令就可以編譯Android原始碼,指令雖短但過幾天就記不全或者忘記順序,每次編譯時還需要看看自己的雲筆記

MTK Android 編譯命令

二、 當修改一些程式碼時,使用什麼編譯命令可以最有效率 1: ./mk n(r) kernel; ./mk bootimage;當修改kernel相關程式碼時,要使用此命令,具體如下:      alps/kernel/      alps/mediatek/platform/mt65xx/kernel/  

Mtk Android編譯命令

一、輸入命令:Usage: (makeMtk|mk) [options] project actions [modules]Options:  -t, -tee      : Print log information on the standard-out.  -o, -o

Android編譯命令

生成 sha mds 賦值 config pty 格式 n) rgs 目錄 說在前面 編譯流程 編譯指令 代碼編譯 代碼檢索 其他指令

Android ADB 命令及原始碼編譯命令筆記

ADB 常用命令 adb root:獲取root 許可權 adb remount:重新掛載 adb shell :進入terminal adb devices -s serialnumber :檢視指定裝置狀態 adb devices 獲取裝置列表及裝置狀態 adb kill-ser

Android.mk的用法和基礎 && m、mm、mmm編譯命令

Android.mk的用法和基礎 && m、mm、mmm編譯命令         一個Android.mk file用來向編譯系統描述你的原始碼。具體來說:該檔案是GNU Makefile的一小部分,會被編譯系統解析一次或多次。你可以在每一個Androi

Android原始碼編譯命令m/mm/mmm/make分析

        在前文中,我們分析了Android編譯環境的初始化過程。android編譯環境初始化完成後,我們就可以用m/mm/mmm/make命令編譯原始碼了。當然,這要求每一個模組都有一個Android.mk檔案。Android.mk實際上是一個Makefile指令碼,用來描述模組編譯資訊。Andr

Android常用的編譯命令

1.make -jX X表示數字,這個命令將編譯Android系統並生成映象,XX表示可以使用到的CPU核數,這在配置好的電腦上特別有用,公司的16核ubuntu伺服器執行make -j16只要不到20分鐘,而雙核PC上需要4個小時! 2.make snod 這條

Android編譯詳解之lunch命令

    Android的優勢就在於其開源,手機和平板生產商可以根據自己的硬體進行個性定製自己的手機產品, 如小米,LePhone,M9等,因此,在我們在對Android的原始碼進行定製的時候,很有必要了解下,Android的編譯過程。 如果你從來沒有做過Android程式碼

MTK Android 編譯模組說明及編譯命令

alps/檔案目錄 [makeMtk]   ALPS project make /build entry point. [bionic]   C runtime libraries, such as, libc, libm, libdl, dynamic linker et

android 原始碼的m、mm、mmm編譯命令的使用與重新打包android系統映象檔案。

一、android 原始碼的m、mm、mmm編譯命令的使用 m:編譯整個安卓系統      makes from the top of the tree mm:編譯當前目錄下的模組,當前目錄下需要有Android.mk這個makefile檔案,否則就往上找最近的A

mtk Android 常用編譯命令

認真看過的才轉載的哈!  很詳細的總結了MTK平臺的編譯命令,包括修改模組時候的快速編譯等。 —————————————————————————————————————————————————————— 一、 命令格式:./maketek [option] [project

Android ant 命令列手動編譯打包詳解

Android 命令列手動編譯打包過程圖 1使用aapt生成R.java類檔案: 例: E:\androidDev\android-sdk-windows2.2\tools>E:\androidDev\android-sdk-windows2.2\platf

Android 編譯錯誤——布局 Error parsing XML: not well-formed (invalid token)

XML width 文件 format source 註意 for 編碼 invalid 在修改了Android布局文件後,編譯出現Error parsing XML: not well-formed (invalid token)。 首先先排查xml文件的編碼格式是否

android 編譯調用C代碼

line out name roi 上網 嵌入 hive set str 博客地址:www.zalezone.cn 前言 需求來源 這幾天幫別人做一個簡單的androidclient,也沒什麽功能。主要就是調用C代碼來對手機的Wifi網

我的Android進階之旅------>Android編譯錯誤java.util.zip.ZipException: duplicate entry的解決方法

image bsp failed 進階 技術分享 san col get cep 今天在Android Studio中把另外一個項目引入當前項目,編譯的時候出現了java.util.zip.ZipException: duplicate entry錯誤。 錯誤例如以下

常用cl編譯命令參數解釋

文件依賴 scope 也不能 不知道 x86 介紹 tle .idb pla 緊接前文,第一行cl命令如下: [plain] view plain copy print? 1> cl /c /IC:\...\include /ZI

Firefly-RK3288開發板Android編譯環境搭建開荒

android ubuntu 編譯環境 kernel firefly 開發板 入手了Firefly-RK3288的開發板,自己從零開始搭建編譯環境開荒第一步:安裝Ubuntu12.04,使用安裝盤安裝(安裝的過程就不詳寫了,下面貼圖) 安裝完後,更新ubuntu 第二步:從官網上下載

windows命令行中java和javac、javap使用詳解(java編譯命令)

路徑 point 目錄 pan static article 字節碼 區別 string 如題,首先我們在桌面,開始->運行->鍵入cmd 回車,進入windows命令行。進入如圖所示的畫面: 可知,當前默認目錄為C盤Users文件夾下的Administr