日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android编译系统入门(二)

發布時間:2024/4/14 Android 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android编译系统入门(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Android.mk的使用方法

在上一篇Android編譯系統入門(一)中我們只要介紹了Android系統使用make命令默認編譯的依賴樹是droid,而droid是一個偽目標,它有兩個先決條件droidcore和dist_files,其中重點是droidcore,它主要用于編譯系統所需的system.img,boot.img等。有了上一篇的基礎,今天我們要分析一下Android.mk文件在整個編譯系統中的地位和作用。

一棵大樹的繁茂和枝葉的多少息息相關。一方面只有枝干足夠茁壯才能托起枝葉,另一方面枝葉的光合作用也能促進枝干的生長。那么在Android編譯系統中,droid就是這棵樹中強有里的枝干,而Android.mk則是一片片的葉子,縱觀整個Android平臺Android.mk的數量在一千個以上。那么如此多的makefile文件又是在何時被整合進整個編譯系統的呢?其實答案還是在main.mk中。

ifneq ($(ONE_SHOT_MAKEFILE),) # We've probably been invoked by the "mm" shell function # with a subdirectory's makefile. include $(ONE_SHOT_MAKEFILE) # Change CUSTOM_MODULES to include only modules that were # defined by this makefile; this will install all of those # modules as a side-effect. Do this after including ONE_SHOT_MAKEFILE # so that the modules will be installed in the same place they # would have been with a normal make. CUSTOM_MODULES := $(sort $(call get-tagged-modules,$(ALL_MODULE_TAGS))) FULL_BUILD := # Stub out the notice targets, which probably aren't defined # when using ONE_SHOT_MAKEFILE. NOTICE-HOST-%: ; NOTICE-TARGET-%: ;# A helper goal printing out install paths .PHONY: GET-INSTALL-PATH GET-INSTALL-PATH:@$(foreach m, $(ALL_MODULES), $(if $(ALL_MODULES.$(m).INSTALLED), \echo 'INSTALL-PATH: $(m) $(ALL_MODULES.$(m).INSTALLED)';))else # ONE_SHOT_MAKEFILEifneq ($(dont_bother),true) # # Include all of the makefiles in the system ## Can't use first-makefiles-under here because # --mindepth=2 makes the prunes not work. subdir_makefiles := \$(shell build/tools/findleaves.py $(FIND_LEAVES_EXCLUDES) $(subdirs) Android.mk)$(foreach mk, $(subdir_makefiles), $(info including $(mk) ...)$(eval include $(mk)))endif # dont_bother

ONE_SHOT_MAKEFILE變量和編譯選項有關,當選擇默認make命令進行整編的時候ONE_SHOT_MAKEFILE值為空,這是就會走下面這個分支

subdir_makefiles := \$(shell build/tools/findleaves.py $(FIND_LEAVES_EXCLUDES) $(subdirs) Android.mk)$(foreach mk, $(subdir_makefiles), $(info including $(mk) ...)$(eval include $(mk)))

其中就是通過findleaves.py這個腳本來查找所有的Android.mk文件但可能并不是所有的Android.mk都會被包好進來比如.repo .git下的就會被排除在外。這些排除選項由FIND_LEAVES_EXCLUDES決定。所有被包含進來的Android.mk的路徑都會被追加到subdir_makefiles變量,接著通過一個foreach函數將所有的Android.mk文件都include進來。其中$(info including $(mk) ...)負責打印這些文件信息,如下

再通過eval函數執行include操作將Android.mk文件整合進整棵大樹。

OK,到這里所有的Android.mk文件都被包含進來了,等整個大樹被構建完成后make會從依賴樹最外層的葉子開始往上執行所有的COMMANDS。

接下來我們選取Settings模塊作為例子,詳細的解釋一下Android.mk的編寫規則和一些注意事項。Settings模塊的Android.mk內容如下

#LOCAL_PATH表示當前目錄的地址,一般位于include $(CLEAR_VARS)之前 LOCAL_PATH:= $(call my-dir)#CLEAR_VARS對應的是clean_vars.mk,用于清除除了LOCAL_PATH以外的所有LOCAL_打頭的變量 include $(CLEAR_VARS)#重定向java庫文件 LOCAL_JAVA_LIBRARIES := bouncycastle conscrypt telephony-common ims-common#重定向java靜態庫文件 LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 android-support-v13 jsr305#模塊tag為optional,表示不管是選擇了什么模式都會編譯該模塊 LOCAL_MODULE_TAGS := optional#重定向本地源碼 LOCAL_SRC_FILES := \$(call all-java-files-under, src) \src/com/android/settings/EventLogTags.logtags#重定向本地資源文件 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res#模塊名 LOCAL_PACKAGE_NAME := Settings#模塊證書簽名 LOCAL_CERTIFICATE := platform#是否是特權文件 LOCAL_PRIVILEGED_MODULE := true#使用代碼混淆 LOCAL_PROGUARD_FLAG_FILES := proguard.flags#判斷是否進行增量編譯 ifneq ($(INCREMENTAL_BUILDS),)LOCAL_PROGUARD_ENABLED := disabledLOCAL_JACK_ENABLED := incremental endif#include三個makefile文件,進項相關變量賦值 include frameworks/opt/setupwizard/navigationbar/common.mk include frameworks/opt/setupwizard/library/common.mk include frameworks/base/packages/SettingsLib/common.mk#開始編譯Settings模塊,對應package.mk文件。感興趣的可以進一步研究apk是怎么被編譯出來的,里面還是很復雜的 include $(BUILD_PACKAGE)# 如果使用的是mm或mmm命令單編Settings模塊的話會額外include test目錄下的Android.mk,用于編譯測試模塊。 ifeq (,$(ONE_SHOT_MAKEFILE)) include $(call all-makefiles-under,$(LOCAL_PATH)) endif

通過上述對Android.mk文件的分析,我們可以看到需要編譯一個模塊要做的工作還是很少的,只要指定幾個變量就可以了,這也得益與google的用心良苦,它把所有的公共操作都抽取了出來,做好了各種模板,如BUILD_PACKAGE等,我們要做的只是調用適當的模板就行了。
下面介紹一些Android.mk中常用的變量,以供讀者參考。

變量名說明
LOCAL_PATH用于確定源碼所在的目錄,一般把它放在CLEAR_VARS變量引用的前面,因為它不會背清除,每個Android.mk只需要定義一次就行
CLAER_VARS清空很多LOCAL_開頭的變量(LOCAL_PATH除外)。因為所有的Makefile都是在一個編譯環境下執行,因此變量的定義理論上都是全局的,每個模塊開始編譯前進行清理工作是必不可少的
LOCAL_MODULE模塊名,需要保證唯一存在且中間不能又空格
LOCAL_MODULE_PATH模塊的輸出路徑
LOCAL_SRC_FILES模塊編譯所涉及的源文件。如果是java程序,可以考慮調用all-java-files-under添加java代碼。因為有LOCAL_PATH,所以這里只需要給出文件名即可,如src
LOCAL_CC用于指定C編譯器
LOCAL_CXX用于指定C++編譯器
LOCAL_CPP_EXTENSION用于指定特殊的C++文件后綴名
LOCAL_CFLAGSC語言編譯時的額外選項
LOCAL_CXXFLOAGSC++編譯時的額外選項
LOCAL_C_INCLUDES編譯C和C++時需要的額外頭文件
LOCAL_STATIC_LIBRARIES編譯所需的靜態庫列表
LOCAL_SHARED_LIBRARIES編譯所需的共享庫列表
LOCAL_JAVA_LIBRARIES編譯時所需的JAVA類庫
LOCAL_LDLIBS編譯時所需的鏈接選項
LOCAL_COPY_HEADERS安裝應用程序時需要復制的頭文件列表,需要和LOCAL_COPY_HEADERS_TO變量配合使用
LOCAL_COPY_HEADERS_TO上述頭文件列表的復制目的地
BUILD_XX_XX各種形式的編譯模板,如生成靜態、動態庫文件,可執行文件,文檔等

總結

在Android編譯系統的學習中,我們先從最基礎的makefile語法規則入手,導出了依賴樹的概念,然后按照依賴樹的結構逐步梳理出一個完整的Android版本編譯所設計的幾個重要節點。Android編譯系統是非常龐大的,不過經過這次的學習希望大家能夠對它的結構和基本原理有一個初步的認識。那么接下來的各種編譯細節也能通過代碼的研讀和分析變得明朗起來。

轉載于:https://www.cnblogs.com/zqlxtt/p/5018956.html

總結

以上是生活随笔為你收集整理的Android编译系统入门(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。