編輯:關於Android編程
對andriod系統層進行開發,或者進行移植時,時常需要添加文件到編譯體系中,在最終的編譯中復制到out中,最後打包成鏡像,這裡總結一下Copy File 方法,這裡以我的 android 4.2.1為例.
這個變量就是用來標記Copy操作的,比較常見的形式如下:
#jscese cp 3g script and PRODUCT_COPY_FILES += $(DEVICE_SOURCES)/3g-script/ip-up-datakey:system/etc/ppp/ip-up-datakey $(DEVICE_SOURCES)/3g-script/ip-down-datakey:system/etc/ppp/ip-down-datakey $(DEVICE_SOURCES)/3g-script/init.gprs-pppd:system/etc/ppp/init.gprs-pppd device/sample/etc/apns-full-conf.xml:system/etc/apns-conf.xml #external/usb-modeswitch/usb_modeswitch.d:system/etc/usb_modeswitch.d #PRODUCT_COPY_FILES += #$(DEVICE_SOURCES)/3g-script/ip-down-datakey:system/etc/ppp/ip-down-datakey #end
可以看到 格式: 中間用 “ : ” 隔開!
編譯過源碼的都知道在最開始 編譯的時候 都會出現:
PRODUCT_COPY_FILES frameworks/base/data/sounds/effects/ogg/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg ignored. PRODUCT_COPY_FILES frameworks/base/data/sounds/effects/ogg/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg ignored. PRODUCT_COPY_FILES frameworks/base/data/sounds/effects/ogg/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg ignored. PRODUCT_COPY_FILES frameworks/base/data/sounds/effects/ogg/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg ignored. PRODUCT_COPY_FILES frameworks/base/data/sounds/effects/ogg/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg ignored. ...
# ----------------------------------------------------------------- # Define rules to copy PRODUCT_COPY_FILES defined by the product. # PRODUCT_COPY_FILES contains words like :[:]. # is relative to $(PRODUCT_OUT), so it should look like, # e.g., system/etc/file.xml. # The filter part means only eval the copy-one-file rule if this # src:dest pair is the first one to match the same dest #$(1): the src:dest pair define check-product-copy-files $(if $(filter %.apk, $(1)),$(error Prebuilt apk found in PRODUCT_COPY_FILES: $(1), use BUILD_PREBUILT instead!)) endef # filter out the duplicate : pairs. unique_product_copy_files_pairs := $(foreach cf,$(PRODUCT_COPY_FILES), $(if $(filter $(unique_product_copy_files_pairs),$(cf)),, $(eval unique_product_copy_files_pairs += $(cf)))) unique_product_copy_files_destinations := $(foreach cf,$(unique_product_copy_files_pairs), $(eval _src := $(call word-colon,1,$(cf))) $(eval _dest := $(call word-colon,2,$(cf))) $(call check-product-copy-files,$(cf)) $(if $(filter $(unique_product_copy_files_destinations),$(_dest)), $(info PRODUCT_COPY_FILES $(cf) ignored.), $(eval _fulldest := $(call append-path,$(PRODUCT_OUT),$(_dest))) $(if $(filter %.xml,$(_dest)), $(eval $(call copy-xml-file-checked,$(_src),$(_fulldest))), $(eval $(call copy-one-file,$(_src),$(_fulldest)))) $(eval ALL_DEFAULT_INSTALLED_MODULES += $(_fulldest)) $(eval unique_product_copy_files_destinations += $(_dest)))) unique_product_copy_files_pairs := unique_product_copy_files_destinations :=
這就是 PRODUCT_COPY_FILES 起作用的地方! 可以看上面注釋,描述了規則用法,只能copy file!
也就是上面編譯打印的出處,代表忽略項. 詳細的規則可跟進去細看,無非是依賴Copy之類的.
這裡需要注意一點, PRODUCT_COPY_FILES 不能在 Android.mk 中使用 添加新的Copy 項!
# Can't use first-makefiles-under here because # --mindepth=2 makes the prunes not work. subdir_makefiles := $(shell build/tools/findleaves.py --prune=out --prune=.repo --prune=.git $(subdirs) Android.mk) include $(subdir_makefiles) endif # ONE_SHOT_MAKEFILE # Now with all Android.mks loaded we can do post cleaning steps. include $(BUILD_SYSTEM)/post_clean.mk ifeq ($(stash_product_vars),true) $(call assert-product-vars, __STASHED) endif
在這裡加載所有的Android.mk ,重點在後面的 assert-product-vars 函數:
# # Assert that the the variable stashed by stash-product-vars remains untouched. # $(1): The prefix as supplied to stash-product-vars # define assert-product-vars $(strip $(eval changed_variables:=) $(foreach v,$(_product_stash_var_list), $(if $(call streq,$($(v)),$($(strip $(1))_$(call rot13,$(v)))),, $(eval $(warning $(v) has been modified: $($(v)))) $(eval $(warning previous value: $($(strip $(1))_$(call rot13,$(v))))) $(eval changed_variables := $(changed_variables) $(v))) ) $(if $(changed_variables), $(eval $(error The following variables have been changed: $(changed_variables))),) ) endef
build/core/main.mk:528: *** The following variables have been changed: PRODUCT_COPY_FILES。 停止。
使用 PRODUCT_COPY_FILES 應該算是最常用的Copy File 的方法了,一般可直接加在 device.mk 中!
這個方法用在Android.mk中,可參考 /system/core/rootdir/Android.mk:
copy_from += etc/init.goldfish.sh copy_to := $(addprefix $(TARGET_OUT)/,$(copy_from)) copy_from := $(addprefix $(LOCAL_PATH)/,$(copy_from)) $(copy_to) : PRIVATE_MODULE := system_etcdir $(copy_to) : $(TARGET_OUT)/% : $(LOCAL_PATH)/% | $(ACP) $(transform-prebuilt-to-target) ALL_PREBUILT += $(copy_to)
可以看下規則,定義在/build/core/definitions.mk中:
# Copy a prebuilt file to a target location. define transform-prebuilt-to-target @echo $(if $(PRIVATE_IS_HOST_MODULE),host,target) Prebuilt: $(PRIVATE_MODULE) ($@) $(copy-file-to-target) endef
define copy-file-to-target @mkdir -p $(dir $@) $(hide) $(ACP) -fp $< $@ endef
build/core/main.mk:533: *** Some files have been added to ALL_PREBUILT. build/core/main.mk:534: * build/core/main.mk:535: * ALL_PREBUILT is a deprecated mechanism that build/core/main.mk:536: * should not be used for new files. build/core/main.mk:537: * As an alternative, use PRODUCT_COPY_FILES in build/core/main.mk:538: * the appropriate product definition. build/core/main.mk:539: * build/target/product/core.mk is the product build/core/main.mk:540: * definition used in all products. build/core/main.mk:541: * build/core/main.mk:542: * unexpected usb_modeswitch.h in ALL_PREBUILT build/core/main.mk:542: * unexpected usb_modeswitch.sh in ALL_PREBUILT build/core/main.mk:542: * unexpected usb_modeswitch.tcl in ALL_PREBUILT build/core/main.mk:543: * build/core/main.mk:544: *** ALL_PREBUILT contains unexpected files。 停止。
include $(BUILD_SYSTEM)/legacy_prebuilts.mk ifneq ($(filter-out $(GRANDFATHERED_ALL_PREBUILT),$(strip $(notdir $(ALL_PREBUILT)))),) $(warning *** Some files have been added to ALL_PREBUILT.) $(warning *) $(warning * ALL_PREBUILT is a deprecated mechanism that) $(warning * should not be used for new files.) $(warning * As an alternative, use PRODUCT_COPY_FILES in) $(warning * the appropriate product definition.) $(warning * build/target/product/core.mk is the product) $(warning * definition used in all products.) $(warning *) $(foreach bad_prebuilt,$(filter-out $(GRANDFATHERED_ALL_PREBUILT),$(strip $(notdir $(ALL_PREBUILT)))),$(warning * unexpected $(bad_prebuilt) in ALL_PREBUILT)) $(warning *) $(error ALL_PREBUILT contains unexpected files) endif
上面的打印信息告訴我們 ALL_PREBUILT 是一種過時的機制,已經不讓用於copy新的文件了,推薦使用PRODUCT_COPY_FILES !
而可以添加進 ALL_PREBUILT 變量的成員定義在 legacy_prebuilts.mk中:
# This is the list of modules grandfathered to use ALL_PREBUILT # DO NOT ADD ANY NEW MODULE TO THIS FILE # # ALL_PREBUILT modules are hard to control and audit and we don't want # to add any new such module in the system GRANDFATHERED_ALL_PREBUILT := akmd2 am ap_gain.bin ...
注釋寫的很明白了!
所以如果我們自己想加個文件編譯copy ,就不能使用 copy_from copy_to ALL_prebuilt 這種機制 !
這種方式把文件當成編譯項目,在Android.mk中copy一個file:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := usb_modeswitch.conf LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT)/etc LOCAL_SRC_FILES :=$(LOCAL_MODULE) include $(BUILD_PREBUILT)
上面所有的都說的是Copy File 但是如果需要 Copy 一個文件目錄下所有就需要另做操作了!
以我前面的博客 Android——4.2 - 3G移植之路之usb-modeswitch (二) 中copy usb-modewitch.d 數據目錄 為例.
在那裡的Android.mk 中我使用了shell命令Copy:
$(shell cp -rf $(LOCAL_PATH)/usb_modeswitch.d $(TARGET_OUT)/etc/usb_modeswitch.d)
所以說在android的編譯體系中 還得按照android提供的機制來進行操作,像這種shell取巧,是方便,但不是正途!
我現在的處理:
在上面的shell的地方 include 處理Copy usb-modewitch.d 的mk文件,內容如下:
# $(1): module name # $(2): source file # $(3): destination directory define include-prebuilt-with-destination-directory include $$(CLEAR_VARS) LOCAL_MODULE := $(1) LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/usb_modeswitch_data.mk LOCAL_MODULE_STEM := $(notdir $(2)) LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(3) LOCAL_SRC_FILES := $(2) include $$(BUILD_PREBUILT) endef #== rename 's/:/_/' * ==# usb_modeswitch_data := $(notdir $(wildcard $(LOCAL_PATH)/usb_modeswitch.d/*)) $(warning jscese display -usb_modeswitch_data--$(usb_modeswitch_data)) usb_modeswitch_data_target_directory := $(TARGET_OUT)/etc/usb_modeswitch.d $(foreach data, $(usb_modeswitch_data), $(eval $(call include-prebuilt-with-destination-directory,target-data-$(notdir $(data)),usb_modeswitch.d/$(data),$(usb_modeswitch_data_target_directory)))) usb_modeswitch_data_target := $(addprefix $(usb_modeswitch_data_target_directory)/,$(foreach cacert,$(usb_modeswitch_data),$(notdir $(usb_modeswitch_data)))) .PHONY: usb_modeswitch_data_target usb_modeswitch_data: $(usb_modeswitch_data_target) # This is so that build/target/product/core.mk can use usb_modeswitch_data in PRODUCT_PACKAGES ALL_MODULES.usb_modeswitch_data.INSTALLED := $(usb_modeswitch_data_target)
關於PRODUCT_PACKAGES 變量的作用可參考我之前的博文 Android——編譯安裝Module的控制因素
另外因為文件名稱都是 XXXX:XXXX類型,我這裡先在直接使用reanme命令把:全替換成 _
如果不替換,導致傳入文件的時候 makefile 把中間的 : 可能當成了依賴符號~ 會報錯
我如果使用subst 把:換成 : 添加進去轉義符號,好像是文件又找不到,不知道有沒有遇到過這種情況.....
剛開始學對於這個機制理解不夠深刻,現在重新整理下思路。開發中,接口回調是我們經常用到的。接口回調的意思即,注冊之後並不立馬執行,而在某個時機觸發執行。首先解決啥是回調:舉
前段時間研究了不少android二次開發,其中有一種方法就是通過aidl通信,留接口提供給外面二次開發。從這裡也可以看出:aidl通信是兩個應用程序之間的進程通信了。在這
1、如何對APK簽名(1)、創建數字證書,android123.keystore keytool -genkey -alias android123.keyst
一、網絡爬蟲的基本知識網絡爬蟲通過遍歷互聯網絡,把網絡中的相關網頁全部抓取過來,這體現了爬的概念。爬蟲如何遍歷網絡呢,互聯網可以看做是一張大圖,每個頁面看做其中的一個節點
轉載請標明出處:http://write.blog.csdn.net/
三星Galaxy S6 Edge推出有一段時間了,受很多用
1、概述Drawable在我們平時的開發中,基本都會用到,而且給大家非常
最近這幾個月都是在准備找工作和找工作中,付出了很多,總算是有點收獲,所以