2010-11-13 12:36 511人閱讀 評論(0) 收藏 舉報
圖1 android 的makefile結構
android的編譯檔案主要依賴於mk檔案,其源碼編譯名字是Android.mk,而不我們常見的Makefile檔案。
android目錄下的Makefile檔案,include了build/core目錄下的main.mk檔案。
main.mk檔案
main.mk要完成功能,主要如下:
包含build/core/config.mk:根據目標板的標準變數和主機資訊,設定一些變數。確定輸出目錄和產品工程。
SHELL := /bin/bash, 表明用到系統bash,如果想用其他的sh,那麼據此而改即可。
檢測host的作業系統,編譯環境。
包含definitions.mk,標準的編譯系統設定參數。主要是一些宏定義,如在Android.mk常見到的all-subdir-makefiles、my-dir之類的宏。
主要內容還是在 config.mk檔案。
1config.mk
首先會檢測主目錄下的buildspec.mk,目前此檔案不存在,我們可在此設定一些參數。
這些參數,可用於envsettup.mk,如果沒有buildspec.mk檔案,envsettup.mk則預設一些變數,如TARGET_ARCH:= arm ,TARGET_OS := linux等。
1.1 envsettup.mk
應該說envsettup.mk是config.mk重要組成部分,設定一些主要編譯工程的相關參數。
首先includeversion_defaults.mk,設定以下變數:
PLATFORM_VERSION
PLATFORM_SDK_VERSION
DEFAULT_APP_TARGET_SDK
BUILD_ID
BUILD_NUMBER
其次設定TARGET_PRODUCT,也就是在編譯地時候如果沒有用makePRODUCT-xxx-xxx,則會在此處設定。否則就要根據product_config.mk檔案裡的內容進行target和product的相關參數。
再次,設定一些輸出檔案路徑變數,如TARGET_OUT_XXX之類的。
最後把一些簡單資訊顯示終端上:
$(info============================================)
$(info PLATFORM_VERSION_CODENAME=$(PLATFORM_VERSION_CODENAME))
$(info PLATFORM_VERSION=$(PLATFORM_VERSION))
$(info TARGET_PRODUCT=$(TARGET_PRODUCT))
$(info TARGET_BUILD_VARIANT=$(TARGET_BUILD_VARIANT))
$(info TARGET_SIMULATOR=$(TARGET_SIMULATOR))
$(info TARGET_BUILD_TYPE=$(TARGET_BUILD_TYPE))
$(info TARGET_ARCH=$(TARGET_ARCH))
$(info HOST_ARCH=$(HOST_ARCH))
$(info HOST_OS=$(HOST_OS))
$(info HOST_BUILD_TYPE=$(HOST_BUILD_TYPE))
$(info BUILD_ID=$(BUILD_ID))
$(info============================================)
envsetup.mk裡頭最主要的就是product_config.mk
product_config.mk包含三個檔案node_fns.mk、product.mk和device.mk。此三檔案都是一些宏定義或變數定義,目的是根據make時傳進來的參數,從vendor目錄和build/target目錄下,找到相應的product和devcie資訊,即找BoardConfig.mk檔案,從而設定TARGET_PRODUCT、TARGET_DEVICE等值。
1.2 pathmap.mk,一些標頭檔路徑,及androidframework目錄。
編譯系統內部的一些檔案:host_static_library.mk、host_shared_library.mk等
1.3 BoardConfig.mk
預設情況下是編譯的board是generic。
尋找build/target/board/generic目錄上的內容,共有兩個mk檔案,AndroidBoard.mk和BoardConfig.mk。其中BoardConfig.mk定義一些硬體特性。
2 Makefile檔案
build/core/Makefile檔案是系統整合了,完成img,app,frameworks、模組的編譯(可能有錯)
3 對於framework開發,或者在系統移植時添加應用程式,每寫一次代碼就要進行編譯,而每次用make相關參數命令時,編譯的時間會比較長。這時可以考慮以下方式進行編譯
cdanddroid_top_path
./build/envsetup.sh
此時就用mmm,mm和m命令進行編譯:
m表示在頂層目錄進行編譯
mm 表示在目前的目錄下進行模組編譯
mmm path, 編譯path目錄下的模組。
一般在寫模組時,用mmm命令就可以了。
以下是轉載內容,在framework新增加或修改代碼,所謂的系統移植了,連結地址為http://xxw8393.blog.163.com/blog/static/3725683420107532137920/
“
如何向android的framework裡添加新類
google對於所有的類和API,分為開放式和不開放式兩種。所謂的開放式就是值javadoc所包含 的,並不是java中有public和private,而是跟javadoc有關係,代碼沒有關係。
在開放式的類中增加了一個變數,而又沒隱藏,導致和原API的doc不一致造成的就會有錯。
通過提示,有2個方法可以解決 該問題:
1、將新增加的變數或方法加上"@hide" 的注釋,注意一點,加"@hide" 不是簡簡單單 的/*@hide */就行了,標準的javadoc要這樣 /** */ 而且對於 format 變數 應該加上 { }, 也就是/**{@hide}*/
2、如果想在產生的doc中增加該變數或方法的話,必須輸入:
make update-api
這樣的話,系統 自動 將新增加的API添加到current.xml中了。
所以如果要加方法就是按上面的方法加。
如果需要加進新的類 這時候又分2種 :一種是原有的包下面加類 這個最簡單 加完之後直接make update-api就好了 還有一種是加在framework/base下面 這個時候你make update-api是不會在current。xml裡產生你的類的。 看了Android。mk才知道 原來需要修改 android源碼根目錄下的build/core/pathmap.mk把你的目錄加進去。然後就好了。
”
事實上對於famework的開發,可以通過mmm命令產生新jar包,然後手動的方式傳到模組器對應目錄,一般是/system/framework/即可,當然也可以自己寫個指令碼,敲一命令,一步到位亦可。
圖1 android 的makefile結構
android的編譯檔案主要依賴於mk檔案,其源碼編譯名字是Android.mk,而不我們常見的Makefile檔案。
android目錄下的Makefile檔案,include了build/core目錄下的main.mk檔案。
main.mk檔案
main.mk要完成功能,主要如下:
包含build/core/config.mk:根據目標板的標準變數和主機資訊,設定一些變數。確定輸出目錄和產品工程。
SHELL := /bin/bash, 表明用到系統bash,如果想用其他的sh,那麼據此而改即可。
檢測host的作業系統,編譯環境。
包含definitions.mk,標準的編譯系統設定參數。主要是一些宏定義,如在Android.mk常見到的all-subdir-makefiles、my-dir之類的宏。
主要內容還是在 config.mk檔案。
1config.mk
首先會檢測主目錄下的buildspec.mk,目前此檔案不存在,我們可在此設定一些參數。
這些參數,可用於envsettup.mk,如果沒有buildspec.mk檔案,envsettup.mk則預設一些變數,如TARGET_ARCH:= arm ,TARGET_OS := linux等。
1.1 envsettup.mk
應該說envsettup.mk是config.mk重要組成部分,設定一些主要編譯工程的相關參數。
首先includeversion_defaults.mk,設定以下變數:
PLATFORM_VERSION
PLATFORM_SDK_VERSION
DEFAULT_APP_TARGET_SDK
BUILD_ID
BUILD_NUMBER
其次設定TARGET_PRODUCT,也就是在編譯地時候如果沒有用makePRODUCT-xxx-xxx,則會在此處設定。否則就要根據product_config.mk檔案裡的內容進行target和product的相關參數。
再次,設定一些輸出檔案路徑變數,如TARGET_OUT_XXX之類的。
最後把一些簡單資訊顯示終端上:
$(info============================================)
$(info PLATFORM_VERSION_CODENAME=$(PLATFORM_VERSION_CODENAME))
$(info PLATFORM_VERSION=$(PLATFORM_VERSION))
$(info TARGET_PRODUCT=$(TARGET_PRODUCT))
$(info TARGET_BUILD_VARIANT=$(TARGET_BUILD_VARIANT))
$(info TARGET_SIMULATOR=$(TARGET_SIMULATOR))
$(info TARGET_BUILD_TYPE=$(TARGET_BUILD_TYPE))
$(info TARGET_ARCH=$(TARGET_ARCH))
$(info HOST_ARCH=$(HOST_ARCH))
$(info HOST_OS=$(HOST_OS))
$(info HOST_BUILD_TYPE=$(HOST_BUILD_TYPE))
$(info BUILD_ID=$(BUILD_ID))
$(info============================================)
envsetup.mk裡頭最主要的就是product_config.mk
product_config.mk包含三個檔案node_fns.mk、product.mk和device.mk。此三檔案都是一些宏定義或變數定義,目的是根據make時傳進來的參數,從vendor目錄和build/target目錄下,找到相應的product和devcie資訊,即找BoardConfig.mk檔案,從而設定TARGET_PRODUCT、TARGET_DEVICE等值。
1.2 pathmap.mk,一些標頭檔路徑,及androidframework目錄。
編譯系統內部的一些檔案:host_static_library.mk、host_shared_library.mk等
1.3 BoardConfig.mk
預設情況下是編譯的board是generic。
尋找build/target/board/generic目錄上的內容,共有兩個mk檔案,AndroidBoard.mk和BoardConfig.mk。其中BoardConfig.mk定義一些硬體特性。
2 Makefile檔案
build/core/Makefile檔案是系統整合了,完成img,app,frameworks、模組的編譯(可能有錯)
3 對於framework開發,或者在系統移植時添加應用程式,每寫一次代碼就要進行編譯,而每次用make相關參數命令時,編譯的時間會比較長。這時可以考慮以下方式進行編譯
cdanddroid_top_path
./build/envsetup.sh
此時就用mmm,mm和m命令進行編譯:
m表示在頂層目錄進行編譯
mm 表示在目前的目錄下進行模組編譯
mmm path, 編譯path目錄下的模組。
一般在寫模組時,用mmm命令就可以了。
以下是轉載內容,在framework新增加或修改代碼,所謂的系統移植了,連結地址為http://xxw8393.blog.163.com/blog/static/3725683420107532137920/
“
如何向android的framework裡添加新類
google對於所有的類和API,分為開放式和不開放式兩種。所謂的開放式就是值javadoc所包含 的,並不是java中有public和private,而是跟javadoc有關係,代碼沒有關係。
在開放式的類中增加了一個變數,而又沒隱藏,導致和原API的doc不一致造成的就會有錯。
通過提示,有2個方法可以解決 該問題:
1、將新增加的變數或方法加上"@hide" 的注釋,注意一點,加"@hide" 不是簡簡單單 的/*@hide */就行了,標準的javadoc要這樣 /** */ 而且對於 format 變數 應該加上 { }, 也就是/**{@hide}*/
2、如果想在產生的doc中增加該變數或方法的話,必須輸入:
make update-api
這樣的話,系統 自動 將新增加的API添加到current.xml中了。
所以如果要加方法就是按上面的方法加。
如果需要加進新的類 這時候又分2種 :一種是原有的包下面加類 這個最簡單 加完之後直接make update-api就好了 還有一種是加在framework/base下面 這個時候你make update-api是不會在current。xml裡產生你的類的。 看了Android。mk才知道 原來需要修改 android源碼根目錄下的build/core/pathmap.mk把你的目錄加進去。然後就好了。
”
事實上對於famework的開發,可以通過mmm命令產生新jar包,然後手動的方式傳到模組器對應目錄,一般是/system/framework/即可,當然也可以自己寫個指令碼,敲一命令,一步到位亦可。