在Android系統中修改Android.mk使其同時編譯rgb2565和rgb2888(向out/host/linux-x86/bin/下新增加一個工具命令)
修改對應的Android.mk檔案使其在源碼編譯時間能夠同時編譯出rgb2565和rgb2888,rgb2888的源碼檔案已有,其實實現很簡單,這裡只是將我在具體測試中不同模組標籤的模組在不同編譯模式下的所採取的編譯方式列舉一下,因為我們的改動最好能和源碼進行無縫的結合。
一、 Android系統的四種編譯模式
Android系統有四種編譯模式,分別是user、userdebug、eng、test。這個值由編譯環境變數TARGET_BUILD_VARIANT儲存,在源碼編譯之前需要我們手動指定。指定方式是,執行$ . build/envsetup.sh命令之後,執行lunch命令,系統會根據我們這一步的選擇自動修改TARGET_BUILD_VARIANT的值。如果這個值未指定,系統則將其預設為eng。
不同的模式決定了不同的模組被安裝到目標系統(system.img)中,並適用於不同的發布版本。這樣可以使發布版本的系統更輕量,更簡潔。下面看一下不同的編譯模式之間的主要區別。
eng |
This is the default flavor. A plain "make " is the same as "make eng ". droid is an alias foreng . · Installs modules tagged with: eng , debug , user , and/or development . · Installs non-APK modules that have no tags specified. · Installs APKs according to the product definition files, in addition to tagged APKs. · ro.secure=0 · ro.debuggable=1 · ro.kernel.android.checkjni=1 · adb is enabled by default. |
user |
"make user " This is the flavor intended to be the final release bits. · Installs modules tagged with user . · Installs non-APK modules that have no tags specified. · Installs APKs according to the product definition files; tags are ignored for APK modules. · ro.secure=1 · ro.debuggable=0 · adb is disabled by default. |
userdebug |
"make userdebug " The same as user , except: · Also installs modules tagged with debug . · ro.debuggable=1 · adb is enabled by default. |
tests |
Installs modules tagged with user,debug,eng,tests。 |
上面的表格區分了不同編譯模式中,編譯系統所做的不同的事情。從上面的表格我們可以得知:
①並不是在對應的編譯模式下,對應的編譯模組才預裝到目標系統中。例如中的eng。在eng編譯模式下,會預裝標籤為eng、debug、user的模組。在tests編譯模式下,會預裝模組標籤為user、debug、eng、tests的模組。這對於我們修改Android.mk並成功編譯rgb2888來說是非常重要的資訊。
②其中在user編譯模式下,只會預裝標籤為user的模組。在userdebug模式下,預裝的模組除了標籤為user的還有標籤為debug的模組。
③ 如果在執行編譯時間未指定編譯模式,則系統將編譯模式自動預設為eng模式。
④其他的區別對於編譯rgb2888並沒有影響。
二、 Android.mk檔案中的模組標籤
①Android.mk檔案是Android源碼中的編譯設定檔,指定了對應的模組以怎樣的方式進行編譯。Android源碼中的編譯都是以模組進行的,一個Android.mk檔案可以同時編譯一個或多個模組。
② Android.mk中以include $(CLEAR_VARS)為開始,以include $(檔案格式)為結束算作一個模組。我們可以在其之間指定這個模組的標籤,模組的名稱,需要的源檔案,需要使用的庫等等。
③ 每個模組標籤的取值範圍是user、eng、tests、optional、samples。系統會根據上面提到的TARGET_BUILD_VARIANT值將對應的模組編譯到目標系統中。可以對模 塊標籤進行如下直觀的理解:
user:指該模組在user模式下才編譯。
eng:指該模組在eng模式下才編譯。
tests:指該模組在tests模式下才編譯
optional:指該模組在任何編譯模式下都將編譯。
samples:還不確定。
④上面官方給出的模組標籤的理解,好想是不對的。因為在不同的編譯模式下可能會預裝不同的模組,比如,eng模式下,會預裝標籤為user、debug、eng的模組,所以在eng模式下也要編譯標籤為user,debug的模組。總之,我們可以理解為,編譯模式和模組標籤共同決定了在實際的編譯中對應模組的編譯方式,兩者相互依賴。
⑤當模組標籤未指定時,預設值是user。
三、 修改Android.mk使其同時編譯rgb2565和rgb2888
①首先仿照Android.mk檔案中rgb2565模組,編寫rgb2888對應的編譯配置。如所示:
②編寫完Android.mk並選擇eng模式編譯。會出現如下的錯誤提示:
③上面提示user標籤只支援傳統的模組。如果在任何模式下編譯該模組,需要指定模組的標籤為optional。我們向Android.mk中rgb2888模組中添加對應的模組標籤為 optional,然後重新編譯,通過。
④將模組標籤修改為optional後編譯成功。當在對應的目錄(out/host/linux-x86/bin/)中尋找時,發現rgb2565命令已經產生,而rgb2888並未輸出到該目錄中。但是我們的編譯已經通過,說明rgb2888的模組已經正確編譯了。通過查看目錄out/host/linux-x86/obj/EXECUTABLES/rgb2888_intermediates/,發現編譯的中間產生物的確已經產生,說明我們的編譯沒有錯誤。從這一點可以說明,標籤為optional的模組雖然在任何模式下都會編譯,但是不會預裝到目標系統中。
⑤當使用預設標籤user時,提示user標籤只支援傳統的模組。通過測試發現,在eng模式下如果預裝標籤為user的模組時,必須顯示指定user標籤支援的模組。指定方式是修改源碼中的build/core/user_tags.mk檔案,在GRANDFATHERED_USER_MODULES +=中添加上模組的名稱,即我們的rgb2888。然後編譯,測試通過,對應的
rgb2888和rgb2565成功輸出到了out/host/linux-x86/bin目錄下。
⑥ 使用標籤eng重新編譯後,發現也會成功通過,rgb2888也成功輸出到了對應的bin目錄下(編譯模式為eng)。
⑦通過比較發現,當使用編譯模式為eng時,預裝標籤為user的模組時,要顯示的指定,模組使用eng標籤時,不需要顯示的指定就可以預裝該模組。對於eng模式下預裝optional標籤的模組,能否通過修改對應的支援才可以正確的預裝,尚不明確。
⑧另外,將編譯的模組預裝到目標系統(system.img)貌似不能等價理解為對應的rgb2888在out/host/linux-x86/bin下正確輸出了。這兩者好像沒有必然的聯絡。但是這並不影響我們解決問題。
四、 總結
綜上所述,修改Android.mk檔案使其同時編譯出rgb2565和rgb2888,可以使用以下三種方式(eng編譯模式):
①在對應的rgb2565/Android.mk檔案中添加rgb2888的模組(使用預設模組標籤),並修改build/core/user_tags.mk添加對rgb2888的支援。
②可以在rgb2565目錄所在的位置下,建立rgb2888目錄,拷貝對應的源碼檔案,編寫rgb2888模組的編譯檔案Android.mk(使用預設模組標籤),並修改build/core/user_tags.mk添加對rgb2888的支援。這種方式是源碼更清晰簡介。但也要修改user_tags.mk,這是關鍵。
③直接在rgb2888模組中顯示使用eng標籤。