eclair snapshot
This commit is contained in:
@@ -21,6 +21,30 @@
|
|||||||
# "buildspec.mk" should never be checked in to source control.
|
# "buildspec.mk" should never be checked in to source control.
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
|
# Choose a product to build for. Look in the products directory for ones
|
||||||
|
# that work.
|
||||||
|
ifndef TARGET_PRODUCT
|
||||||
|
#TARGET_PRODUCT:=generic
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Choose a variant to build. If you don't pick one, the default is eng.
|
||||||
|
# User is what we ship. Userdebug is that, with a few flags turned on
|
||||||
|
# for debugging. Eng has lots of extra tools for development.
|
||||||
|
ifndef TARGET_BUILD_VARIANT
|
||||||
|
#TARGET_BUILD_VARIANT:=user
|
||||||
|
#TARGET_BUILD_VARIANT:=userdebug
|
||||||
|
#TARGET_BUILD_VARIANT:=eng
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Choose additional targets to always install, even when building
|
||||||
|
# minimal targets like "make droid". This takes simple target names
|
||||||
|
# like "Browser" or "MyApp", the names used by LOCAL_MODULE or
|
||||||
|
# LOCAL_PACKAGE_NAME. Modules listed here will always be installed in
|
||||||
|
# /system, even if they'd usually go in /data.
|
||||||
|
ifndef CUSTOM_MODULES
|
||||||
|
#CUSTOM_MODULES:=
|
||||||
|
endif
|
||||||
|
|
||||||
# Uncomment this if you want the simulator, otherwise, build for arm
|
# Uncomment this if you want the simulator, otherwise, build for arm
|
||||||
ifndef TARGET_SIMULATOR
|
ifndef TARGET_SIMULATOR
|
||||||
#TARGET_SIMULATOR:=true
|
#TARGET_SIMULATOR:=true
|
||||||
@@ -50,21 +74,6 @@ endif
|
|||||||
#HOST_CUSTOM_DEBUG_CFLAGS:=
|
#HOST_CUSTOM_DEBUG_CFLAGS:=
|
||||||
#TARGET_CUSTOM_DEBUG_CFLAGS:=
|
#TARGET_CUSTOM_DEBUG_CFLAGS:=
|
||||||
|
|
||||||
# Choose a product to build for. Look in the products directory for ones
|
|
||||||
# that work.
|
|
||||||
ifndef TARGET_PRODUCT
|
|
||||||
#TARGET_PRODUCT:=generic
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Choose additional targets to always install, even when building
|
|
||||||
# minimal targets like "make droid". This takes simple target names
|
|
||||||
# like "Browser" or "MyApp", the names used by LOCAL_MODULE or
|
|
||||||
# LOCAL_PACKAGE_NAME. Modules listed here will always be installed in
|
|
||||||
# /system, even if they'd usually go in /data.
|
|
||||||
ifndef CUSTOM_MODULES
|
|
||||||
#CUSTOM_MODULES:=
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Choose additional locales, like "en_US" or "it_IT", to add to any
|
# Choose additional locales, like "en_US" or "it_IT", to add to any
|
||||||
# built product. Any locales that appear in CUSTOM_LOCALES but not in
|
# built product. Any locales that appear in CUSTOM_LOCALES but not in
|
||||||
# the locale list for the selected product will be added to the end
|
# the locale list for the selected product will be added to the end
|
||||||
@@ -88,10 +97,16 @@ ifndef NO_FALLBACK_FONT
|
|||||||
#NO_FALLBACK_FONT:=true
|
#NO_FALLBACK_FONT:=true
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# To enabled instrumentation in webcore based apps like gmail and
|
# To enable instrumentation in webcore based apps like gmail and
|
||||||
# the browser, define WEBCORE_INSTRUMENTATION:=true
|
# the browser, define WEBCORE_INSTRUMENTATION:=true
|
||||||
|
ifndef WEBCORE_INSTRUMENTATION
|
||||||
#WEBCORE_INSTRUMENTATION:=true
|
#WEBCORE_INSTRUMENTATION:=true
|
||||||
#endif
|
endif
|
||||||
|
|
||||||
|
# To enable SVG in webcore define ENABLE_SVG:=true
|
||||||
|
ifndef ENABLE_SVG
|
||||||
|
#ENABLE_SVG:=true
|
||||||
|
endif
|
||||||
|
|
||||||
# when the build system changes such that this file must be updated, this
|
# when the build system changes such that this file must be updated, this
|
||||||
# variable will be changed. After you have modified this file with the new
|
# variable will be changed. After you have modified this file with the new
|
||||||
|
38
cleanspec.mk
38
cleanspec.mk
@@ -18,7 +18,7 @@
|
|||||||
# WHEN DOING SO, DELETE ANY "add-clean-step" ENTRIES THAT HAVE PILED UP.
|
# WHEN DOING SO, DELETE ANY "add-clean-step" ENTRIES THAT HAVE PILED UP.
|
||||||
# **********************************************************************
|
# **********************************************************************
|
||||||
#
|
#
|
||||||
INTERNAL_CLEAN_BUILD_VERSION := 2
|
INTERNAL_CLEAN_BUILD_VERSION := 3
|
||||||
#
|
#
|
||||||
# ***********************************************************************
|
# ***********************************************************************
|
||||||
# Do not touch INTERNAL_CLEAN_BUILD_VERSION if you've added a clean step!
|
# Do not touch INTERNAL_CLEAN_BUILD_VERSION if you've added a clean step!
|
||||||
@@ -31,7 +31,7 @@ INTERNAL_CLEAN_BUILD_VERSION := 2
|
|||||||
#
|
#
|
||||||
# E.g.:
|
# E.g.:
|
||||||
# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
|
# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
|
||||||
# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/external/zlib/)
|
# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
|
||||||
#
|
#
|
||||||
# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
|
# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
|
||||||
# files that are missing or have been moved.
|
# files that are missing or have been moved.
|
||||||
@@ -54,38 +54,10 @@ INTERNAL_CLEAN_BUILD_VERSION := 2
|
|||||||
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
|
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
|
||||||
#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
|
#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
|
||||||
#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
|
#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
|
||||||
|
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libwebcore_intermediates)
|
||||||
|
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libwebcore_intermediates)
|
||||||
|
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
|
||||||
|
|
||||||
$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/etc/NOTICE.html)
|
|
||||||
# Remove generated java files after CL 126153
|
|
||||||
$(call add-clean-step, find $(OUT_DIR) -type f -name "*.java" -print0 | xargs -0 rm -f)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/product/sapphire/obj/SHARED_LIBRARIES/libhardware_legacy_intermediates/led)
|
|
||||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/mountd)
|
|
||||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/mountd.conf)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/Browser_intermediates)
|
|
||||||
$(call add-clean-step, rm -f vendor/google/apps/Talk/res/drawable/%*)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/product/*/obj/SHARED_LIBRARIES/libandroid_runtime_intermediates/android_os_NetStat.o)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/product/*/obj/SHARED_LIBRARIES/libjni_andpyime_intermediates)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/product/*/obj/SHARED_LIBRARIES/share)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/product/*/obj/SHARED_LIBRARIES/libwebcore_intermediates)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/PinyinIME_intermediates)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/com.android.inputmethod.pinyin.lib_intermediates)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/PinyinIMEGoogleService_intermediates)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/com.android.inputmethod.pinyin.lib_intermediates)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/PinyinIMEGoogleService_intermediates)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/telephony)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/product/*/obj)
|
|
||||||
$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/bin/tcpdump)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/location)
|
|
||||||
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/product/*/obj/SHARED_LIBRARIES/lib?camera_intermediates)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/product/*/obj/STATIC_LIBRARIES/lib?camera_intermediates)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/product/*/obj/SHARED_LIBRARIES/libwebcore_intermediates)
|
|
||||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
|
|
||||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/ringtones/Silence.ogg)
|
|
||||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/ringtones/notifications/Silence.ogg)
|
|
||||||
# ************************************************
|
# ************************************************
|
||||||
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
|
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
|
||||||
# ************************************************
|
# ************************************************
|
||||||
|
@@ -118,6 +118,7 @@ $(INSTALLED_BUILD_PROP_TARGET): $(BUILDINFO_SH) $(INTERNAL_BUILD_ID_MAKEFILE)
|
|||||||
PRODUCT_BRAND="$(PRODUCT_BRAND)" \
|
PRODUCT_BRAND="$(PRODUCT_BRAND)" \
|
||||||
PRODUCT_DEFAULT_LANGUAGE="$(call default-locale-language,$(PRODUCT_LOCALES))" \
|
PRODUCT_DEFAULT_LANGUAGE="$(call default-locale-language,$(PRODUCT_LOCALES))" \
|
||||||
PRODUCT_DEFAULT_REGION="$(call default-locale-region,$(PRODUCT_LOCALES))" \
|
PRODUCT_DEFAULT_REGION="$(call default-locale-region,$(PRODUCT_LOCALES))" \
|
||||||
|
PRODUCT_DEFAULT_WIFI_CHANNELS="$(PRODUCT_DEFAULT_WIFI_CHANNELS)" \
|
||||||
PRODUCT_MODEL="$(PRODUCT_MODEL)" \
|
PRODUCT_MODEL="$(PRODUCT_MODEL)" \
|
||||||
PRODUCT_MANUFACTURER="$(PRODUCT_MANUFACTURER)" \
|
PRODUCT_MANUFACTURER="$(PRODUCT_MANUFACTURER)" \
|
||||||
PRIVATE_BUILD_DESC="$(PRIVATE_BUILD_DESC)" \
|
PRIVATE_BUILD_DESC="$(PRIVATE_BUILD_DESC)" \
|
||||||
@@ -299,7 +300,7 @@ else # TARGET_BOOTIMAGE_USE_EXT2 != true
|
|||||||
$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES)
|
$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES)
|
||||||
$(call pretty,"Target boot image: $@")
|
$(call pretty,"Target boot image: $@")
|
||||||
$(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) --output $@
|
$(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) --output $@
|
||||||
$(hide) $(call assert-max-file-size,$@,$(BOARD_BOOTIMAGE_MAX_SIZE),raw)
|
$(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE),raw)
|
||||||
endif # TARGET_BOOTIMAGE_USE_EXT2
|
endif # TARGET_BOOTIMAGE_USE_EXT2
|
||||||
|
|
||||||
else # TARGET_NO_KERNEL
|
else # TARGET_NO_KERNEL
|
||||||
@@ -501,7 +502,7 @@ endif
|
|||||||
# Recovery image
|
# Recovery image
|
||||||
|
|
||||||
# If neither TARGET_NO_KERNEL nor TARGET_NO_RECOVERY are true
|
# If neither TARGET_NO_KERNEL nor TARGET_NO_RECOVERY are true
|
||||||
ifeq (,$(filter true, $(TARGET_NO_KERNEL) $(TARGET_NO_RECOVERY)))
|
ifeq (,$(filter true, $(TARGET_NO_KERNEL) $(TARGET_NO_RECOVERY) $(BUILD_TINY_ANDROID)))
|
||||||
|
|
||||||
INSTALLED_RECOVERYIMAGE_TARGET := $(PRODUCT_OUT)/recovery.img
|
INSTALLED_RECOVERYIMAGE_TARGET := $(PRODUCT_OUT)/recovery.img
|
||||||
|
|
||||||
@@ -577,7 +578,7 @@ $(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \
|
|||||||
$(MKBOOTFS) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk)
|
$(MKBOOTFS) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk)
|
||||||
$(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) --output $@
|
$(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) --output $@
|
||||||
@echo ----- Made recovery image -------- $@
|
@echo ----- Made recovery image -------- $@
|
||||||
$(hide) $(call assert-max-file-size,$@,$(BOARD_RECOVERYIMAGE_MAX_SIZE),raw)
|
$(hide) $(call assert-max-image-size,$@,$(BOARD_RECOVERYIMAGE_PARTITION_SIZE),raw)
|
||||||
|
|
||||||
else
|
else
|
||||||
INSTALLED_RECOVERYIMAGE_TARGET :=
|
INSTALLED_RECOVERYIMAGE_TARGET :=
|
||||||
@@ -662,7 +663,7 @@ endif
|
|||||||
$(INSTALLED_SYSTEMIMAGE): $(BUILT_SYSTEMIMAGE) $(RECOVERY_FROM_BOOT_PATCH) | $(ACP)
|
$(INSTALLED_SYSTEMIMAGE): $(BUILT_SYSTEMIMAGE) $(RECOVERY_FROM_BOOT_PATCH) | $(ACP)
|
||||||
@echo "Install system fs image: $@"
|
@echo "Install system fs image: $@"
|
||||||
$(copy-file-to-target)
|
$(copy-file-to-target)
|
||||||
$(hide) $(call assert-max-file-size,$@ $(RECOVERY_FROM_BOOT_PATCH),$(BOARD_SYSTEMIMAGE_MAX_SIZE),yaffs)
|
$(hide) $(call assert-max-image-size,$@ $(RECOVERY_FROM_BOOT_PATCH),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE),yaffs)
|
||||||
|
|
||||||
systemimage: $(INSTALLED_SYSTEMIMAGE)
|
systemimage: $(INSTALLED_SYSTEMIMAGE)
|
||||||
|
|
||||||
@@ -671,7 +672,7 @@ systemimage-nodeps snod: $(filter-out systemimage-nodeps snod,$(MAKECMDGOALS)) \
|
|||||||
| $(INTERNAL_MKUSERFS)
|
| $(INTERNAL_MKUSERFS)
|
||||||
@echo "make $@: ignoring dependencies"
|
@echo "make $@: ignoring dependencies"
|
||||||
$(call build-systemimage-target,$(INSTALLED_SYSTEMIMAGE))
|
$(call build-systemimage-target,$(INSTALLED_SYSTEMIMAGE))
|
||||||
$(hide) $(call assert-max-file-size,$(INSTALLED_SYSTEMIMAGE),$(BOARD_SYSTEMIMAGE_MAX_SIZE),yaffs)
|
$(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEMIMAGE),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE),yaffs)
|
||||||
|
|
||||||
#######
|
#######
|
||||||
## system tarball
|
## system tarball
|
||||||
@@ -708,7 +709,7 @@ define build-userdataimage-target
|
|||||||
$(call pretty,"Target userdata fs image: $(INSTALLED_USERDATAIMAGE_TARGET)")
|
$(call pretty,"Target userdata fs image: $(INSTALLED_USERDATAIMAGE_TARGET)")
|
||||||
@mkdir -p $(TARGET_OUT_DATA)
|
@mkdir -p $(TARGET_OUT_DATA)
|
||||||
$(call build-userimage-ext2-target,$(TARGET_OUT_DATA),$(INSTALLED_USERDATAIMAGE_TARGET),userdata,)
|
$(call build-userimage-ext2-target,$(TARGET_OUT_DATA),$(INSTALLED_USERDATAIMAGE_TARGET),userdata,)
|
||||||
$(hide) $(call assert-max-file-size,$(INSTALLED_USERDATAIMAGE_TARGET),$(BOARD_USERDATAIMAGE_MAX_SIZE),yaffs)
|
$(hide) $(call assert-max-image-size,$(INSTALLED_USERDATAIMAGE_TARGET),$(BOARD_USERDATAIMAGE_PARTITION_SIZE),yaffs)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
else # TARGET_USERIMAGES_USE_EXT2 != true
|
else # TARGET_USERIMAGES_USE_EXT2 != true
|
||||||
@@ -718,7 +719,7 @@ define build-userdataimage-target
|
|||||||
$(call pretty,"Target userdata fs image: $(INSTALLED_USERDATAIMAGE_TARGET)")
|
$(call pretty,"Target userdata fs image: $(INSTALLED_USERDATAIMAGE_TARGET)")
|
||||||
@mkdir -p $(TARGET_OUT_DATA)
|
@mkdir -p $(TARGET_OUT_DATA)
|
||||||
$(hide) $(MKYAFFS2) -f $(TARGET_OUT_DATA) $(INSTALLED_USERDATAIMAGE_TARGET)
|
$(hide) $(MKYAFFS2) -f $(TARGET_OUT_DATA) $(INSTALLED_USERDATAIMAGE_TARGET)
|
||||||
$(hide) $(call assert-max-file-size,$(INSTALLED_USERDATAIMAGE_TARGET),$(BOARD_USERDATAIMAGE_MAX_SIZE),yaffs)
|
$(hide) $(call assert-max-image-size,$(INSTALLED_USERDATAIMAGE_TARGET),$(BOARD_USERDATAIMAGE_PARTITION_SIZE),yaffs)
|
||||||
endef
|
endef
|
||||||
endif # TARGET_USERIMAGES_USE_EXT2
|
endif # TARGET_USERIMAGES_USE_EXT2
|
||||||
|
|
||||||
@@ -813,6 +814,13 @@ $(BUILT_TARGET_FILES_PACKAGE): PRIVATE_OTA_TOOLS := $(built_ota_tools)
|
|||||||
|
|
||||||
$(BUILT_TARGET_FILES_PACKAGE): PRIVATE_RECOVERY_API_VERSION := $(RECOVERY_API_VERSION)
|
$(BUILT_TARGET_FILES_PACKAGE): PRIVATE_RECOVERY_API_VERSION := $(RECOVERY_API_VERSION)
|
||||||
|
|
||||||
|
ifeq ($(TARGET_RELEASETOOLS_EXTENSIONS),)
|
||||||
|
# default to common dir for device vendor
|
||||||
|
$(BUILT_TARGET_FILES_PACKAGE): tool_extensions := $(TARGET_DEVICE_DIR)/../common
|
||||||
|
else
|
||||||
|
$(BUILT_TARGET_FILES_PACKAGE): tool_extensions := $(TARGET_RELEASETOOLS_EXTENSIONS)
|
||||||
|
endif
|
||||||
|
|
||||||
# Depending on the various images guarantees that the underlying
|
# Depending on the various images guarantees that the underlying
|
||||||
# directories are up-to-date.
|
# directories are up-to-date.
|
||||||
$(BUILT_TARGET_FILES_PACKAGE): \
|
$(BUILT_TARGET_FILES_PACKAGE): \
|
||||||
@@ -841,6 +849,9 @@ ifdef INSTALLED_2NDBOOTLOADER_TARGET
|
|||||||
endif
|
endif
|
||||||
ifdef BOARD_KERNEL_CMDLINE
|
ifdef BOARD_KERNEL_CMDLINE
|
||||||
$(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/RECOVERY/cmdline
|
$(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/RECOVERY/cmdline
|
||||||
|
endif
|
||||||
|
ifdef BOARD_KERNEL_BASE
|
||||||
|
$(hide) echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/RECOVERY/base
|
||||||
endif
|
endif
|
||||||
@# Components of the boot image
|
@# Components of the boot image
|
||||||
$(hide) mkdir -p $(zip_root)/BOOT
|
$(hide) mkdir -p $(zip_root)/BOOT
|
||||||
@@ -856,11 +867,12 @@ endif
|
|||||||
ifdef BOARD_KERNEL_CMDLINE
|
ifdef BOARD_KERNEL_CMDLINE
|
||||||
$(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/BOOT/cmdline
|
$(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/BOOT/cmdline
|
||||||
endif
|
endif
|
||||||
ifdef INSTALLED_RADIOIMAGE_TARGET
|
ifdef BOARD_KERNEL_BASE
|
||||||
@# The radio image
|
$(hide) echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/BOOT/base
|
||||||
$(hide) mkdir -p $(zip_root)/RADIO
|
|
||||||
$(hide) $(ACP) $(INSTALLED_RADIOIMAGE_TARGET) $(zip_root)/RADIO/image
|
|
||||||
endif
|
endif
|
||||||
|
$(hide) $(foreach t,$(INSTALLED_RADIOIMAGE_TARGET),\
|
||||||
|
mkdir -p $(zip_root)/RADIO; \
|
||||||
|
$(ACP) $(t) $(zip_root)/RADIO/$(notdir $(t));)
|
||||||
@# Contents of the system image
|
@# Contents of the system image
|
||||||
$(hide) $(call package_files-copy-root, \
|
$(hide) $(call package_files-copy-root, \
|
||||||
$(SYSTEMIMAGE_SOURCE_DIR),$(zip_root)/SYSTEM)
|
$(SYSTEMIMAGE_SOURCE_DIR),$(zip_root)/SYSTEM)
|
||||||
@@ -878,10 +890,11 @@ endif
|
|||||||
$(hide) echo "$(PRODUCT_OTA_PUBLIC_KEYS)" > $(zip_root)/META/otakeys.txt
|
$(hide) echo "$(PRODUCT_OTA_PUBLIC_KEYS)" > $(zip_root)/META/otakeys.txt
|
||||||
$(hide) echo "$(PRIVATE_RECOVERY_API_VERSION)" > $(zip_root)/META/recovery-api-version.txt
|
$(hide) echo "$(PRIVATE_RECOVERY_API_VERSION)" > $(zip_root)/META/recovery-api-version.txt
|
||||||
$(hide) echo "blocksize $(BOARD_FLASH_BLOCK_SIZE)" > $(zip_root)/META/imagesizes.txt
|
$(hide) echo "blocksize $(BOARD_FLASH_BLOCK_SIZE)" > $(zip_root)/META/imagesizes.txt
|
||||||
$(hide) echo "boot $(BOARD_BOOTIMAGE_MAX_SIZE)" >> $(zip_root)/META/imagesizes.txt
|
$(hide) echo "boot $(call image-size-from-data-size,$(BOARD_BOOTIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/imagesizes.txt
|
||||||
$(hide) echo "recovery $(BOARD_RECOVERYIMAGE_MAX_SIZE)" >> $(zip_root)/META/imagesizes.txt
|
$(hide) echo "recovery $(call image-size-from-data-size,$(BOARD_RECOVERYIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/imagesizes.txt
|
||||||
$(hide) echo "system $(BOARD_SYSTEMIMAGE_MAX_SIZE)" >> $(zip_root)/META/imagesizes.txt
|
$(hide) echo "system $(call image-size-from-data-size,$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/imagesizes.txt
|
||||||
$(hide) echo "userdata $(BOARD_USERDATAIMAGE_MAX_SIZE)" >> $(zip_root)/META/imagesizes.txt
|
$(hide) echo "userdata $(call image-size-from-data-size,$(BOARD_USERDATAIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/imagesizes.txt
|
||||||
|
$(hide) echo "$(tool_extensions)" > $(zip_root)/META/tool-extensions.txt
|
||||||
@# Zip everything up, preserving symlinks
|
@# Zip everything up, preserving symlinks
|
||||||
$(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .)
|
$(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .)
|
||||||
|
|
||||||
@@ -904,9 +917,17 @@ INTERNAL_OTA_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip
|
|||||||
|
|
||||||
$(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)
|
$(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)
|
||||||
|
|
||||||
|
ifeq ($(TARGET_OTA_SCRIPT_MODE),)
|
||||||
|
# default to "auto"
|
||||||
|
$(INTERNAL_OTA_PACKAGE_TARGET): scriptmode := auto
|
||||||
|
else
|
||||||
|
$(INTERNAL_OTA_PACKAGE_TARGET): scriptmode := $(TARGET_OTA_SCRIPT_MODE)
|
||||||
|
endif
|
||||||
|
|
||||||
$(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) otatools
|
$(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) otatools
|
||||||
@echo "Package OTA: $@"
|
@echo "Package OTA: $@"
|
||||||
$(hide) ./build/tools/releasetools/ota_from_target_files \
|
$(hide) ./build/tools/releasetools/ota_from_target_files \
|
||||||
|
-m $(scriptmode) \
|
||||||
-p $(HOST_OUT) \
|
-p $(HOST_OUT) \
|
||||||
-k $(KEY_CERT_PAIR) \
|
-k $(KEY_CERT_PAIR) \
|
||||||
$(BUILT_TARGET_FILES_PACKAGE) $@
|
$(BUILT_TARGET_FILES_PACKAGE) $@
|
||||||
@@ -1030,9 +1051,17 @@ name := $(name)-img-$(FILE_NAME_TAG)
|
|||||||
|
|
||||||
INTERNAL_UPDATE_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip
|
INTERNAL_UPDATE_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip
|
||||||
|
|
||||||
|
ifeq ($(TARGET_RELEASETOOLS_EXTENSIONS),)
|
||||||
|
# default to common dir for device vendor
|
||||||
|
$(INTERNAL_UPDATE_PACKAGE_TARGET): extensions := $(TARGET_DEVICE_DIR)/../common
|
||||||
|
else
|
||||||
|
$(INTERNAL_UPDATE_PACKAGE_TARGET): extensions := $(TARGET_RELEASETOOLS_EXTENSIONS)
|
||||||
|
endif
|
||||||
|
|
||||||
$(INTERNAL_UPDATE_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) otatools
|
$(INTERNAL_UPDATE_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) otatools
|
||||||
@echo "Package: $@"
|
@echo "Package: $@"
|
||||||
$(hide) ./build/tools/releasetools/img_from_target_files \
|
$(hide) ./build/tools/releasetools/img_from_target_files \
|
||||||
|
-s $(extensions) \
|
||||||
-p $(HOST_OUT) \
|
-p $(HOST_OUT) \
|
||||||
$(BUILT_TARGET_FILES_PACKAGE) $@
|
$(BUILT_TARGET_FILES_PACKAGE) $@
|
||||||
|
|
||||||
|
@@ -7,10 +7,10 @@ To make these errors go away, you have two choices:
|
|||||||
errors above.
|
errors above.
|
||||||
|
|
||||||
2) You can update current.xml by executing the following command:
|
2) You can update current.xml by executing the following command:
|
||||||
|
|
||||||
make update-api
|
make update-api
|
||||||
|
|
||||||
To check in the revised current.xml, you will need approval from the android API council.
|
To submit the revised current.xml to the main Android repository,
|
||||||
|
you will need approval.
|
||||||
******************************
|
******************************
|
||||||
|
|
||||||
|
|
||||||
|
@@ -272,8 +272,10 @@ $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_SOURCE_INTERMEDIATES_DIR := $(intermediat
|
|||||||
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JAVA_SOURCES := $(all_java_sources)
|
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JAVA_SOURCES := $(all_java_sources)
|
||||||
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JAVA_OBJECTS := $(patsubst %.java,%.class,$(LOCAL_SRC_FILES))
|
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JAVA_OBJECTS := $(patsubst %.java,%.class,$(LOCAL_SRC_FILES))
|
||||||
ifeq ($(my_prefix),TARGET_)
|
ifeq ($(my_prefix),TARGET_)
|
||||||
|
ifeq ($(LOCAL_SDK_VERSION),)
|
||||||
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH := -bootclasspath $(call java-lib-files,core)
|
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH := -bootclasspath $(call java-lib-files,core)
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_RESOURCE_DIR := $(LOCAL_RESOURCE_DIR)
|
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_RESOURCE_DIR := $(LOCAL_RESOURCE_DIR)
|
||||||
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_EXTRA_JAR_ARGS := $(extra_jar_args)
|
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_EXTRA_JAR_ARGS := $(extra_jar_args)
|
||||||
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ASSET_DIR := $(LOCAL_ASSET_DIR)
|
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ASSET_DIR := $(LOCAL_ASSET_DIR)
|
||||||
@@ -350,7 +352,6 @@ $(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_PATH:=$(LOCAL_PATH)
|
|||||||
$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_POST_PROCESS_COMMAND:= $(LOCAL_POST_PROCESS_COMMAND)
|
$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_POST_PROCESS_COMMAND:= $(LOCAL_POST_PROCESS_COMMAND)
|
||||||
$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_AAPT_FLAGS:= $(LOCAL_AAPT_FLAGS)
|
$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_AAPT_FLAGS:= $(LOCAL_AAPT_FLAGS)
|
||||||
$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_JAVA_LIBRARIES:= $(LOCAL_JAVA_LIBRARIES)
|
$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_JAVA_LIBRARIES:= $(LOCAL_JAVA_LIBRARIES)
|
||||||
#TODO: add this: $(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_ADDITIONAL_DEPENDENCIES:= $(LOCAL_ADDITIONAL_DEPENDENCIES)
|
|
||||||
|
|
||||||
$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_ALL_JAVA_LIBRARIES:= $(full_java_libs)
|
$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_ALL_JAVA_LIBRARIES:= $(full_java_libs)
|
||||||
$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_IS_HOST_MODULE := $(LOCAL_IS_HOST_MODULE)
|
$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_IS_HOST_MODULE := $(LOCAL_IS_HOST_MODULE)
|
||||||
|
@@ -87,7 +87,7 @@ yacc_objects := $(yacc_cpps:$(LOCAL_CPP_EXTENSION)=.o)
|
|||||||
ifneq ($(strip $(yacc_cpps)),)
|
ifneq ($(strip $(yacc_cpps)),)
|
||||||
$(yacc_cpps): $(intermediates)/%$(LOCAL_CPP_EXTENSION): \
|
$(yacc_cpps): $(intermediates)/%$(LOCAL_CPP_EXTENSION): \
|
||||||
$(TOPDIR)$(LOCAL_PATH)/%.y \
|
$(TOPDIR)$(LOCAL_PATH)/%.y \
|
||||||
$(lex_cpps) $(PRIVATE_ADDITIONAL_DEPENDENCIES)
|
$(lex_cpps) $(LOCAL_ADDITIONAL_DEPENDENCIES)
|
||||||
$(call transform-y-to-cpp,$(PRIVATE_CPP_EXTENSION))
|
$(call transform-y-to-cpp,$(PRIVATE_CPP_EXTENSION))
|
||||||
$(yacc_headers): $(intermediates)/%.h: $(intermediates)/%$(LOCAL_CPP_EXTENSION)
|
$(yacc_headers): $(intermediates)/%.h: $(intermediates)/%$(LOCAL_CPP_EXTENSION)
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ $(lex_objects): PRIVATE_ARM_MODE := $(normal_objects_mode)
|
|||||||
$(lex_objects): PRIVATE_ARM_CFLAGS := $(normal_objects_cflags)
|
$(lex_objects): PRIVATE_ARM_CFLAGS := $(normal_objects_cflags)
|
||||||
$(lex_objects): $(intermediates)/%.o: \
|
$(lex_objects): $(intermediates)/%.o: \
|
||||||
$(intermediates)/%$(LOCAL_CPP_EXTENSION) \
|
$(intermediates)/%$(LOCAL_CPP_EXTENSION) \
|
||||||
$(PRIVATE_ADDITIONAL_DEPENDENCIES) \
|
$(LOCAL_ADDITIONAL_DEPENDENCIES) \
|
||||||
$(yacc_headers)
|
$(yacc_headers)
|
||||||
$(transform-$(PRIVATE_HOST)cpp-to-o)
|
$(transform-$(PRIVATE_HOST)cpp-to-o)
|
||||||
endif
|
endif
|
||||||
@@ -142,7 +142,7 @@ cpp_objects := $(cpp_arm_objects) $(cpp_normal_objects)
|
|||||||
ifneq ($(strip $(cpp_objects)),)
|
ifneq ($(strip $(cpp_objects)),)
|
||||||
$(cpp_objects): $(intermediates)/%.o: \
|
$(cpp_objects): $(intermediates)/%.o: \
|
||||||
$(TOPDIR)$(LOCAL_PATH)/%$(LOCAL_CPP_EXTENSION) \
|
$(TOPDIR)$(LOCAL_PATH)/%$(LOCAL_CPP_EXTENSION) \
|
||||||
$(yacc_cpps) $(PRIVATE_ADDITIONAL_DEPENDENCIES)
|
$(yacc_cpps) $(LOCAL_ADDITIONAL_DEPENDENCIES)
|
||||||
$(transform-$(PRIVATE_HOST)cpp-to-o)
|
$(transform-$(PRIVATE_HOST)cpp-to-o)
|
||||||
-include $(cpp_objects:%.o=%.P)
|
-include $(cpp_objects:%.o=%.P)
|
||||||
endif
|
endif
|
||||||
@@ -159,7 +159,7 @@ ifneq ($(strip $(gen_cpp_objects)),)
|
|||||||
# TODO: support compiling certain generated files as arm.
|
# TODO: support compiling certain generated files as arm.
|
||||||
$(gen_cpp_objects): PRIVATE_ARM_MODE := $(normal_objects_mode)
|
$(gen_cpp_objects): PRIVATE_ARM_MODE := $(normal_objects_mode)
|
||||||
$(gen_cpp_objects): PRIVATE_ARM_CFLAGS := $(normal_objects_cflags)
|
$(gen_cpp_objects): PRIVATE_ARM_CFLAGS := $(normal_objects_cflags)
|
||||||
$(gen_cpp_objects): $(intermediates)/%.o: $(intermediates)/%$(LOCAL_CPP_EXTENSION) $(yacc_cpps) $(PRIVATE_ADDITIONAL_DEPENDENCIES)
|
$(gen_cpp_objects): $(intermediates)/%.o: $(intermediates)/%$(LOCAL_CPP_EXTENSION) $(yacc_cpps) $(LOCAL_ADDITIONAL_DEPENDENCIES)
|
||||||
$(transform-$(PRIVATE_HOST)cpp-to-o)
|
$(transform-$(PRIVATE_HOST)cpp-to-o)
|
||||||
-include $(gen_cpp_objects:%.o=%.P)
|
-include $(gen_cpp_objects:%.o=%.P)
|
||||||
endif
|
endif
|
||||||
@@ -172,7 +172,7 @@ gen_S_sources := $(filter %.S,$(LOCAL_GENERATED_SOURCES))
|
|||||||
gen_S_objects := $(gen_S_sources:%.S=%.o)
|
gen_S_objects := $(gen_S_sources:%.S=%.o)
|
||||||
|
|
||||||
ifneq ($(strip $(gen_S_sources)),)
|
ifneq ($(strip $(gen_S_sources)),)
|
||||||
$(gen_S_objects): $(intermediates)/%.o: $(intermediates)/%.S $(PRIVATE_ADDITIONAL_DEPENDENCIES)
|
$(gen_S_objects): $(intermediates)/%.o: $(intermediates)/%.S $(LOCAL_ADDITIONAL_DEPENDENCIES)
|
||||||
$(transform-$(PRIVATE_HOST)s-to-o)
|
$(transform-$(PRIVATE_HOST)s-to-o)
|
||||||
-include $(gen_S_objects:%.o=%.P)
|
-include $(gen_S_objects:%.o=%.P)
|
||||||
endif
|
endif
|
||||||
@@ -181,7 +181,7 @@ gen_s_sources := $(filter %.s,$(LOCAL_GENERATED_SOURCES))
|
|||||||
gen_s_objects := $(gen_s_sources:%.s=%.o)
|
gen_s_objects := $(gen_s_sources:%.s=%.o)
|
||||||
|
|
||||||
ifneq ($(strip $(gen_s_objects)),)
|
ifneq ($(strip $(gen_s_objects)),)
|
||||||
$(gen_s_objects): $(intermediates)/%.o: $(intermediates)/%.s $(PRIVATE_ADDITIONAL_DEPENDENCIES)
|
$(gen_s_objects): $(intermediates)/%.o: $(intermediates)/%.s $(LOCAL_ADDITIONAL_DEPENDENCIES)
|
||||||
$(transform-$(PRIVATE_HOST)s-to-o-no-deps)
|
$(transform-$(PRIVATE_HOST)s-to-o-no-deps)
|
||||||
-include $(gen_s_objects:%.o=%.P)
|
-include $(gen_s_objects:%.o=%.P)
|
||||||
endif
|
endif
|
||||||
@@ -206,11 +206,28 @@ $(c_normal_objects): PRIVATE_ARM_CFLAGS := $(normal_objects_cflags)
|
|||||||
c_objects := $(c_arm_objects) $(c_normal_objects)
|
c_objects := $(c_arm_objects) $(c_normal_objects)
|
||||||
|
|
||||||
ifneq ($(strip $(c_objects)),)
|
ifneq ($(strip $(c_objects)),)
|
||||||
$(c_objects): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.c $(yacc_cpps) $(PRIVATE_ADDITIONAL_DEPENDENCIES)
|
$(c_objects): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.c $(yacc_cpps) $(LOCAL_ADDITIONAL_DEPENDENCIES)
|
||||||
$(transform-$(PRIVATE_HOST)c-to-o)
|
$(transform-$(PRIVATE_HOST)c-to-o)
|
||||||
-include $(c_objects:%.o=%.P)
|
-include $(c_objects:%.o=%.P)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
###########################################################
|
||||||
|
## C: Compile generated .c files to .o.
|
||||||
|
###########################################################
|
||||||
|
|
||||||
|
gen_c_sources := $(filter %.c,$(LOCAL_GENERATED_SOURCES))
|
||||||
|
gen_c_objects := $(gen_c_sources:%.c=%.o)
|
||||||
|
|
||||||
|
ifneq ($(strip $(gen_c_objects)),)
|
||||||
|
# Compile all generated files as thumb.
|
||||||
|
# TODO: support compiling certain generated files as arm.
|
||||||
|
$(gen_c_objects): PRIVATE_ARM_MODE := $(normal_objects_mode)
|
||||||
|
$(gen_c_objects): PRIVATE_ARM_CFLAGS := $(normal_objects_cflags)
|
||||||
|
$(gen_c_objects): $(intermediates)/%.o: $(intermediates)/%.c $(yacc_cpps) $(LOCAL_ADDITIONAL_DEPENDENCIES)
|
||||||
|
$(transform-$(PRIVATE_HOST)c-to-o)
|
||||||
|
-include $(gen_c_objects:%.o=%.P)
|
||||||
|
endif
|
||||||
|
|
||||||
###########################################################
|
###########################################################
|
||||||
## ObjC: Compile .m files to .o
|
## ObjC: Compile .m files to .o
|
||||||
###########################################################
|
###########################################################
|
||||||
@@ -232,7 +249,7 @@ asm_sources_S := $(filter %.S,$(LOCAL_SRC_FILES))
|
|||||||
asm_objects_S := $(addprefix $(intermediates)/,$(asm_sources_S:.S=.o))
|
asm_objects_S := $(addprefix $(intermediates)/,$(asm_sources_S:.S=.o))
|
||||||
|
|
||||||
ifneq ($(strip $(asm_objects_S)),)
|
ifneq ($(strip $(asm_objects_S)),)
|
||||||
$(asm_objects_S): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.S $(PRIVATE_ADDITIONAL_DEPENDENCIES)
|
$(asm_objects_S): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.S $(LOCAL_ADDITIONAL_DEPENDENCIES)
|
||||||
$(transform-$(PRIVATE_HOST)s-to-o)
|
$(transform-$(PRIVATE_HOST)s-to-o)
|
||||||
-include $(asm_objects_S:%.o=%.P)
|
-include $(asm_objects_S:%.o=%.P)
|
||||||
endif
|
endif
|
||||||
@@ -241,7 +258,7 @@ asm_sources_s := $(filter %.s,$(LOCAL_SRC_FILES))
|
|||||||
asm_objects_s := $(addprefix $(intermediates)/,$(asm_sources_s:.s=.o))
|
asm_objects_s := $(addprefix $(intermediates)/,$(asm_sources_s:.s=.o))
|
||||||
|
|
||||||
ifneq ($(strip $(asm_objects_s)),)
|
ifneq ($(strip $(asm_objects_s)),)
|
||||||
$(asm_objects_s): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.s $(PRIVATE_ADDITIONAL_DEPENDENCIES)
|
$(asm_objects_s): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.s $(LOCAL_ADDITIONAL_DEPENDENCIES)
|
||||||
$(transform-$(PRIVATE_HOST)s-to-o-no-deps)
|
$(transform-$(PRIVATE_HOST)s-to-o-no-deps)
|
||||||
-include $(asm_objects_s:%.o=%.P)
|
-include $(asm_objects_s:%.o=%.P)
|
||||||
endif
|
endif
|
||||||
@@ -261,6 +278,7 @@ all_objects := \
|
|||||||
$(gen_cpp_objects) \
|
$(gen_cpp_objects) \
|
||||||
$(gen_asm_objects) \
|
$(gen_asm_objects) \
|
||||||
$(c_objects) \
|
$(c_objects) \
|
||||||
|
$(gen_c_objects) \
|
||||||
$(yacc_objects) \
|
$(yacc_objects) \
|
||||||
$(lex_objects) \
|
$(lex_objects) \
|
||||||
$(addprefix $(TOPDIR)$(LOCAL_PATH)/,$(LOCAL_PREBUILT_OBJ_FILES))
|
$(addprefix $(TOPDIR)$(LOCAL_PATH)/,$(LOCAL_PREBUILT_OBJ_FILES))
|
||||||
|
947
core/build-system.html
Normal file
947
core/build-system.html
Normal file
@@ -0,0 +1,947 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
A lot of people read this document template. Please keep it clean:
|
||||||
|
|
||||||
|
- keep the document xhtml-compliant, as many people use validating editors
|
||||||
|
- check your edits for typos, spelling errors, and questionable grammar
|
||||||
|
- prefer css styles to formatting tags like <font>, <tt>, etc.
|
||||||
|
- keep it human-readable and human-editable in a plain text editor:
|
||||||
|
- strive to keep lines wrapped at 80 columns, unless a link prevents it
|
||||||
|
- use plenty of whitespace
|
||||||
|
- try to pretty-format (wrt nesting and indenting) any hairy html
|
||||||
|
- check your inline javascript for errors using the javascript console
|
||||||
|
|
||||||
|
Your readers will be very appreciative.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Android Build System</title>
|
||||||
|
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
|
||||||
|
<link href="../android.css" type="text/css" rel="stylesheet" />
|
||||||
|
|
||||||
|
<!-- commenting out so the xhtml validator doesn't whine about < and &&;
|
||||||
|
the browser should still find the script tag. -->
|
||||||
|
<script language="JavaScript1.2" type="text/javascript">
|
||||||
|
<!--
|
||||||
|
function highlight(name) {
|
||||||
|
if (document.getElementsByTagName) {
|
||||||
|
tags = [ 'span', 'div', 'tr', 'td' ];
|
||||||
|
for (i in tags) {
|
||||||
|
elements = document.getElementsByTagName(tags[i]);
|
||||||
|
if (elements) {
|
||||||
|
for (j = 0; j < elements.length; j++) {
|
||||||
|
elementName = elements[j].getAttribute("class");
|
||||||
|
if (elementName == name) {
|
||||||
|
elements[j].style.backgroundColor = "#C0F0C0";
|
||||||
|
} else if (elementName && elementName.indexOf("rev") == 0) {
|
||||||
|
elements[j].style.backgroundColor = "#FFFFFF";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//-->
|
||||||
|
</script>
|
||||||
|
<!-- this style sheet is for the style of the toc -->
|
||||||
|
<link href="toc.css" type="text/css" rel="stylesheet" />
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
.warning {
|
||||||
|
border: 1px solid red;
|
||||||
|
padding: 8px;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
pre.prettyprint {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body onload="prettyPrint()">
|
||||||
|
|
||||||
|
<h1><a name="My_Project_" />Android Build System</h1>
|
||||||
|
|
||||||
|
<!-- Status is one of: Draft, Current, Needs Update, Obsolete -->
|
||||||
|
<p style="text-align:center">
|
||||||
|
<strong>Status:</strong> <em>Draft </em>
|
||||||
|
<small>(as of May 18, 2006)</small>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><b>Contents</b></p>
|
||||||
|
<!-- this div expands out to a list of contents based on the H2 and H3 headings.
|
||||||
|
Believe it! -->
|
||||||
|
<div id="nav" class="nav-2-levels"></div>
|
||||||
|
|
||||||
|
<h2>Objective</h2>
|
||||||
|
<p>The primary goals of reworking the build system are (1) to make dependencies
|
||||||
|
work more reliably, so that when files need to rebuilt, they are, and (2) to
|
||||||
|
improve performance of the build system so that unnecessary modules are not
|
||||||
|
rebuilt, and so doing a top-level build when little or nothing needs to be done
|
||||||
|
for a build takes as little time as possible.</p>
|
||||||
|
|
||||||
|
<h2>Principles and Use Cases and Policy</h2>
|
||||||
|
<p>Given the above objective, these are the overall principles and use cases
|
||||||
|
that we will support. This is not an exhaustive list.</p>
|
||||||
|
<h3>Multiple Targets</h3>
|
||||||
|
<p>It needs to be possible to build the Android platform for multiple targets.
|
||||||
|
This means:</p>
|
||||||
|
<ul>
|
||||||
|
<li>The build system will support building tools for the host platform,
|
||||||
|
both ones that are used in the build process itself, and developer tools
|
||||||
|
like the simulator.</li>
|
||||||
|
<li>The build system will need to be able to build tools on Linux
|
||||||
|
(definitely Goobuntu and maybe Grhat), MacOS, and to some degree on
|
||||||
|
Windows.</li>
|
||||||
|
<li>The build system will need to be able to build the OS on Linux, and in
|
||||||
|
the short-term, MacOS. Note that this is a conscious decision to stop
|
||||||
|
building the OS on Windows. We are going to rely on the emulator there
|
||||||
|
and not attempt to use the simulator. This is a requirement change now
|
||||||
|
that the emulator story is looking brighter.</li>
|
||||||
|
</ul>
|
||||||
|
<h3>Non-Recursive Make</h3>
|
||||||
|
<p>To achieve the objectives, the build system will be rewritten to use make
|
||||||
|
non-recursively. For more background on this, read <a href="http://aegis.sourceforge.net/auug97.pdf">Recursive Make Considered Harmful</a>. For those that don't
|
||||||
|
want PDF, here is the
|
||||||
|
<a href="http://72.14.203.104/search?q=cache:HwuX7YF2uBIJ:aegis.sourceforge.net/auug97.pdf&hl=en&gl=us&ct=clnk&cd=2&client=firefox">Google translated version</a>.
|
||||||
|
<h3>Rapid Compile-Test Cycles</h3>
|
||||||
|
<p>When developing a component, for example a C++ shared library, it must be
|
||||||
|
possible to easily rebuild just that component, and not have to wait more than a
|
||||||
|
couple seconds for dependency checks, and not have to wait for unneeded
|
||||||
|
components to be built.</p>
|
||||||
|
<h3>Both Environment and Config File Based Settings</h3>
|
||||||
|
<p>To set the target, and other options, some people on the team like to have a
|
||||||
|
configuration file in a directory so they do not have an environment setup
|
||||||
|
script to run, and others want an environment setup script to run so they can
|
||||||
|
run builds in different terminals on the same tree, or switch back and forth
|
||||||
|
in one terminal. We will support both.</p>
|
||||||
|
<h3>Object File Directory / make clean</h3>
|
||||||
|
<p>Object files and other intermediate files will be generated into a directory
|
||||||
|
that is separate from the source tree. The goal is to have make clean be
|
||||||
|
"rm -rf <obj>" in the tree root directory. The primary goals of
|
||||||
|
this are to simplify searching the source tree, and to make "make clean" more
|
||||||
|
reliable.</p>
|
||||||
|
|
||||||
|
<h3>SDK</h3>
|
||||||
|
<p>The SDK will be a tarball that will allow non-OS-developers to write apps.
|
||||||
|
The apps will actually be built by first building the SDK, and then building
|
||||||
|
the apps against that SDK. This will hopefully (1) make writing apps easier
|
||||||
|
for us, because we won't have to rebuild the OS as much, and we can use the
|
||||||
|
standard java-app development tools, and (2) allow us to dog-food the SDK, to
|
||||||
|
help ensure its quality. Cedric has suggested (and I agree) that apps built
|
||||||
|
from the SDK should be built with ant. Stay tuned for more details as we
|
||||||
|
figure out exactly how this will work.</p>
|
||||||
|
|
||||||
|
<h3>Dependecies</h3>
|
||||||
|
<p>Dependencies should all be automatic. Unless there is a custom tool involved
|
||||||
|
(e.g. the webkit has several), the dependencies for shared and static libraries,
|
||||||
|
.c, .cpp, .h, .java, java libraries, etc., should all work without intervention
|
||||||
|
in the Android.mk file.</p>
|
||||||
|
|
||||||
|
<h3>Hiding command lines</h3>
|
||||||
|
<p>The default of the build system will be to hide the command lines being
|
||||||
|
executed for make steps. It will be possible to override this by specifying
|
||||||
|
the showcommands pseudo-target, and possibly by setting an environment
|
||||||
|
variable.</p>
|
||||||
|
|
||||||
|
<h3>Wildcard source files</h3>
|
||||||
|
<p>Wildcarding source file will be discouraged. It may be useful in some
|
||||||
|
scenarios. The default <code>$(wildcard *)</code> will not work due to the
|
||||||
|
current directory being set to the root of the build tree.<p>
|
||||||
|
|
||||||
|
<h3>Multiple targets in one directory</h3>
|
||||||
|
<p>It will be possible to generate more than one target from a given
|
||||||
|
subdirectory. For example, libutils generates a shared library for the target
|
||||||
|
and a static library for the host.</p>
|
||||||
|
|
||||||
|
<h3>Makefile fragments for modules</h3>
|
||||||
|
<p><b>Android.mk</b> is the standard name for the makefile fragments that
|
||||||
|
control the building of a given module. Only the top directory should
|
||||||
|
have a file named "Makefile".</p>
|
||||||
|
|
||||||
|
<h3>Use shared libraries</h3>
|
||||||
|
<p>Currently, the simulator is not built to use shared libraries. This should
|
||||||
|
be fixed, and now is a good time to do it. This implies getting shared
|
||||||
|
libraries to work on Mac OS.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Nice to Have</h2>
|
||||||
|
|
||||||
|
<p>These things would be nice to have, and this is a good place to record them,
|
||||||
|
however these are not promises.</p>
|
||||||
|
|
||||||
|
<h3>Simultaneous Builds</h3>
|
||||||
|
<p>The hope is to be able to do two builds for different combos in the same
|
||||||
|
tree at the same time, but this is a stretch goal, not a requirement.
|
||||||
|
Doing two builds in the same tree, not at the same time must work. (update:
|
||||||
|
it's looking like we'll get the two builds at the same time working)</p>
|
||||||
|
|
||||||
|
<h3>Deleting headers (or other dependecies)</h3>
|
||||||
|
<p>Problems can arise if you delete a header file that is referenced in
|
||||||
|
".d" files. The easy way to deal with this is "make clean". There
|
||||||
|
should be a better way to handle it. (from fadden)</p>
|
||||||
|
<p>One way of solving this is introducing a dependency on the directory. The
|
||||||
|
problem is that this can create extra dependecies and slow down the build.
|
||||||
|
It's a tradeoff.</p>
|
||||||
|
|
||||||
|
<h3>Multiple builds</h3>
|
||||||
|
<p>General way to perform builds across the set of known platforms. This
|
||||||
|
would make it easy to perform multiple platform builds when testing a
|
||||||
|
change, and allow a wide-scale "make clean". Right now the buildspec.mk
|
||||||
|
or environment variables need to be updated before each build. (from fadden)</p>
|
||||||
|
|
||||||
|
<h3>Aftermarket Locales and Carrier</h3>
|
||||||
|
<p>We will eventually need to add support for creating locales and carrier
|
||||||
|
customizations to the SDK, but that will not be addressed right now.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<h2><a id="usage"/>Usage</h2>
|
||||||
|
<p>You've read (or scrolled past) all of the motivations for this build system,
|
||||||
|
and you want to know how to use it. This is the place.</p>
|
||||||
|
|
||||||
|
<h3>Your first build</h3>
|
||||||
|
<p>The <a href="../building.html">Building</a> document describes how do do
|
||||||
|
builds.</p>
|
||||||
|
|
||||||
|
<h3>build/envsetup.sh functions</h3>
|
||||||
|
If you source the file build/envsetup.sh into your bash environment,
|
||||||
|
<code>. build/envsetup.sh</code>you'll get a few helpful shell functions:
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><b>printconfig</b> - Prints the current configuration as set by the
|
||||||
|
lunch and choosecombo commands.</li>
|
||||||
|
<li><b>m</b> - Runs <code>make</code> from the top of the tree. This is
|
||||||
|
useful because you can run make from within subdirectories. If you have the
|
||||||
|
<code>TOP</code> environment variable set, it uses that. If you don't, it looks
|
||||||
|
up the tree from the current directory, trying to find the top of the tree.</li>
|
||||||
|
<li><b>croot</b> - <code>cd</code> to the top of the tree.</li>
|
||||||
|
<li><b>sgrep</b> - grep for the regex you provide in all .c, .cpp, .h, .java,
|
||||||
|
and .xml files below the current directory.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>Build flavors/types</h3>
|
||||||
|
<p>
|
||||||
|
When building for a particular product, it's often useful to have minor
|
||||||
|
variations on what is ultimately the final release build. These are the
|
||||||
|
currently-defined "flavors" or "types" (we need to settle on a real name
|
||||||
|
for these).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<table border=1>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>eng<code>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
This is the default flavor. A plain "<code>make</code>" is the
|
||||||
|
same as "<code>make eng</code>". <code>droid</code> is an alias
|
||||||
|
for <code>eng</code>.
|
||||||
|
<ul>
|
||||||
|
<li>Installs modules tagged with: <code>eng</code>, <code>debug</code>,
|
||||||
|
<code>user</code>, and/or <code>development</code>.
|
||||||
|
<li>Installs non-APK modules that have no tags specified.
|
||||||
|
<li>Installs APKs according to the product definition files, in
|
||||||
|
addition to tagged APKs.
|
||||||
|
<li><code>ro.secure=0</code>
|
||||||
|
<li><code>ro.debuggable=1</code>
|
||||||
|
<li><code>ro.kernel.android.checkjni=1</code>
|
||||||
|
<li><code>adb</code> is enabled by default.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>user<code>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
"<code>make user</code>"
|
||||||
|
<p>
|
||||||
|
This is the flavor intended to be the final release bits.
|
||||||
|
<ul>
|
||||||
|
<li>Installs modules tagged with <code>user</code>.
|
||||||
|
<li>Installs non-APK modules that have no tags specified.
|
||||||
|
<li>Installs APKs according to the product definition files; tags
|
||||||
|
are ignored for APK modules.
|
||||||
|
<li><code>ro.secure=1</code>
|
||||||
|
<li><code>ro.debuggable=0</code>
|
||||||
|
<li><code>adb</code> is disabled by default.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>userdebug<code>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
"<code>make userdebug</code>"
|
||||||
|
<p>
|
||||||
|
The same as <code>user</code>, except:
|
||||||
|
<ul>
|
||||||
|
<li>Also installs modules tagged with <code>debug</code>.
|
||||||
|
<li><code>ro.debuggable=1</code>
|
||||||
|
<li><code>adb</code> is enabled by default.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If you build one flavor and then want to build another, you should run
|
||||||
|
"<code>make installclean</code>" between the two makes to guarantee that
|
||||||
|
you don't pick up files installed by the previous flavor. "<code>make
|
||||||
|
clean</code>" will also suffice, but it takes a lot longer.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<h3>More pseudotargets</h3>
|
||||||
|
<p>Sometimes you want to just build one thing. The following pseudotargets are
|
||||||
|
there for your convenience:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><b>droid</b> - <code>make droid</code> is the normal build. This target
|
||||||
|
is here because the default target has to have a name.</li>
|
||||||
|
<li><b>all</b> - <code>make all</code> builds everything <code>make
|
||||||
|
droid</code> does, plus everything whose <code>LOCAL_MODULE_TAGS</code> do not
|
||||||
|
include the "droid" tag. The build server runs this to make sure
|
||||||
|
that everything that is in the tree and has an Android.mk builds.</li>
|
||||||
|
<li><b>clean-$(LOCAL_MODULE)</b> and <b>clean-$(LOCAL_PACKAGE_NAME)</b> -
|
||||||
|
Let you selectively clean one target. For example, you can type
|
||||||
|
<code>make clean-libutils</code> and it will delete libutils.so and all of the
|
||||||
|
intermediate files, or you can type <code>make clean-Home</code> and it will
|
||||||
|
clean just the Home app.</li>
|
||||||
|
<li><b>clean</b> - <code>make clean</code> deletes all of the output and
|
||||||
|
intermediate files for this configuration. This is the same as <code>rm -rf
|
||||||
|
out/<configuration>/</code></li>
|
||||||
|
<li><b>clobber</b> - <code>make clobber</code> deletes all of the output
|
||||||
|
and intermediate files for all configurations. This is the same as
|
||||||
|
<code>rm -rf out/</code>.</li>
|
||||||
|
<li><b>dataclean</b> - <code>make dataclean</code> deletes contents of the data
|
||||||
|
directory inside the current combo directory. This is especially useful on the
|
||||||
|
simulator and emulator, where the persistent data remains present between
|
||||||
|
builds.</li>
|
||||||
|
<li><b>showcommands</b> - <code>showcommands</code> is a modifier target
|
||||||
|
which causes the build system to show the actual command lines for the build
|
||||||
|
steps, instead of the brief descriptions. Most people don't like seeing the
|
||||||
|
actual commands, because they're quite long and hard to read, but if you need
|
||||||
|
to for debugging purposes, you can add <code>showcommands</code> to the list
|
||||||
|
of targets you build. For example <code>make showcommands</code> will build
|
||||||
|
the default android configuration, and <code>make runtime showcommands</code>
|
||||||
|
will build just the runtime, and targets that it depends on, while displaying
|
||||||
|
the full command lines. Please note that there are a couple places where the
|
||||||
|
commands aren't shown here. These are considered bugs, and should be fixed,
|
||||||
|
but they're often hard to track down. Please let
|
||||||
|
<a href="mailto:android-build-team">android-build-team</a> know if you find
|
||||||
|
any.</li>
|
||||||
|
<li><b>LOCAL_MODULE</b> - Anything you specify as a <code>LOCAL_MODULE</code>
|
||||||
|
in an Android.mk is made into a pseudotarget. For example, <code>make
|
||||||
|
runtime</code> might be shorthand for <code>make
|
||||||
|
out/linux-x86-debug/system/bin/runtime</code> (which would work), and
|
||||||
|
<code>make libkjs</code> might be shorthand for <code>make
|
||||||
|
out/linux-x86-debug/system/lib/libkjs.so</code> (which would also work).</li>
|
||||||
|
<li><b>targets</b> - <code>make targets</code> will print a list of all of
|
||||||
|
the LOCAL_MODULE names you can make.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3><a name="templates"/>How to add another component to the build - Android.mk templates</h3>
|
||||||
|
<p>You have a new library, a new app, or a new executable. For each of the
|
||||||
|
common types of modules, there is a corresponding file in the templates
|
||||||
|
directory. It will usually be enough to copy one of these, and fill in your
|
||||||
|
own values. Some of the more esoteric values are not included in the
|
||||||
|
templates, but are instead just documented here, as is the documentation
|
||||||
|
on using custom tools to generate files.</p>
|
||||||
|
<p>Mostly, you can just look for the TODO comments in the templates and do
|
||||||
|
what it says. Please remember to delete the TODO comments when you're done
|
||||||
|
to keep the files clean. The templates have minimal documentation in them,
|
||||||
|
because they're going to be copied, and when that gets stale, the copies just
|
||||||
|
won't get updated. So read on...</p>
|
||||||
|
|
||||||
|
<h4>Apps</h4>
|
||||||
|
<p>Use the <code>templates/apps</code> file.</p>
|
||||||
|
<p>This template is pretty self-explanitory. See the variables below for more
|
||||||
|
details.</p>
|
||||||
|
|
||||||
|
<h4>Java Libraries</h4>
|
||||||
|
<p>Use the <code>templates/java_library</code> file.</p>
|
||||||
|
<p>The interesting thing here is the value of LOCAL_MODULE, which becomes
|
||||||
|
the name of the jar file. (Actually right now, we're not making jar files yet,
|
||||||
|
just directories of .class files, but the directory is named according to
|
||||||
|
what you put in LOCAL_MODULE). This name will be what goes in the
|
||||||
|
LOCAL_JAVA_LIBRARIES variable in modules that depend on your java library.</p>
|
||||||
|
|
||||||
|
<h4>C/C++ Executables</h4>
|
||||||
|
<p>Use the <code>templates/executable</code> file, or the
|
||||||
|
<code>templates/executable_host</code> file.</p>
|
||||||
|
<p>This template has a couple extra options that you usually don't need.
|
||||||
|
Please delete the ones you don't need, and remove the TODO comments. It makes
|
||||||
|
the rest of them easier to read, and you can always refer back to the templates
|
||||||
|
if you need them again later.</p>
|
||||||
|
<p>By default, on the target these are built into /system/bin, and on the
|
||||||
|
host, they're built into <combo>/host/bin. These can be overridden by setting
|
||||||
|
<code>LOCAL_MODULE_PATH</code>. See
|
||||||
|
<a href="#moving-targets">Putting targets elsewhere</a>
|
||||||
|
for more.</p>
|
||||||
|
|
||||||
|
<h4>Shared Libraries</h4>
|
||||||
|
<p>Use the <code>templates/shared_library</code> file, or the
|
||||||
|
<code>templates/shared_library_host</code> file.</p>
|
||||||
|
<p>Remember that on the target, we use shared libraries, and on the host,
|
||||||
|
we use static libraries, since executable size isn't as big an issue, and it
|
||||||
|
simplifies distribution in the SDK.</p>
|
||||||
|
|
||||||
|
<h4>Static Libraries</h4>
|
||||||
|
<p>Use the <code>templates/static_library</code> file, or the
|
||||||
|
<code>templates/static_library_host</code> file.</p>
|
||||||
|
<p>Remember that on the target, we use shared libraries, and on the host,
|
||||||
|
we use static libraries, since executable size isn't as big an issue, and it
|
||||||
|
simplifies distribution in the SDK.</p>
|
||||||
|
|
||||||
|
<h4><a name="custom-tools"/>Using Custom Tools</h4>
|
||||||
|
<p>If you have a tool that generates source files for you, it's possible
|
||||||
|
to have the build system get the dependencies correct for it. Here are
|
||||||
|
a couple of examples. <code>$@</code> is the make built-in variable for
|
||||||
|
"the current target." The <font color=red>red</font> parts are the parts you'll
|
||||||
|
need to change.</p>
|
||||||
|
|
||||||
|
<p>You need to put this after you have declared <code>LOCAL_PATH</code> and
|
||||||
|
<code>LOCAL_MODULE</code>, because the <code>$(local-intermediates-dir)</code>
|
||||||
|
and <code>$(local-host-intermediates-dir)</code> macros use these variables
|
||||||
|
to determine where to put the files.
|
||||||
|
|
||||||
|
<h5>Example 1</h5>
|
||||||
|
<p>Here, there is one generated file, called
|
||||||
|
chartables.c, which doesn't depend on anything. And is built by the tool
|
||||||
|
built to $(HOST_OUT_EXECUTABLES)/dftables. Note on the second to last line
|
||||||
|
that a dependency is created on the tool.</p>
|
||||||
|
<pre>
|
||||||
|
intermediates:= $(local-intermediates-dir)
|
||||||
|
GEN := $(intermediates)/<font color=red>chartables.c</font>
|
||||||
|
$(GEN): PRIVATE_CUSTOM_TOOL = <font color=red>$(HOST_OUT_EXECUTABLES)/dftables $@</font>
|
||||||
|
$(GEN): <font color=red>$(HOST_OUT_EXECUTABLES)/dftables</font>
|
||||||
|
$(transform-generated-source)
|
||||||
|
LOCAL_GENERATED_SOURCES += $(GEN)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h5>Example 2</h5>
|
||||||
|
<p>Here as a hypothetical example, we use use cat as if it were to transform
|
||||||
|
a file. Pretend that it does something useful. Note how we use a
|
||||||
|
target-specific variable called PRIVATE_INPUT_FILE to store the name of the
|
||||||
|
input file.</p>
|
||||||
|
<pre>
|
||||||
|
intermediates:= $(local-intermediates-dir)
|
||||||
|
GEN := $(intermediates)/<font color=red>file.c</font>
|
||||||
|
$(GEN): PRIVATE_INPUT_FILE := $(LOCAL_PATH)/<font color=red>input.file</font>
|
||||||
|
$(GEN): PRIVATE_CUSTOM_TOOL = <font color=red>cat $(PRIVATE_INPUT_FILE) > $@</font>
|
||||||
|
$(GEN): <font color=red>$(LOCAL_PATH)/file.c</font>
|
||||||
|
$(transform-generated-source)
|
||||||
|
LOCAL_GENERATED_SOURCES += $(GEN)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h5>Example 3</h5>
|
||||||
|
<p>If you have several files that are all similar in
|
||||||
|
name, and use the same tool, you can combine them. (here the *.lut.h files are
|
||||||
|
the generated ones, and the *.cpp files are the input files)</p>
|
||||||
|
<pre>
|
||||||
|
intermediates:= $(local-intermediates-dir)
|
||||||
|
GEN := $(addprefix $(intermediates)<font color=red>/kjs/, \
|
||||||
|
array_object.lut.h \
|
||||||
|
bool_object.lut.h \</font>
|
||||||
|
)
|
||||||
|
$(GEN): PRIVATE_CUSTOM_TOOL = <font color=red>perl libs/WebKitLib/WebKit/JavaScriptCore/kjs/create_hash_table $< -i > $@</font>
|
||||||
|
$(GEN): $(intermediates)/<font color=red>%.lut.h</font> : $(LOCAL_PATH)/<font color=red>%.cpp</font>
|
||||||
|
$(transform-generated-source)
|
||||||
|
LOCAL_GENERATED_SOURCES += $(GEN)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h3><a name="platform-specific"/>Platform specific conditionals</h3>
|
||||||
|
<p>Sometimes you need to set flags specifically for different platforms. Here
|
||||||
|
is a list of which values the different build-system defined variables will be
|
||||||
|
set to and some examples.</p>
|
||||||
|
<p>For a device build, <code>TARGET_OS</code> is <code>linux</code> (we're using
|
||||||
|
linux!), and <code>TARGET_ARCH</code> is <code>arm</code>.</p>
|
||||||
|
<p>For a simulator build, <code>TARGET_OS</code> and <code>TARGET_ARCH</code>
|
||||||
|
are set to the same as <code>HOST_OS</code> and <code>HOST_ARCH</code> are
|
||||||
|
on your platform. <code>TARGET_PRODUCT</code> is the name of the target
|
||||||
|
hardware/product you are building for. The value <code>sim</code> is used
|
||||||
|
for the simulator. We haven't thought through the full extent of customization
|
||||||
|
that will happen here, but likely there will be additional UI configurations
|
||||||
|
specified here as well.</p>
|
||||||
|
<table cellspacing=25>
|
||||||
|
<tr>
|
||||||
|
<td valign=top align=center>
|
||||||
|
<b>HOST_OS</b><br/>
|
||||||
|
linux<br/>
|
||||||
|
darwin<br/>
|
||||||
|
(cygwin)
|
||||||
|
</td>
|
||||||
|
<td valign=top align=center>
|
||||||
|
<b>HOST_ARCH</b><br/>
|
||||||
|
x86
|
||||||
|
</td>
|
||||||
|
<td valign=top align=center>
|
||||||
|
<b>HOST_BUILD_TYPE</b><br/>
|
||||||
|
release<br/>
|
||||||
|
debug
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign=top align=center>
|
||||||
|
<b>TARGET_OS</b><br/>
|
||||||
|
linux<br/>
|
||||||
|
darwin<br/>
|
||||||
|
(cygwin)
|
||||||
|
</td>
|
||||||
|
<td valign=top align=center>
|
||||||
|
<b>TARGET_ARCH</b><br/>
|
||||||
|
arm<br/>
|
||||||
|
x86
|
||||||
|
</td>
|
||||||
|
<td valign=top align=center>
|
||||||
|
<b>TARGET_BUILD_TYPE</b><br/>
|
||||||
|
release<br/>
|
||||||
|
debug
|
||||||
|
</td>
|
||||||
|
<td valign=top align=center>
|
||||||
|
<b>TARGET_PRODUCT</b><br/>
|
||||||
|
sim<br/>
|
||||||
|
dream<br/>
|
||||||
|
sooner
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4>TARGET_SIMULATOR</h4>
|
||||||
|
<p>If we're building the simulator, as opposed to the arm or emulator builds,
|
||||||
|
<code>TARGET_SIMULATOR</code> will be set to <code>true</code>.
|
||||||
|
|
||||||
|
<h4>Some Examples</h4>
|
||||||
|
<pre>ifeq ($(TARGET_SIMULATOR),true)
|
||||||
|
LOCAL_CFLAGS += -DSIMULATOR
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(TARGET_BUILD_TYPE),release)
|
||||||
|
LOCAL_CFLAGS += -DNDEBUG=1
|
||||||
|
endif
|
||||||
|
|
||||||
|
# from libutils
|
||||||
|
ifeq ($(TARGET_OS),linux)
|
||||||
|
# Use the futex based mutex and condition variable
|
||||||
|
# implementation from android-arm because it's shared mem safe
|
||||||
|
LOCAL_SRC_FILES += futex_synchro.c
|
||||||
|
LOCAL_LDLIBS += -lrt -ldl
|
||||||
|
endif
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<h3><a name="moving-modules"/>Putting modules elsewhere</h3>
|
||||||
|
<p>If you have modules that normally go somewhere, and you need to have them
|
||||||
|
build somewhere else, read this. One use of this is putting files on
|
||||||
|
the root filesystem instead of where they normally go in /system. Add these
|
||||||
|
lines to your Android.mk:</p>
|
||||||
|
<pre>
|
||||||
|
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN)
|
||||||
|
LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED)
|
||||||
|
</pre>
|
||||||
|
<p>For executables and libraries, you need to also specify a
|
||||||
|
<code>LOCAL_UNSTRIPPED_PATH</code> location, because on target builds, we keep
|
||||||
|
the unstripped executables so GDB can find the symbols.</code>
|
||||||
|
<p>Look in <code>config/envsetup.make</code> for all of the variables defining
|
||||||
|
places to build things.</p>
|
||||||
|
<p>FYI: If you're installing an executable to /sbin, you probably also want to
|
||||||
|
set <code>LOCAL_FORCE_STATIC_EXCUTABLE := true</code> in your Android.mk, which
|
||||||
|
will force the linker to only accept static libraries.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<h3>Android.mk variables</h3>
|
||||||
|
<p>These are the variables that you'll commonly see in Android.mk files, listed
|
||||||
|
alphabetically.</p>
|
||||||
|
<p>But first, a note on variable naming:
|
||||||
|
<ul>
|
||||||
|
<li><b>LOCAL_</b> - These variables are set per-module. They are cleared
|
||||||
|
by the <code>include $(CLEAR_VARS)</code> line, so you can rely on them
|
||||||
|
being empty after including that file. Most of the variables you'll use
|
||||||
|
in most modules are LOCAL_ variables.</li>
|
||||||
|
<li><b>PRIVATE_</b> - These variables are make-target-specific variables. That
|
||||||
|
means they're only usable within the commands for that module. It also
|
||||||
|
means that they're unlikely to change behind your back from modules that
|
||||||
|
are included after yours. This
|
||||||
|
<a href="http://www.gnu.org/software/make/manual/make.html#Target_002dspecific">link to the make documentation</a>
|
||||||
|
describes more about target-specific variables. Please note that there
|
||||||
|
are a couple of these laying around the tree that aren't prefixed with
|
||||||
|
PRIVATE_. It is safe, and they will be fixed as they are discovered.
|
||||||
|
Sorry for the confusion.</li>
|
||||||
|
<li><b>INTERNAL_</b> - These variables are critical to functioning of
|
||||||
|
the build system, so you shouldn't create variables named like this, and
|
||||||
|
you probably shouldn't be messing with these variables in your makefiles.
|
||||||
|
</li>
|
||||||
|
<li><b>HOST_</b> and <b>TARGET_</b> - These contain the directories
|
||||||
|
and definitions that are specific to either the host or the target builds.
|
||||||
|
Do not set variables that start with HOST_ or TARGET_ in your makefiles.
|
||||||
|
</li>
|
||||||
|
<li><b>BUILD_</b> and <b>CLEAR_VARS</b> - These contain the names of
|
||||||
|
well-defined template makefiles to include. Some examples are CLEAR_VARS
|
||||||
|
and BUILD_HOST_PACKAGE.</li>
|
||||||
|
<li>Any other name is fair-game for you to use in your Android.mk. However,
|
||||||
|
remember that this is a non-recursive build system, so it is possible that
|
||||||
|
your variable will be changed by another Android.mk included later, and be
|
||||||
|
different when the commands for your rule / module are executed.</li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_ASSET_FILES</h4>
|
||||||
|
<p>In Android.mk files that <code>include $(BUILD_PACKAGE)</code> set this
|
||||||
|
to the set of files you want built into your app. Usually:</p>
|
||||||
|
<p><code>LOCAL_ASSET_FILES += $(call find-subdir-assets)</code></p>
|
||||||
|
<p>This will probably change when we switch to ant for the apps' build
|
||||||
|
system.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_CC</h4>
|
||||||
|
<p>If you want to use a different C compiler for this module, set LOCAL_CC
|
||||||
|
to the path to the compiler. If LOCAL_CC is blank, the appropriate default
|
||||||
|
compiler is used.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_CXX</h4>
|
||||||
|
<p>If you want to use a different C++ compiler for this module, set LOCAL_CXX
|
||||||
|
to the path to the compiler. If LOCAL_CXX is blank, the appropriate default
|
||||||
|
compiler is used.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_CFLAGS</h4>
|
||||||
|
<p>If you have additional flags to pass into the C or C++ compiler, add
|
||||||
|
them here. For example:</p>
|
||||||
|
<p><code>LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1</code></p>
|
||||||
|
|
||||||
|
<h4>LOCAL_CPPFLAGS</h4>
|
||||||
|
<p>If you have additional flags to pass into <i>only</i> the C++ compiler, add
|
||||||
|
them here. For example:</p>
|
||||||
|
<p><code>LOCAL_CPPFLAGS += -ffriend-injection</code></p>
|
||||||
|
<code>LOCAL_CPPFLAGS</code> is guaranteed to be after <code>LOCAL_CFLAGS</code>
|
||||||
|
on the compile line, so you can use it to override flags listed in
|
||||||
|
<code>LOCAL_CFLAGS</code>.
|
||||||
|
|
||||||
|
<h4>LOCAL_CPP_EXTENSION</h4>
|
||||||
|
<p>If your C++ files end in something other than "<code>.cpp</code>",
|
||||||
|
you can specify the custom extension here. For example:</p>
|
||||||
|
<p><code>LOCAL_CPP_EXTENSION := .cc</code></p>
|
||||||
|
Note that all C++ files for a given module must have the same
|
||||||
|
extension; it is not currently possible to mix different extensions.
|
||||||
|
|
||||||
|
<h4>LOCAL_NO_DEFAULT_COMPILER_FLAGS</h4>
|
||||||
|
<p>Normally, the compile line for C and C++ files includes global include
|
||||||
|
paths and global cflags. If <code>LOCAL_NO_DEFAULT_COMPILER_FLAGS</code>
|
||||||
|
is non-empty, none of the default includes or flags will be used when compiling
|
||||||
|
C and C++ files in this module.
|
||||||
|
<code>LOCAL_C_INCLUDES</code>, <code>LOCAL_CFLAGS</code>, and
|
||||||
|
<code>LOCAL_CPPFLAGS</code> will still be used in this case, as will
|
||||||
|
any <code>DEBUG_CFLAGS</code> that are defined for the module.
|
||||||
|
|
||||||
|
<h4>LOCAL_COPY_HEADERS</h4>
|
||||||
|
<p class=warning>This will be going away.</p>
|
||||||
|
<p>The set of files to copy to the install include tree. You must also
|
||||||
|
supply <code>LOCAL_COPY_HEADERS_TO</code>.</p>
|
||||||
|
<p>This is going away because copying headers messes up the error messages, and
|
||||||
|
may lead to people editing those headers instead of the correct ones. It also
|
||||||
|
makes it easier to do bad layering in the system, which we want to avoid. We
|
||||||
|
also aren't doing a C/C++ SDK, so there is no ultimate requirement to copy any
|
||||||
|
headers.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_COPY_HEADERS_TO</h4>
|
||||||
|
<p class=warning>This will be going away.</p>
|
||||||
|
<p>The directory within "include" to copy the headers listed in
|
||||||
|
<code>LOCAL_COPY_HEADERS</code> to.</p>
|
||||||
|
<p>This is going away because copying headers messes up the error messages, and
|
||||||
|
may lead to people editing those headers instead of the correct ones. It also
|
||||||
|
makes it easier to do bad layering in the system, which we want to avoid. We
|
||||||
|
also aren't doing a C/C++ SDK, so there is no ultimate requirement to copy any
|
||||||
|
headers.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_C_INCLUDES</h4>
|
||||||
|
<p>Additional directories to instruct the C/C++ compilers to look for header
|
||||||
|
files in. These paths are rooted at the top of the tree. Use
|
||||||
|
<code>LOCAL_PATH</code> if you have subdirectories of your own that you
|
||||||
|
want in the include paths. For example:</p>
|
||||||
|
<p><code>
|
||||||
|
LOCAL_C_INCLUDES += extlibs/zlib-1.2.3<br/>
|
||||||
|
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
|
||||||
|
</code></p>
|
||||||
|
<p>You should not add subdirectories of include to
|
||||||
|
<code>LOCAL_C_INCLUDES</code>, instead you should reference those files
|
||||||
|
in the <code>#include</code> statement with their subdirectories. For
|
||||||
|
example:</p>
|
||||||
|
<p><code>#include <utils/KeyedVector.h></code><br/>
|
||||||
|
not <code><s>#include <KeyedVector.h></s></code></p>
|
||||||
|
<p>There are some components that are doing this wrong, and should be cleaned
|
||||||
|
up.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_MODULE_TAGS</h4>
|
||||||
|
<p>Set <code>LOCAL_MODULE_TAGS</code> to any number of whitespace-separated
|
||||||
|
tags. If the tag list is empty or contains <code>droid</code>, the module
|
||||||
|
will get installed as part of a <code>make droid</code>. Otherwise, it will
|
||||||
|
only get installed by running <code>make <your-module></code>
|
||||||
|
or with the <code>make all</code> pseudotarget.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_REQUIRED_MODULES</h4>
|
||||||
|
<p>Set <code>LOCAL_REQUIRED_MODULES</code> to any number of whitespace-separated
|
||||||
|
module names, like "libblah" or "Email". If this module is installed, all
|
||||||
|
of the modules that it requires will be installed as well. This can be
|
||||||
|
used to, e.g., ensure that necessary shared libraries or providers are
|
||||||
|
installed when a given app is installed.
|
||||||
|
|
||||||
|
<h4>LOCAL_FORCE_STATIC_EXECUTABLE</h4>
|
||||||
|
<p>If your executable should be linked statically, set
|
||||||
|
<code>LOCAL_FORCE_STATIC_EXECUTABLE:=true</code>. There is a very short
|
||||||
|
list of libraries that we have in static form (currently only libc). This is
|
||||||
|
really only used for executables in /sbin on the root filesystem.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_GENERATED_SOURCES</h4>
|
||||||
|
<p>Files that you add to <code>LOCAL_GENERATED_SOURCES</code> will be
|
||||||
|
automatically generated and then linked in when your module is built.
|
||||||
|
See the <a href="#custom-tools">Custom Tools</a> template makefile for an
|
||||||
|
example.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_JAVA_LIBRARIES</h4>
|
||||||
|
<p>When linking Java apps and libraries, <code>LOCAL_JAVA_LIBRARIES</code>
|
||||||
|
specifies which sets of java classes to include. Currently there are
|
||||||
|
two of these: <code>core</code> and <code>framework</code>.
|
||||||
|
In most cases, it will look like this:</p>
|
||||||
|
<p><code>LOCAL_JAVA_LIBRARIES := core framework</code></p>
|
||||||
|
<p>Note that setting <code>LOCAL_JAVA_LIBRARIES</code> is not necessary
|
||||||
|
(and is not allowed) when building an APK with
|
||||||
|
"<code>include $(BUILD_PACKAGE)</code>". The appropriate libraries
|
||||||
|
will be included automatically.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_LDFLAGS</h4>
|
||||||
|
<p>You can pass additional flags to the linker by setting
|
||||||
|
<code>LOCAL_LDFLAGS</code>. Keep in mind that the order of parameters is
|
||||||
|
very important to ld, so test whatever you do on all platforms.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_LDLIBS</h4>
|
||||||
|
<p><code>LOCAL_LDLIBS</code> allows you to specify additional libraries
|
||||||
|
that are not part of the build for your executable or library. Specify
|
||||||
|
the libraries you want in -lxxx format; they're passed directly to the
|
||||||
|
link line. However, keep in mind that there will be no dependency generated
|
||||||
|
for these libraries. It's most useful in simulator builds where you want
|
||||||
|
to use a library preinstalled on the host. The linker (ld) is a particularly
|
||||||
|
fussy beast, so it's sometimes necessary to pass other flags here if you're
|
||||||
|
doing something sneaky. Some examples:</p>
|
||||||
|
<p><code>LOCAL_LDLIBS += -lcurses -lpthread<br/>
|
||||||
|
LOCAL_LDLIBS += -Wl,-z,origin
|
||||||
|
</code></p>
|
||||||
|
|
||||||
|
<h4>LOCAL_NO_MANIFEST</h4>
|
||||||
|
<p>If your package doesn't have a manifest (AndroidManifest.xml), then
|
||||||
|
set <code>LOCAL_NO_MANIFEST:=true</code>. The common resources package
|
||||||
|
does this.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_PACKAGE_NAME</h4>
|
||||||
|
<p><code>LOCAL_PACKAGE_NAME</code> is the name of an app. For example,
|
||||||
|
Dialer, Contacts, etc. This will probably change or go away when we switch
|
||||||
|
to an ant-based build system for the apps.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_PATH</h4>
|
||||||
|
<p>The directory your Android.mk file is in. You can set it by putting the
|
||||||
|
following as the first line in your Android.mk:</p>
|
||||||
|
<p><code>LOCAL_PATH := $(my-dir)</code></p>
|
||||||
|
<p>The <code>my-dir</code> macro uses the
|
||||||
|
<code><a href="http://www.gnu.org/software/make/manual/make.html#MAKEFILE_005fLIST-Variable">MAKEFILE_LIST</a></code>
|
||||||
|
variable, so you must call it before you include any other makefiles. Also,
|
||||||
|
consider that any subdirectories you inlcude might reset LOCAL_PATH, so do your
|
||||||
|
own stuff before you include them. This also means that if you try to write
|
||||||
|
several <code>include</code> lines that reference <code>LOCAL_PATH</code>,
|
||||||
|
it won't work, because those included makefiles might reset LOCAL_PATH.
|
||||||
|
|
||||||
|
<h4>LOCAL_POST_PROCESS_COMMAND</h4>
|
||||||
|
<p>For host executables, you can specify a command to run on the module
|
||||||
|
after it's been linked. You might have to go through some contortions
|
||||||
|
to get variables right because of early or late variable evaluation:</p>
|
||||||
|
<p><code>module := $(HOST_OUT_EXECUTABLES)/$(LOCAL_MODULE)<br/>
|
||||||
|
LOCAL_POST_PROCESS_COMMAND := /Developer/Tools/Rez -d __DARWIN__ -t APPL\<br/>
|
||||||
|
-d __WXMAC__ -o $(module) Carbon.r
|
||||||
|
</code></p>
|
||||||
|
|
||||||
|
<h4>LOCAL_PREBUILT_EXECUTABLES</h4>
|
||||||
|
<p>When including $(BUILD_PREBUILT) or $(BUILD_HOST_PREBUILT), set these to
|
||||||
|
executables that you want copied. They're located automatically into the
|
||||||
|
right bin directory.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_PREBUILT_LIBS</h4>
|
||||||
|
<p>When including $(BUILD_PREBUILT) or $(BUILD_HOST_PREBUILT), set these to
|
||||||
|
libraries that you want copied. They're located automatically into the
|
||||||
|
right lib directory.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_SHARED_LIBRARIES</h4>
|
||||||
|
<p>These are the libraries you directly link against. You don't need to
|
||||||
|
pass transitively included libraries. Specify the name without the suffix:</p>
|
||||||
|
<p><code>LOCAL_SHARED_LIBRARIES := \<br/>
|
||||||
|
libutils \<br/>
|
||||||
|
libui \<br/>
|
||||||
|
libaudio \<br/>
|
||||||
|
libexpat \<br/>
|
||||||
|
libsgl
|
||||||
|
</code></p>
|
||||||
|
|
||||||
|
<h4>LOCAL_SRC_FILES</h4>
|
||||||
|
<p>The build system looks at <code>LOCAL_SRC_FILES</code> to know what source
|
||||||
|
files to compile -- .cpp .c .y .l .java. For lex and yacc files, it knows
|
||||||
|
how to correctly do the intermediate .h and .c/.cpp files automatically. If
|
||||||
|
the files are in a subdirectory of the one containing the Android.mk, prefix
|
||||||
|
them with the directory name:</p>
|
||||||
|
<p><code>LOCAL_SRC_FILES := \<br/>
|
||||||
|
file1.cpp \<br/>
|
||||||
|
dir/file2.cpp
|
||||||
|
</code></p>
|
||||||
|
|
||||||
|
<h4>LOCAL_STATIC_LIBRARIES</h4>
|
||||||
|
<p>These are the static libraries that you want to include in your module.
|
||||||
|
Mostly, we use shared libraries, but there are a couple of places, like
|
||||||
|
executables in sbin and host executables where we use static libraries instead.
|
||||||
|
<p><code>LOCAL_STATIC_LIBRARIES := \<br/>
|
||||||
|
libutils \<br/>
|
||||||
|
libtinyxml
|
||||||
|
</code></p>
|
||||||
|
|
||||||
|
<h4>LOCAL_MODULE</h4>
|
||||||
|
<p><code>LOCAL_MODULE</code> is the name of what's supposed to be generated
|
||||||
|
from your Android.mk. For exmample, for libkjs, the <code>LOCAL_MODULE</code>
|
||||||
|
is "libkjs" (the build system adds the appropriate suffix -- .so .dylib .dll).
|
||||||
|
For app modules, use <code>LOCAL_PACKAGE_NAME</code> instead of
|
||||||
|
<code>LOCAL_MODULE</code>. We're planning on switching to ant for the apps,
|
||||||
|
so this might become moot.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_MODULE_PATH</h4>
|
||||||
|
<p>Instructs the build system to put the module somewhere other than what's
|
||||||
|
normal for its type. If you override this, make sure you also set
|
||||||
|
<code>LOCAL_UNSTRIPPED_PATH</code> if it's an executable or a shared library
|
||||||
|
so the unstripped binary has somewhere to go. An error will occur if you forget
|
||||||
|
to.</p>
|
||||||
|
<p>See <a href="#moving-modules">Putting modules elsewhere</a> for more.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_UNSTRIPPED_PATH</h4>
|
||||||
|
<p>Instructs the build system to put the unstripped version of the module
|
||||||
|
somewhere other than what's normal for its type. Usually, you override this
|
||||||
|
because you overrode <code>LOCAL_MODULE_PATH</code> for an executable or a
|
||||||
|
shared library. If you overrode <code>LOCAL_MODULE_PATH</code>, but not
|
||||||
|
<code>LOCAL_UNSTRIPPED_PATH</code>, an error will occur.</p>
|
||||||
|
<p>See <a href="#moving-modules">Putting modules elsewhere</a> for more.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_WHOLE_STATIC_LIBRARIES</h4>
|
||||||
|
<p>These are the static libraries that you want to include in your module without allowing
|
||||||
|
the linker to remove dead code from them. This is mostly useful if you want to add a static library
|
||||||
|
to a shared library and have the static library's content exposed from the shared library.
|
||||||
|
<p><code>LOCAL_WHOLE_STATIC_LIBRARIES := \<br/>
|
||||||
|
libsqlite3_android<br/>
|
||||||
|
</code></p>
|
||||||
|
|
||||||
|
<h4>LOCAL_YACCFLAGS</h4>
|
||||||
|
<p>Any flags to pass to invocations of yacc for your module. A known limitation
|
||||||
|
here is that the flags will be the same for all invocations of YACC for your
|
||||||
|
module. This can be fixed. If you ever need it to be, just ask.</p>
|
||||||
|
<p><code>LOCAL_YACCFLAGS := -p kjsyy</code></p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Implementation Details</h2>
|
||||||
|
|
||||||
|
<p>You should never have to touch anything in the config directory unless
|
||||||
|
you're adding a new platform, new tools, or adding new features to the
|
||||||
|
build system. In general, please consult with the build system owner(s)
|
||||||
|
(<a href="mailto:android-build-team">android-build-team</a>) before you go
|
||||||
|
mucking around in here. That said, here are some notes on what's going on
|
||||||
|
under the hood.</p>
|
||||||
|
|
||||||
|
<h3>Environment Setup / buildspec.mk Versioning</h3>
|
||||||
|
<p>In order to make easier for people when the build system changes, when
|
||||||
|
it is necessary to make changes to buildspec.mk or to rerun the environment
|
||||||
|
setup scripts, they contain a version number in the variable
|
||||||
|
BUILD_ENV_SEQUENCE_NUMBER. If this variable does not match what the build
|
||||||
|
system expects, it fails printing an error message explaining what happened.
|
||||||
|
If you make a change that requires an update, you need to update two places
|
||||||
|
so this message will be printed.
|
||||||
|
<ul>
|
||||||
|
<li>In config/envsetup.make, increment the
|
||||||
|
CORRECT_BUILD_ENV_SEQUENCE_NUMBER definition.</li>
|
||||||
|
<li>In buildspec.mk.default, update the BUILD_ENV_SEQUENCE_DUMBER
|
||||||
|
definition to match the one in config/envsetup.make</li>
|
||||||
|
</ul>
|
||||||
|
The scripts automatically get the value from the build system, so they will
|
||||||
|
trigger the warning as well.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Additional makefile variables</h3>
|
||||||
|
<p>You probably shouldn't use these variables. Please consult
|
||||||
|
<a href="mailto:android-build-team">android-build-team</a> before using them.
|
||||||
|
These are mostly there for workarounds for other issues, or things that aren't
|
||||||
|
completely done right.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_ADDITIONAL_DEPENDENCIES</h4>
|
||||||
|
<p>If your module needs to depend on anything else that
|
||||||
|
isn't actually built in to it, you can add those make targets to
|
||||||
|
<code>LOCAL_ADDITIONAL_DEPENDENCIES</code>. Usually this is a workaround
|
||||||
|
for some other dependency that isn't created automatically.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_BUILT_MODULE</h4>
|
||||||
|
<p>When a module is built, the module is created in an intermediate
|
||||||
|
directory then copied to its final location. LOCAL_BUILT_MODULE is
|
||||||
|
the full path to the intermediate file. See LOCAL_INSTALLED_MODULE
|
||||||
|
for the path to the final installed location of the module.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_HOST</h4>
|
||||||
|
<p>Set by the host_xxx.make includes to tell base_rules.make and the other
|
||||||
|
includes that we're building for the host. Kenneth did this as part of
|
||||||
|
openbinder, and I would like to clean it up so the rules, includes and
|
||||||
|
definitions aren't duplicated for host and target.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_INSTALLED_MODULE</h4>
|
||||||
|
<p>The fully qualified path name of the final location of the module.
|
||||||
|
See LOCAL_BUILT_MODULE for the location of the intermediate file that
|
||||||
|
the make rules should actually be constructing.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_REPLACE_VARS</h4>
|
||||||
|
<p>Used in some stuff remaining from the openbinder for building scripts
|
||||||
|
with particular values set,</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_SCRIPTS</h4>
|
||||||
|
<p>Used in some stuff remaining from the openbinder build system that we
|
||||||
|
might find handy some day.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_MODULE_CLASS</h4>
|
||||||
|
<p>Which kind of module this is. This variable is used to construct other
|
||||||
|
variable names used to locate the modules. See base_rules.make and
|
||||||
|
envsetup.make.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_MODULE_NAME</h4>
|
||||||
|
<p>Set to the leaf name of the LOCAL_BUILT_MODULE. I'm not sure,
|
||||||
|
but it looks like it's just used in the WHO_AM_I variable to identify
|
||||||
|
in the pretty printing what's being built.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_MODULE_SUFFIX</h4>
|
||||||
|
<p>The suffix that will be appended to <code>LOCAL_MODULE</code> to form
|
||||||
|
<code>LOCAL_MODULE_NAME</code>. For example, .so, .a, .dylib.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_STRIP_MODULE</h4>
|
||||||
|
<p>Calculated in base_rules.make to determine if this module should actually
|
||||||
|
be stripped or not, based on whether <code>LOCAL_STRIPPABLE_MODULE</code>
|
||||||
|
is set, and whether the combo is configured to ever strip modules. With
|
||||||
|
Iliyan's stripping tool, this might change.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_STRIPPABLE_MODULE</h4>
|
||||||
|
<p>Set by the include makefiles if that type of module is strippable.
|
||||||
|
Executables and shared libraries are.</p>
|
||||||
|
|
||||||
|
<h4>LOCAL_SYSTEM_SHARED_LIBRARIES</h4>
|
||||||
|
<p>Used while building the base libraries: libc, libm, libdl. Usually
|
||||||
|
it should be set to "none," as it is in $(CLEAR_VARS). When building
|
||||||
|
these libraries, it's set to the ones they link against. For example,
|
||||||
|
libc, libstdc++ and libdl don't link against anything, and libm links against
|
||||||
|
libc. Normally, when the value is none, these libraries are automatically
|
||||||
|
linked in to executables and libraries, so you don't need to specify them
|
||||||
|
manually.</p>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -23,7 +23,7 @@
|
|||||||
# (like "TC1-RC5"). It must be a single word, and is
|
# (like "TC1-RC5"). It must be a single word, and is
|
||||||
# capitalized by convention.
|
# capitalized by convention.
|
||||||
#
|
#
|
||||||
BUILD_ID := Donut
|
BUILD_ID := ECLAIR
|
||||||
|
|
||||||
# DISPLAY_BUILD_NUMBER should only be set for development branches,
|
# DISPLAY_BUILD_NUMBER should only be set for development branches,
|
||||||
# If set, the BUILD_NUMBER (cl) is appended to the BUILD_ID for
|
# If set, the BUILD_NUMBER (cl) is appended to the BUILD_ID for
|
||||||
|
@@ -87,6 +87,8 @@ LOCAL_CERTIFICATE:=
|
|||||||
LOCAL_SDK_VERSION:=
|
LOCAL_SDK_VERSION:=
|
||||||
LOCAL_NO_EMMA_INSTRUMENT:=
|
LOCAL_NO_EMMA_INSTRUMENT:=
|
||||||
LOCAL_NO_EMMA_COMPILE:=
|
LOCAL_NO_EMMA_COMPILE:=
|
||||||
|
LOCAL_PROGUARD_ENABLED:= # '',optonly,full,custom
|
||||||
|
LOCAL_PROGUARD_FLAGS:=
|
||||||
|
|
||||||
# Trim MAKEFILE_LIST so that $(call my-dir) doesn't need to
|
# Trim MAKEFILE_LIST so that $(call my-dir) doesn't need to
|
||||||
# iterate over thousands of entries every time.
|
# iterate over thousands of entries every time.
|
||||||
|
23
core/combo/arch/arm/armv4t.mk
Normal file
23
core/combo/arch/arm/armv4t.mk
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Configuration for Linux on ARM.
|
||||||
|
# Generating binaries for the ARMv4T architecture and higher
|
||||||
|
#
|
||||||
|
# Supporting armv4 (without thumb) does not make much sense since
|
||||||
|
# it's mostly an obsoleted instruction set architecture (only available
|
||||||
|
# in StrongArm and arm8). Supporting armv4 will require a lot of conditional
|
||||||
|
# code in assembler source since the bx (branch and exchange) instruction is
|
||||||
|
# not supported.
|
||||||
|
#
|
||||||
|
$(warning ARMv4t support is currently a work in progress. It does not work right now!)
|
||||||
|
ARCH_ARM_HAVE_THUMB_SUPPORT := false
|
||||||
|
ARCH_ARM_HAVE_THUMB_INTERWORKING := false
|
||||||
|
ARCH_ARM_HAVE_64BIT_DATA := false
|
||||||
|
ARCH_ARM_HAVE_HALFWORD_MULTIPLY := false
|
||||||
|
ARCH_ARM_HAVE_CLZ := false
|
||||||
|
ARCH_ARM_HAVE_FFS := false
|
||||||
|
|
||||||
|
DEFAULT_TARGET_CPU := arm920t
|
||||||
|
|
||||||
|
# Note: Hard coding the 'tune' value here is probably not ideal,
|
||||||
|
# and a better solution should be found in the future.
|
||||||
|
#
|
||||||
|
arch_variant_cflags := -march=armv4t -mtune=arm920t -D__ARM_ARCH_4T__
|
7
core/combo/arch/arm/armv5te-vfp.mk
Normal file
7
core/combo/arch/arm/armv5te-vfp.mk
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# At the moment, use the same settings than the one
|
||||||
|
# for armv5te, since TARGET_ARCH_VARIANT := armv5te-vfp
|
||||||
|
# will only be used to select an optimized VFP-capable assembly
|
||||||
|
# interpreter loop for Dalvik.
|
||||||
|
#
|
||||||
|
include $(BUILD_COMBOS)/arch/arm/armv5te.mk
|
||||||
|
|
21
core/combo/arch/arm/armv5te.mk
Normal file
21
core/combo/arch/arm/armv5te.mk
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Configuration for Linux on ARM.
|
||||||
|
# Generating binaries for the ARMv5TE architecture and higher
|
||||||
|
#
|
||||||
|
ARCH_ARM_HAVE_THUMB_SUPPORT := true
|
||||||
|
ARCH_ARM_HAVE_FAST_INTERWORKING := true
|
||||||
|
ARCH_ARM_HAVE_64BIT_DATA := true
|
||||||
|
ARCH_ARM_HAVE_HALFWORD_MULTIPLY := true
|
||||||
|
ARCH_ARM_HAVE_CLZ := true
|
||||||
|
ARCH_ARM_HAVE_FFS := true
|
||||||
|
|
||||||
|
# Note: Hard coding the 'tune' value here is probably not ideal,
|
||||||
|
# and a better solution should be found in the future.
|
||||||
|
#
|
||||||
|
arch_variant_cflags := \
|
||||||
|
-march=armv5te \
|
||||||
|
-mtune=xscale \
|
||||||
|
-D__ARM_ARCH_5__ \
|
||||||
|
-D__ARM_ARCH_5T__ \
|
||||||
|
-D__ARM_ARCH_5E__ \
|
||||||
|
-D__ARM_ARCH_5TE__
|
||||||
|
|
22
core/combo/arch/arm/armv7-a.mk
Normal file
22
core/combo/arch/arm/armv7-a.mk
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Configuration for Linux on ARM.
|
||||||
|
# Generating binaries for the ARMv7-a architecture and higher
|
||||||
|
#
|
||||||
|
ARCH_ARM_HAVE_THUMB_SUPPORT := true
|
||||||
|
ARCH_ARM_HAVE_FAST_INTERWORKING := true
|
||||||
|
ARCH_ARM_HAVE_64BIT_DATA := true
|
||||||
|
ARCH_ARM_HAVE_HALFWORD_MULTIPLY := true
|
||||||
|
ARCH_ARM_HAVE_CLZ := true
|
||||||
|
ARCH_ARM_HAVE_FFS := true
|
||||||
|
ARCH_ARM_HAVE_VFP := true
|
||||||
|
ARCH_ARM_HAVE_NEON := true
|
||||||
|
|
||||||
|
# Note: Hard coding the 'tune' value here is probably not ideal,
|
||||||
|
# and a better solution should be found in the future.
|
||||||
|
#
|
||||||
|
arch_variant_cflags := \
|
||||||
|
-march=armv7-a \
|
||||||
|
-mfloat-abi=softfp \
|
||||||
|
-mfpu=neon
|
||||||
|
|
||||||
|
arch_variant_ldflags := \
|
||||||
|
-Wl,--fix-cortex-a8
|
@@ -1,10 +1,44 @@
|
|||||||
# Configuration for Linux on ARM.
|
# Configuration for Linux on ARM.
|
||||||
# Included by combo/select.make
|
# Included by combo/select.make
|
||||||
|
|
||||||
|
# You can set TARGET_ARCH_VARIANT to use an arch version other
|
||||||
|
# than ARMv5TE. Each value should correspond to a file named
|
||||||
|
# $(BUILD_COMBOS)/arch/<name>.mk which must contain
|
||||||
|
# makefile variable definitions similar to the preprocessor
|
||||||
|
# defines in system/core/include/arch/<combo>/AndroidConfig.h. Their
|
||||||
|
# purpose is to allow module Android.mk files to selectively compile
|
||||||
|
# different versions of code based upon the funtionality and
|
||||||
|
# instructions available in a given architecture version.
|
||||||
|
#
|
||||||
|
# The blocks also define specific arch_variant_cflags, which
|
||||||
|
# include defines, and compiler settings for the given architecture
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
ifeq ($(strip $(TARGET_ARCH_VARIANT)),)
|
||||||
|
TARGET_ARCH_VARIANT := armv5te
|
||||||
|
endif
|
||||||
|
|
||||||
|
# TARGET_ARCH_VARIANT used to be called TARGET_ARCH_VERSION
|
||||||
|
# to avoid any weirdness, issue an error message if the latter
|
||||||
|
# is defined.
|
||||||
|
#
|
||||||
|
ifneq ($(strip $(TARGET_ARCH_VERSION)),)
|
||||||
|
$(info Definition for TARGET_ARCH_VERSION encountered !)
|
||||||
|
$(info This variable has been renamed TARGET_ARCH_VARIANT, please update your build files !!)
|
||||||
|
$(error Aborting the build.)
|
||||||
|
endif
|
||||||
|
|
||||||
|
TARGET_ARCH_SPECIFIC_MAKEFILE := $(BUILD_COMBOS)/arch/$(TARGET_ARCH)/$(TARGET_ARCH_VARIANT).mk
|
||||||
|
ifeq ($(strip $(wildcard $(TARGET_ARCH_SPECIFIC_MAKEFILE))),)
|
||||||
|
$(error Unknown ARM architecture version: $(TARGET_ARCH_VARIANT))
|
||||||
|
endif
|
||||||
|
|
||||||
|
include $(TARGET_ARCH_SPECIFIC_MAKEFILE)
|
||||||
|
|
||||||
# You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
|
# You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
|
||||||
ifeq ($(strip $($(combo_target)TOOLS_PREFIX)),)
|
ifeq ($(strip $($(combo_target)TOOLS_PREFIX)),)
|
||||||
$(combo_target)TOOLS_PREFIX := \
|
$(combo_target)TOOLS_PREFIX := \
|
||||||
prebuilt/$(HOST_PREBUILT_TAG)/toolchain/arm-eabi-4.2.1/bin/arm-eabi-
|
prebuilt/$(HOST_PREBUILT_TAG)/toolchain/arm-eabi-4.4.0/bin/arm-eabi-
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(combo_target)CC := $($(combo_target)TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
|
$(combo_target)CC := $($(combo_target)TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
|
||||||
@@ -21,11 +55,19 @@ TARGET_arm_CFLAGS := -O2 \
|
|||||||
-funswitch-loops \
|
-funswitch-loops \
|
||||||
-finline-limit=300
|
-finline-limit=300
|
||||||
|
|
||||||
|
# Modules can choose to compile some source as thumb. As
|
||||||
|
# non-thumb enabled targets are supported, this is treated
|
||||||
|
# as a 'hint'. If thumb is not enabled, these files are just
|
||||||
|
# compiled as ARM.
|
||||||
|
ifeq ($(ARCH_ARM_HAVE_THUMB_SUPPORT),true)
|
||||||
TARGET_thumb_CFLAGS := -mthumb \
|
TARGET_thumb_CFLAGS := -mthumb \
|
||||||
-Os \
|
-Os \
|
||||||
-fomit-frame-pointer \
|
-fomit-frame-pointer \
|
||||||
-fno-strict-aliasing \
|
-fno-strict-aliasing \
|
||||||
-finline-limit=64
|
-finline-limit=64
|
||||||
|
else
|
||||||
|
TARGET_thumb_CFLAGS := $(TARGET_arm_CFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
# Set FORCE_ARM_DEBUGGING to "true" in your buildspec.mk
|
# Set FORCE_ARM_DEBUGGING to "true" in your buildspec.mk
|
||||||
# or in your environment to force a full arm build, even for
|
# or in your environment to force a full arm build, even for
|
||||||
@@ -37,26 +79,35 @@ TARGET_thumb_CFLAGS := -mthumb \
|
|||||||
# with -mlong-calls. When built at -O0, those libraries are
|
# with -mlong-calls. When built at -O0, those libraries are
|
||||||
# too big for a thumb "BL <label>" to go from one end to the other.
|
# too big for a thumb "BL <label>" to go from one end to the other.
|
||||||
ifeq ($(FORCE_ARM_DEBUGGING),true)
|
ifeq ($(FORCE_ARM_DEBUGGING),true)
|
||||||
TARGET_arm_CFLAGS += -fno-omit-frame-pointer
|
TARGET_arm_CFLAGS += -fno-omit-frame-pointer -fno-strict-aliasing
|
||||||
TARGET_thumb_CFLAGS += -marm -fno-omit-frame-pointer
|
TARGET_thumb_CFLAGS += -marm -fno-omit-frame-pointer
|
||||||
endif
|
endif
|
||||||
|
|
||||||
## on some hosts, the target cross-compiler is not available so do not run this command
|
android_config_h := $(call select-android-config-h,linux-arm)
|
||||||
ifneq ($(wildcard $($(combo_target)CC)),)
|
arch_include_dir := $(dir $(android_config_h))
|
||||||
$(combo_target)LIBGCC := $(shell $($(combo_target)CC) -mthumb-interwork -print-libgcc-file-name)
|
|
||||||
endif
|
|
||||||
|
|
||||||
$(combo_target)GLOBAL_CFLAGS += \
|
$(combo_target)GLOBAL_CFLAGS += \
|
||||||
-march=armv5te -mtune=xscale \
|
|
||||||
-msoft-float -fpic \
|
-msoft-float -fpic \
|
||||||
-mthumb-interwork \
|
|
||||||
-ffunction-sections \
|
-ffunction-sections \
|
||||||
-funwind-tables \
|
-funwind-tables \
|
||||||
-fstack-protector \
|
-fstack-protector \
|
||||||
-fno-short-enums \
|
-fno-short-enums \
|
||||||
-D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ \
|
$(arch_variant_cflags) \
|
||||||
-D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ \
|
-include $(android_config_h) \
|
||||||
-include $(call select-android-config-h,linux-arm)
|
-I $(arch_include_dir)
|
||||||
|
|
||||||
|
$(combo_target)GLOBAL_LDFLAGS += \
|
||||||
|
$(arch_variant_ldflags)
|
||||||
|
|
||||||
|
# We only need thumb interworking in cases where thumb support
|
||||||
|
# is available in the architecture, and just to be sure, (and
|
||||||
|
# since sometimes thumb-interwork appears to be default), we
|
||||||
|
# specifically disable when thumb support is unavailable.
|
||||||
|
ifeq ($(ARCH_ARM_HAVE_THUMB_SUPPORT),true)
|
||||||
|
$(combo_target)GLOBAL_CFLAGS += -mthumb-interwork
|
||||||
|
else
|
||||||
|
$(combo_target)GLOBAL_CFLAGS += -mno-thumb-interwork
|
||||||
|
endif
|
||||||
|
|
||||||
$(combo_target)GLOBAL_CPPFLAGS += -fvisibility-inlines-hidden
|
$(combo_target)GLOBAL_CPPFLAGS += -fvisibility-inlines-hidden
|
||||||
|
|
||||||
@@ -75,6 +126,15 @@ libm_root := bionic/libm
|
|||||||
libstdc++_root := bionic/libstdc++
|
libstdc++_root := bionic/libstdc++
|
||||||
libthread_db_root := bionic/libthread_db
|
libthread_db_root := bionic/libthread_db
|
||||||
|
|
||||||
|
|
||||||
|
## on some hosts, the target cross-compiler is not available so do not run this command
|
||||||
|
ifneq ($(wildcard $($(combo_target)CC)),)
|
||||||
|
# We compile with the global cflags to ensure that
|
||||||
|
# any flags which affect libgcc are correctly taken
|
||||||
|
# into account.
|
||||||
|
$(combo_target)LIBGCC := $(shell $($(combo_target)CC) $($(combo_target)GLOBAL_CFLAGS) -print-libgcc-file-name)
|
||||||
|
endif
|
||||||
|
|
||||||
# unless CUSTOM_KERNEL_HEADERS is defined, we're going to use
|
# unless CUSTOM_KERNEL_HEADERS is defined, we're going to use
|
||||||
# symlinks located in out/ to point to the appropriate kernel
|
# symlinks located in out/ to point to the appropriate kernel
|
||||||
# headers. see 'config/kernel_headers.make' for more details
|
# headers. see 'config/kernel_headers.make' for more details
|
||||||
@@ -120,6 +180,7 @@ $(TARGET_CXX) \
|
|||||||
$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
|
$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
|
||||||
-o $@ \
|
-o $@ \
|
||||||
$(PRIVATE_LDFLAGS) \
|
$(PRIVATE_LDFLAGS) \
|
||||||
|
$(TARGET_GLOBAL_LDFLAGS) \
|
||||||
$(TARGET_LIBGCC)
|
$(TARGET_LIBGCC)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
@@ -136,6 +197,7 @@ $(TARGET_CXX) -nostdlib -Bdynamic -Wl,-T,$(BUILD_SYSTEM)/armelf.x \
|
|||||||
$(PRIVATE_ALL_OBJECTS) \
|
$(PRIVATE_ALL_OBJECTS) \
|
||||||
$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
|
$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
|
||||||
$(PRIVATE_LDFLAGS) \
|
$(PRIVATE_LDFLAGS) \
|
||||||
|
$(TARGET_GLOBAL_LDFLAGS) \
|
||||||
$(TARGET_LIBGCC) \
|
$(TARGET_LIBGCC) \
|
||||||
$(TARGET_CRTEND_O)
|
$(TARGET_CRTEND_O)
|
||||||
endef
|
endef
|
||||||
@@ -147,6 +209,7 @@ $(TARGET_CXX) -nostdlib -Bstatic -Wl,-T,$(BUILD_SYSTEM)/armelf.x \
|
|||||||
$(TARGET_GLOBAL_LD_DIRS) \
|
$(TARGET_GLOBAL_LD_DIRS) \
|
||||||
$(TARGET_CRTBEGIN_STATIC_O) \
|
$(TARGET_CRTBEGIN_STATIC_O) \
|
||||||
$(PRIVATE_LDFLAGS) \
|
$(PRIVATE_LDFLAGS) \
|
||||||
|
$(TARGET_GLOBAL_LDFLAGS) \
|
||||||
$(PRIVATE_ALL_OBJECTS) \
|
$(PRIVATE_ALL_OBJECTS) \
|
||||||
$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
|
$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
|
||||||
$(TARGET_LIBGCC) \
|
$(TARGET_LIBGCC) \
|
||||||
|
@@ -39,6 +39,7 @@ $(combo_target)HAVE_KERNEL_MODULES := 0
|
|||||||
# These flags might (will) be overridden by the target makefiles
|
# These flags might (will) be overridden by the target makefiles
|
||||||
$(combo_target)GLOBAL_CFLAGS := -fno-exceptions -Wno-multichar
|
$(combo_target)GLOBAL_CFLAGS := -fno-exceptions -Wno-multichar
|
||||||
$(combo_target)RELEASE_CFLAGS := -O2 -g -fno-strict-aliasing
|
$(combo_target)RELEASE_CFLAGS := -O2 -g -fno-strict-aliasing
|
||||||
|
$(combo_target)GLOBAL_LDFLAGS :=
|
||||||
$(combo_target)GLOBAL_ARFLAGS := crs
|
$(combo_target)GLOBAL_ARFLAGS := crs
|
||||||
|
|
||||||
$(combo_target)EXECUTABLE_SUFFIX :=
|
$(combo_target)EXECUTABLE_SUFFIX :=
|
||||||
|
@@ -75,11 +75,11 @@ SHOW_COMMANDS:= $(filter showcommands,$(MAKECMDGOALS))
|
|||||||
# ###############################################################
|
# ###############################################################
|
||||||
|
|
||||||
# These can be changed to modify both host and device modules.
|
# These can be changed to modify both host and device modules.
|
||||||
COMMON_GLOBAL_CFLAGS:= -DANDROID -fmessage-length=0 -W -Wall -Wno-unused
|
COMMON_GLOBAL_CFLAGS:= -DANDROID -fmessage-length=0 -W -Wall -Wno-unused -Winit-self -Wpointer-arith
|
||||||
COMMON_RELEASE_CFLAGS:= -DNDEBUG -UDEBUG
|
COMMON_RELEASE_CFLAGS:= -DNDEBUG -UDEBUG
|
||||||
|
|
||||||
COMMON_GLOBAL_CPPFLAGS:= -DANDROID -fmessage-length=0 -W -Wall -Wno-unused -Wnon-virtual-dtor
|
COMMON_GLOBAL_CPPFLAGS:= $(COMMON_GLOBAL_CFLAGS) -Wsign-promo
|
||||||
COMMON_RELEASE_CPPFLAGS:= -DNDEBUG -UDEBUG
|
COMMON_RELEASE_CPPFLAGS:= $(COMMON_RELEASE_CFLAGS)
|
||||||
|
|
||||||
# Set the extensions used for various packages
|
# Set the extensions used for various packages
|
||||||
COMMON_PACKAGE_SUFFIX := .zip
|
COMMON_PACKAGE_SUFFIX := .zip
|
||||||
@@ -87,7 +87,13 @@ COMMON_JAVA_PACKAGE_SUFFIX := .jar
|
|||||||
COMMON_ANDROID_PACKAGE_SUFFIX := .apk
|
COMMON_ANDROID_PACKAGE_SUFFIX := .apk
|
||||||
|
|
||||||
# list of flags to turn specific warnings in to errors
|
# list of flags to turn specific warnings in to errors
|
||||||
TARGET_ERROR_FLAGS := -Werror=return-type
|
TARGET_ERROR_FLAGS := -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point
|
||||||
|
|
||||||
|
# TODO: do symbol compression
|
||||||
|
TARGET_COMPRESS_MODULE_SYMBOLS := false
|
||||||
|
|
||||||
|
# Default is to prelink modules.
|
||||||
|
TARGET_PRELINK_MODULE := true
|
||||||
|
|
||||||
# ###############################################################
|
# ###############################################################
|
||||||
# Include sub-configuration files
|
# Include sub-configuration files
|
||||||
@@ -105,6 +111,32 @@ TARGET_ERROR_FLAGS := -Werror=return-type
|
|||||||
# are specific to the user's build configuration.
|
# are specific to the user's build configuration.
|
||||||
include $(BUILD_SYSTEM)/envsetup.mk
|
include $(BUILD_SYSTEM)/envsetup.mk
|
||||||
|
|
||||||
|
# Boards may be defined under $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)
|
||||||
|
# or under vendor/*/$(TARGET_DEVICE). Search in both places, but
|
||||||
|
# make sure only one exists.
|
||||||
|
# Real boards should always be associated with an OEM vendor.
|
||||||
|
board_config_mk := \
|
||||||
|
$(strip $(wildcard \
|
||||||
|
$(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk \
|
||||||
|
vendor/*/$(TARGET_DEVICE)/BoardConfig.mk \
|
||||||
|
))
|
||||||
|
ifeq ($(board_config_mk),)
|
||||||
|
$(error No config file found for TARGET_DEVICE $(TARGET_DEVICE))
|
||||||
|
endif
|
||||||
|
ifneq ($(words $(board_config_mk)),1)
|
||||||
|
$(error Multiple board config files for TARGET_DEVICE $(TARGET_DEVICE): $(board_config_mk))
|
||||||
|
endif
|
||||||
|
include $(board_config_mk)
|
||||||
|
TARGET_DEVICE_DIR := $(patsubst %/,%,$(dir $(board_config_mk)))
|
||||||
|
board_config_mk :=
|
||||||
|
|
||||||
|
# Clean up/verify variables defined by the board config file.
|
||||||
|
TARGET_BOOTLOADER_BOARD_NAME := $(strip $(TARGET_BOOTLOADER_BOARD_NAME))
|
||||||
|
TARGET_CPU_ABI := $(strip $(TARGET_CPU_ABI))
|
||||||
|
ifeq ($(TARGET_CPU_ABI),)
|
||||||
|
$(error No TARGET_CPU_ABI defined by board config: $(board_config_mk))
|
||||||
|
endif
|
||||||
|
|
||||||
# $(1): os/arch
|
# $(1): os/arch
|
||||||
define select-android-config-h
|
define select-android-config-h
|
||||||
system/core/include/arch/$(1)/AndroidConfig.h
|
system/core/include/arch/$(1)/AndroidConfig.h
|
||||||
@@ -167,6 +199,7 @@ MKTARBALL := build/tools/mktarball.sh
|
|||||||
TUNE2FS := tune2fs
|
TUNE2FS := tune2fs
|
||||||
E2FSCK := e2fsck
|
E2FSCK := e2fsck
|
||||||
JARJAR := java -jar $(HOST_OUT_JAVA_LIBRARIES)/jarjar.jar
|
JARJAR := java -jar $(HOST_OUT_JAVA_LIBRARIES)/jarjar.jar
|
||||||
|
PROGUARD := external/proguard/bin/proguard.sh
|
||||||
|
|
||||||
# dx is java behind a shell script; no .exe necessary.
|
# dx is java behind a shell script; no .exe necessary.
|
||||||
DX := $(HOST_OUT_EXECUTABLES)/dx
|
DX := $(HOST_OUT_EXECUTABLES)/dx
|
||||||
@@ -259,10 +292,6 @@ HOST_GLOBAL_CPPFLAGS += $(HOST_RELEASE_CPPFLAGS)
|
|||||||
TARGET_GLOBAL_CFLAGS += $(TARGET_RELEASE_CFLAGS)
|
TARGET_GLOBAL_CFLAGS += $(TARGET_RELEASE_CFLAGS)
|
||||||
TARGET_GLOBAL_CPPFLAGS += $(TARGET_RELEASE_CPPFLAGS)
|
TARGET_GLOBAL_CPPFLAGS += $(TARGET_RELEASE_CPPFLAGS)
|
||||||
|
|
||||||
# TODO: do symbol compression
|
|
||||||
TARGET_COMPRESS_MODULE_SYMBOLS := false
|
|
||||||
TARGET_PRELINK_MODULE := true
|
|
||||||
|
|
||||||
PREBUILT_IS_PRESENT := $(if $(wildcard prebuilt/Android.mk),true)
|
PREBUILT_IS_PRESENT := $(if $(wildcard prebuilt/Android.mk),true)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -109,7 +109,14 @@ endef
|
|||||||
|
|
||||||
# Figure out where we are.
|
# Figure out where we are.
|
||||||
define my-dir
|
define my-dir
|
||||||
$(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST),$(MAKEFILE_LIST))))
|
$(strip \
|
||||||
|
$(eval md_file_ := $$(lastword $$(MAKEFILE_LIST))) \
|
||||||
|
$(if $(filter $(CLEAR_VARS),$(md_file_)), \
|
||||||
|
$(error LOCAL_PATH must be set before including $$(CLEAR_VARS)) \
|
||||||
|
, \
|
||||||
|
$(patsubst %/,%,$(dir $(md_file_))) \
|
||||||
|
) \
|
||||||
|
)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
###########################################################
|
###########################################################
|
||||||
@@ -128,7 +135,8 @@ endef
|
|||||||
# $(1): directory to search under
|
# $(1): directory to search under
|
||||||
# Ignores $(1)/Android.mk
|
# Ignores $(1)/Android.mk
|
||||||
define first-makefiles-under
|
define first-makefiles-under
|
||||||
$(shell build/tools/findleaves.sh --mindepth=2 $(1) Android.mk)
|
$(shell build/tools/findleaves.py --prune=out --prune=.repo --prune=.git \
|
||||||
|
--mindepth=2 $(1) Android.mk)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
###########################################################
|
###########################################################
|
||||||
@@ -1166,6 +1174,7 @@ $(hide) $(AAPT) package $(PRIVATE_AAPT_FLAGS) -m -z \
|
|||||||
$(addprefix -S , $(PRIVATE_RESOURCE_DIR)) \
|
$(addprefix -S , $(PRIVATE_RESOURCE_DIR)) \
|
||||||
$(addprefix -A , $(PRIVATE_ASSET_DIR)) \
|
$(addprefix -A , $(PRIVATE_ASSET_DIR)) \
|
||||||
$(addprefix -I , $(PRIVATE_AAPT_INCLUDES)) \
|
$(addprefix -I , $(PRIVATE_AAPT_INCLUDES)) \
|
||||||
|
$(addprefix -G , $(PRIVATE_PROGUARD_OPTIONS_FILE)) \
|
||||||
$(addprefix --min-sdk-version , $(DEFAULT_APP_TARGET_SDK)) \
|
$(addprefix --min-sdk-version , $(DEFAULT_APP_TARGET_SDK)) \
|
||||||
$(addprefix --target-sdk-version , $(DEFAULT_APP_TARGET_SDK)) \
|
$(addprefix --target-sdk-version , $(DEFAULT_APP_TARGET_SDK)) \
|
||||||
$(addprefix --version-code , $(PLATFORM_SDK_VERSION)) \
|
$(addprefix --version-code , $(PLATFORM_SDK_VERSION)) \
|
||||||
@@ -1264,11 +1273,12 @@ endef
|
|||||||
|
|
||||||
#TODO: use a smaller -Xmx value for most libraries;
|
#TODO: use a smaller -Xmx value for most libraries;
|
||||||
# only core.jar and framework.jar need a heap this big.
|
# only core.jar and framework.jar need a heap this big.
|
||||||
|
# Avoid the memory arguments on Windows, dx fails to load for some reason with them.
|
||||||
define transform-classes.jar-to-dex
|
define transform-classes.jar-to-dex
|
||||||
@echo "target Dex: $(PRIVATE_MODULE)"
|
@echo "target Dex: $(PRIVATE_MODULE)"
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
$(hide) $(DX) -JXms16M \
|
$(hide) $(DX) \
|
||||||
-JXmx1536M \
|
$(if $(findstring windows,$(HOST_OS)),,-JXms16M -JXmx1536M) \
|
||||||
--dex --output=$@ \
|
--dex --output=$@ \
|
||||||
$(if $(NO_OPTIMIZE_DX), \
|
$(if $(NO_OPTIMIZE_DX), \
|
||||||
--no-optimize) \
|
--no-optimize) \
|
||||||
@@ -1324,11 +1334,9 @@ $(hide) (cd $(dir $@) && zip -r $(notdir $@) lib)
|
|||||||
$(hide) rm -rf $(dir $@)lib
|
$(hide) rm -rf $(dir $@)lib
|
||||||
endef
|
endef
|
||||||
|
|
||||||
#TODO: use aapt instead of zip, once it supports junking the path
|
|
||||||
# (so adding "xxx/yyy/classes.dex" appears as "classes.dex")
|
|
||||||
#TODO: update the manifest to point to the dex file
|
#TODO: update the manifest to point to the dex file
|
||||||
define add-dex-to-package
|
define add-dex-to-package
|
||||||
$(hide) zip -qj $@ $(PRIVATE_DEX_FILE)
|
$(hide) $(AAPT) add -k $@ $(PRIVATE_DEX_FILE)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define add-java-resources-to-package
|
define add-java-resources-to-package
|
||||||
@@ -1587,7 +1595,7 @@ $(if $(2), \
|
|||||||
echo "$$printname total size is $$total"; \
|
echo "$$printname total size is $$total"; \
|
||||||
img_blocksize=$(call image-size-from-data-size,$(BOARD_FLASH_BLOCK_SIZE)); \
|
img_blocksize=$(call image-size-from-data-size,$(BOARD_FLASH_BLOCK_SIZE)); \
|
||||||
if [ "$(3)" == "yaffs" ]; then \
|
if [ "$(3)" == "yaffs" ]; then \
|
||||||
reservedblocks=5; \
|
reservedblocks=8; \
|
||||||
else \
|
else \
|
||||||
reservedblocks=0; \
|
reservedblocks=0; \
|
||||||
fi; \
|
fi; \
|
||||||
@@ -1607,6 +1615,37 @@ $(if $(2), \
|
|||||||
)
|
)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
# Like assert-max-file-size, but the second argument is a partition
|
||||||
|
# size, which we'll convert to a max image size before checking it
|
||||||
|
# against the files.
|
||||||
|
#
|
||||||
|
# $(1): The file(s) to check (often $@)
|
||||||
|
# $(2): The partition size.
|
||||||
|
define assert-max-image-size
|
||||||
|
$(if $(2), \
|
||||||
|
$(call assert-max-file-size,$(1),$(call image-size-from-data-size,$(2))), \
|
||||||
|
true)
|
||||||
|
endef
|
||||||
|
|
||||||
|
|
||||||
|
###########################################################
|
||||||
|
## Define device-specific radio files
|
||||||
|
###########################################################
|
||||||
|
|
||||||
|
# Copy a radio image file to the output location, and add it to
|
||||||
|
# INSTALLED_RADIOIMAGE_TARGET.
|
||||||
|
# $(1): filename
|
||||||
|
define add-radio-file
|
||||||
|
$(eval $(call add-radio-file-internal,$(1)))
|
||||||
|
endef
|
||||||
|
define add-radio-file-internal
|
||||||
|
INSTALLED_RADIOIMAGE_TARGET += $$(PRODUCT_OUT)/$(1)
|
||||||
|
ALL_PREBUILT += $$(PRODUCT_OUT)/$(1)
|
||||||
|
$$(PRODUCT_OUT)/$(1) : $$(LOCAL_PATH)/$(1) | $$(ACP)
|
||||||
|
$$(transform-prebuilt-to-target)
|
||||||
|
endef
|
||||||
|
|
||||||
|
|
||||||
###########################################################
|
###########################################################
|
||||||
## Other includes
|
## Other includes
|
||||||
###########################################################
|
###########################################################
|
||||||
|
@@ -173,7 +173,7 @@ ifeq ($(TARGET_SIMULATOR),true)
|
|||||||
# under product/) are actually host-dependent.
|
# under product/) are actually host-dependent.
|
||||||
# But, the debug type is controlled by TARGET_BUILD_TYPE and not
|
# But, the debug type is controlled by TARGET_BUILD_TYPE and not
|
||||||
# HOST_BUILD_TYPE.
|
# HOST_BUILD_TYPE.
|
||||||
TARGET_PRODUCT_OUT_ROOT := $(HOST_OUT_$(TARGET_BUILD_TYPE))/product
|
TARGET_PRODUCT_OUT_ROOT := $(HOST_OUT_$(TARGET_BUILD_TYPE))/pr
|
||||||
else
|
else
|
||||||
TARGET_PRODUCT_OUT_ROOT := $(TARGET_OUT_ROOT)/product
|
TARGET_PRODUCT_OUT_ROOT := $(TARGET_OUT_ROOT)/product
|
||||||
endif
|
endif
|
||||||
@@ -270,7 +270,7 @@ ifeq ($(TARGET_SIMULATOR),true)
|
|||||||
ABP:=$(ABP):$(TARGET_OUT_EXECUTABLES)
|
ABP:=$(ABP):$(TARGET_OUT_EXECUTABLES)
|
||||||
else
|
else
|
||||||
# this should be copied to HOST_OUT_EXECUTABLES instead
|
# this should be copied to HOST_OUT_EXECUTABLES instead
|
||||||
ABP:=$(ABP):$(PWD)/prebuilt/$(HOST_PREBUILT_TAG)/toolchain/arm-eabi-4.2.1/bin
|
ABP:=$(ABP):$(PWD)/prebuilt/$(HOST_PREBUILT_TAG)/toolchain/arm-eabi-4.4.0/bin
|
||||||
endif
|
endif
|
||||||
ANDROID_BUILD_PATHS := $(ABP)
|
ANDROID_BUILD_PATHS := $(ABP)
|
||||||
ANDROID_PREBUILTS := prebuilt/$(HOST_PREBUILT_TAG)
|
ANDROID_PREBUILTS := prebuilt/$(HOST_PREBUILT_TAG)
|
||||||
@@ -335,5 +335,3 @@ $(info HOST_BUILD_TYPE=$(HOST_BUILD_TYPE))
|
|||||||
$(info BUILD_ID=$(BUILD_ID))
|
$(info BUILD_ID=$(BUILD_ID))
|
||||||
$(info ============================================)
|
$(info ============================================)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,7 +1,11 @@
|
|||||||
if [[ "x$ANDROID_JAVA_HOME" != x && -e $ANDROID_JAVA_HOME/lib/tools.jar ]] ; then
|
if [ "x$ANDROID_JAVA_HOME" != x ] && [ -e "$ANDROID_JAVA_HOME/lib/tools.jar" ] ; then
|
||||||
echo $ANDROID_JAVA_HOME/lib/tools.jar
|
echo $ANDROID_JAVA_HOME/lib/tools.jar
|
||||||
else
|
else
|
||||||
JAVAC=$(which javac)
|
JAVAC=$(which javac)
|
||||||
|
if [ -z "$JAVAC" ] ; then
|
||||||
|
echo "Please-install-JDK-5.0,-update-12-or-higher,-which-you-can-download-from-java.sun.com"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
while [ -L $JAVAC ] ; do
|
while [ -L $JAVAC ] ; do
|
||||||
LSLINE=$(ls -l $JAVAC)
|
LSLINE=$(ls -l $JAVAC)
|
||||||
JAVAC=$(echo -n $LSLINE | sed -e "s/.* -> //")
|
JAVAC=$(echo -n $LSLINE | sed -e "s/.* -> //")
|
||||||
|
44
core/java.mk
44
core/java.mk
@@ -68,7 +68,8 @@ emma_intermediates_dir := $(intermediates.COMMON)/emma_out
|
|||||||
# the emma tool
|
# the emma tool
|
||||||
full_classes_emma_jar := $(emma_intermediates_dir)/lib/$(full_classes_compiled_jar_leaf)
|
full_classes_emma_jar := $(emma_intermediates_dir)/lib/$(full_classes_compiled_jar_leaf)
|
||||||
full_classes_stubs_jar := $(intermediates.COMMON)/stubs.jar
|
full_classes_stubs_jar := $(intermediates.COMMON)/stubs.jar
|
||||||
full_classes_jarjar_jar := $(full_classes_jar)
|
full_classes_jarjar_jar := $(intermediates.COMMON)/classes-jarjar.jar
|
||||||
|
full_classes_proguard_jar := $(full_classes_jar)
|
||||||
built_dex := $(intermediates.COMMON)/classes.dex
|
built_dex := $(intermediates.COMMON)/classes.dex
|
||||||
|
|
||||||
LOCAL_INTERMEDIATE_TARGETS += \
|
LOCAL_INTERMEDIATE_TARGETS += \
|
||||||
@@ -174,15 +175,14 @@ $(full_classes_emma_jar): $(full_classes_compiled_jar)
|
|||||||
$(PRIVATE_EMMA_COVERAGE_FILE): $(full_classes_emma_jar)
|
$(PRIVATE_EMMA_COVERAGE_FILE): $(full_classes_emma_jar)
|
||||||
else
|
else
|
||||||
$(full_classes_emma_jar): $(full_classes_compiled_jar) | $(ACP)
|
$(full_classes_emma_jar): $(full_classes_compiled_jar) | $(ACP)
|
||||||
@echo Copying $<
|
@echo Copying: $<
|
||||||
$(copy-file-to-target)
|
$(copy-file-to-target)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Run jarjar if necessary, otherwise just copy the file. This is the last
|
# Run jarjar if necessary, otherwise just copy the file.
|
||||||
# part of this step, so the output of this command is full_classes_jar.
|
|
||||||
ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
|
ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
|
||||||
$(full_classes_jarjar_jar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
|
$(full_classes_jarjar_jar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
|
||||||
$(full_classes_jarjar_jar): $(full_classes_emma_jar) | jarjar
|
$(full_classes_jarjar_jar): $(full_classes_emma_jar) | $(JARJAR)
|
||||||
@echo JarJar: $@
|
@echo JarJar: $@
|
||||||
$(hide) $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
|
$(hide) $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
|
||||||
else
|
else
|
||||||
@@ -191,6 +191,40 @@ $(full_classes_jarjar_jar): $(full_classes_emma_jar) | $(ACP)
|
|||||||
$(hide) $(ACP) $< $@
|
$(hide) $(ACP) $< $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Run proguard if necessary, otherwise just copy the file. This is the last
|
||||||
|
# part of this step, so the output of this command is full_classes_jar.
|
||||||
|
ifneq ($(strip $(LOCAL_PROGUARD_ENABLED)),)
|
||||||
|
proguard_dictionary := $(intermediates.COMMON)/proguard_dictionary
|
||||||
|
proguard_flags := $(addprefix -libraryjars ,$(full_java_libs)) \
|
||||||
|
-include $(BUILD_SYSTEM)/proguard.flags \
|
||||||
|
-forceprocessing \
|
||||||
|
-printmapping $(proguard_dictionary)
|
||||||
|
ifeq ($(strip $(LOCAL_PROGUARD_ENABLED)),full)
|
||||||
|
# full
|
||||||
|
else
|
||||||
|
ifeq ($(strip $(LOCAL_PROGUARD_ENABLED)),optonly)
|
||||||
|
# optonly
|
||||||
|
proguard_flags += -dontobfuscate
|
||||||
|
else
|
||||||
|
ifeq ($(strip $(LOCAL_PROGUARD_ENABLED)),custom)
|
||||||
|
# custom
|
||||||
|
else
|
||||||
|
$(warning while processing: $(LOCAL_MODULE))
|
||||||
|
$(error invalid value for LOCAL_PROGUARD_ENABLED: $(LOCAL_PROGUARD_ENABLED))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(full_classes_proguard_jar): PRIVATE_PROGUARD_FLAGS := $(proguard_flags) $(LOCAL_PROGUARD_FLAGS)
|
||||||
|
$(full_classes_proguard_jar): $(full_classes_emma_jar) | $(PROGUARD)
|
||||||
|
@echo Proguard: $@
|
||||||
|
$(hide) $(PROGUARD) -injars $< -outjars $@ $(PRIVATE_PROGUARD_FLAGS)
|
||||||
|
else
|
||||||
|
$(full_classes_proguard_jar): $(full_classes_emma_jar) | $(ACP)
|
||||||
|
@echo Copying: $@
|
||||||
|
$(hide) $(ACP) $< $@
|
||||||
|
endif
|
||||||
|
|
||||||
# Override PRIVATE_INTERMEDIATES_DIR so that install-dex-debug
|
# Override PRIVATE_INTERMEDIATES_DIR so that install-dex-debug
|
||||||
# will work even when intermediates != intermediates.COMMON.
|
# will work even when intermediates != intermediates.COMMON.
|
||||||
$(built_dex): PRIVATE_INTERMEDIATES_DIR := $(intermediates.COMMON)
|
$(built_dex): PRIVATE_INTERMEDIATES_DIR := $(intermediates.COMMON)
|
||||||
|
88
core/main.mk
88
core/main.mk
@@ -54,6 +54,12 @@ include $(BUILD_SYSTEM)/config.mk
|
|||||||
# be generated correctly
|
# be generated correctly
|
||||||
include $(BUILD_SYSTEM)/cleanbuild.mk
|
include $(BUILD_SYSTEM)/cleanbuild.mk
|
||||||
|
|
||||||
|
VERSION_CHECK_SEQUENCE_NUMBER := 1
|
||||||
|
-include $(OUT_DIR)/versions_checked.mk
|
||||||
|
ifneq ($(VERSION_CHECK_SEQUENCE_NUMBER),$(VERSIONS_CHECKED))
|
||||||
|
|
||||||
|
$(info Checking build tools versions...)
|
||||||
|
|
||||||
ifneq ($(HOST_OS),windows)
|
ifneq ($(HOST_OS),windows)
|
||||||
ifneq ($(HOST_OS)-$(HOST_ARCH),darwin-ppc)
|
ifneq ($(HOST_OS)-$(HOST_ARCH),darwin-ppc)
|
||||||
# check for a case sensitive file system
|
# check for a case sensitive file system
|
||||||
@@ -123,6 +129,10 @@ endif
|
|||||||
|
|
||||||
endif # windows
|
endif # windows
|
||||||
|
|
||||||
|
$(shell echo 'VERSIONS_CHECKED := $(VERSION_CHECK_SEQUENCE_NUMBER)' \
|
||||||
|
> $(OUT_DIR)/versions_checked.mk)
|
||||||
|
endif
|
||||||
|
|
||||||
# These are the modifier targets that don't do anything themselves, but
|
# These are the modifier targets that don't do anything themselves, but
|
||||||
# change the behavior of the build.
|
# change the behavior of the build.
|
||||||
# (must be defined before including definitions.make)
|
# (must be defined before including definitions.make)
|
||||||
@@ -220,7 +230,8 @@ ifeq ($(TARGET_BUILD_VARIANT),eng)
|
|||||||
tags_to_install := user debug eng
|
tags_to_install := user debug eng
|
||||||
# Don't require the setup wizard on eng builds
|
# Don't require the setup wizard on eng builds
|
||||||
ADDITIONAL_BUILD_PROPERTIES := $(filter-out ro.setupwizard.mode=%,\
|
ADDITIONAL_BUILD_PROPERTIES := $(filter-out ro.setupwizard.mode=%,\
|
||||||
$(call collapse-pairs, $(ADDITIONAL_BUILD_PROPERTIES)))
|
$(call collapse-pairs, $(ADDITIONAL_BUILD_PROPERTIES))) \
|
||||||
|
ro.setupwizard.mode=OPTIONAL
|
||||||
endif
|
endif
|
||||||
|
|
||||||
## tests ##
|
## tests ##
|
||||||
@@ -241,8 +252,16 @@ tags_to_install := user debug eng
|
|||||||
ADDITIONAL_BUILD_PROPERTIES += xmpp.auto-presence=true
|
ADDITIONAL_BUILD_PROPERTIES += xmpp.auto-presence=true
|
||||||
ADDITIONAL_BUILD_PROPERTIES += ro.config.nocheckin=yes
|
ADDITIONAL_BUILD_PROPERTIES += ro.config.nocheckin=yes
|
||||||
else # !sdk
|
else # !sdk
|
||||||
# Enable sync for non-sdk builds only (sdk builds lack SubscribedFeedsProvider).
|
endif
|
||||||
ADDITIONAL_BUILD_PROPERTIES += ro.config.sync=yes
|
|
||||||
|
## precise GC ##
|
||||||
|
|
||||||
|
ifneq ($(filter dalvik.gc.type-precise,$(PRODUCT_TAGS)),)
|
||||||
|
# Enabling type-precise GC results in larger optimized DEX files. The
|
||||||
|
# additional storage requirements for ".odex" files can cause /system
|
||||||
|
# to overflow on some devices, so this is configured separately for
|
||||||
|
# each product.
|
||||||
|
ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.dexopt-flags=m=y
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Install an apns-conf.xml file if one's not already being installed.
|
# Install an apns-conf.xml file if one's not already being installed.
|
||||||
@@ -256,7 +275,7 @@ endif
|
|||||||
# If we're on an eng or tests build, but not on the sdk, and we have
|
# If we're on an eng or tests build, but not on the sdk, and we have
|
||||||
# a better one, use that instead.
|
# a better one, use that instead.
|
||||||
ifneq ($(filter eng tests,$(TARGET_BUILD_VARIANT)),)
|
ifneq ($(filter eng tests,$(TARGET_BUILD_VARIANT)),)
|
||||||
ifdef is_sdk_build
|
ifndef is_sdk_build
|
||||||
apns_to_use := $(wildcard vendor/google/etc/apns-conf.xml)
|
apns_to_use := $(wildcard vendor/google/etc/apns-conf.xml)
|
||||||
ifneq ($(strip $(apns_to_use)),)
|
ifneq ($(strip $(apns_to_use)),)
|
||||||
PRODUCT_COPY_FILES := \
|
PRODUCT_COPY_FILES := \
|
||||||
@@ -267,6 +286,7 @@ ifneq ($(filter eng tests,$(TARGET_BUILD_VARIANT)),)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ADDITIONAL_BUILD_PROPERTIES += net.bt.name=Android
|
ADDITIONAL_BUILD_PROPERTIES += net.bt.name=Android
|
||||||
|
ADDITIONAL_BUILD_PROPERTIES += ro.config.sync=yes
|
||||||
|
|
||||||
# enable vm tracing in files for now to help track
|
# enable vm tracing in files for now to help track
|
||||||
# the cause of ANRs in the content process
|
# the cause of ANRs in the content process
|
||||||
@@ -317,8 +337,6 @@ endif
|
|||||||
# Bring in all modules that need to be built.
|
# Bring in all modules that need to be built.
|
||||||
ifneq ($(dont_bother),true)
|
ifneq ($(dont_bother),true)
|
||||||
|
|
||||||
subdir_makefiles :=
|
|
||||||
|
|
||||||
ifeq ($(HOST_OS),windows)
|
ifeq ($(HOST_OS),windows)
|
||||||
SDK_ONLY := true
|
SDK_ONLY := true
|
||||||
endif
|
endif
|
||||||
@@ -338,6 +356,7 @@ subdirs := \
|
|||||||
dalvik/tools/hprof-conv \
|
dalvik/tools/hprof-conv \
|
||||||
development/emulator/mksdcard \
|
development/emulator/mksdcard \
|
||||||
development/tools/line_endings \
|
development/tools/line_endings \
|
||||||
|
development/tools/sdklauncher \
|
||||||
development/host \
|
development/host \
|
||||||
external/expat \
|
external/expat \
|
||||||
external/libpng \
|
external/libpng \
|
||||||
@@ -371,6 +390,7 @@ subdirs += \
|
|||||||
development/tools/sdkstats \
|
development/tools/sdkstats \
|
||||||
development/tools/sdkmanager \
|
development/tools/sdkmanager \
|
||||||
development/tools/mkstubs \
|
development/tools/mkstubs \
|
||||||
|
development/tools/layoutopt \
|
||||||
frameworks/base \
|
frameworks/base \
|
||||||
frameworks/base/tools/layoutlib \
|
frameworks/base/tools/layoutlib \
|
||||||
external/googleclient \
|
external/googleclient \
|
||||||
@@ -390,8 +410,6 @@ ifeq ($(BUILD_TINY_ANDROID), true)
|
|||||||
# TINY_ANDROID is a super-minimal build configuration, handy for board
|
# TINY_ANDROID is a super-minimal build configuration, handy for board
|
||||||
# bringup and very low level debugging
|
# bringup and very low level debugging
|
||||||
|
|
||||||
INTERNAL_DEFAULT_DOCS_TARGETS :=
|
|
||||||
|
|
||||||
subdirs := \
|
subdirs := \
|
||||||
bionic \
|
bionic \
|
||||||
system/core \
|
system/core \
|
||||||
@@ -410,7 +428,6 @@ else # !BUILD_TINY_ANDROID
|
|||||||
#
|
#
|
||||||
# Typical build; include any Android.mk files we can find.
|
# Typical build; include any Android.mk files we can find.
|
||||||
#
|
#
|
||||||
INTERNAL_DEFAULT_DOCS_TARGETS := offline-sdk-docs
|
|
||||||
subdirs := $(TOP)
|
subdirs := $(TOP)
|
||||||
|
|
||||||
FULL_BUILD := true
|
FULL_BUILD := true
|
||||||
@@ -419,41 +436,6 @@ endif # !BUILD_TINY_ANDROID
|
|||||||
|
|
||||||
endif # !SDK_ONLY
|
endif # !SDK_ONLY
|
||||||
|
|
||||||
# Can't use first-makefiles-under here because
|
|
||||||
# --mindepth=2 makes the prunes not work.
|
|
||||||
subdir_makefiles += \
|
|
||||||
$(shell build/tools/findleaves.sh --prune="./out" $(subdirs) Android.mk)
|
|
||||||
|
|
||||||
# Boards may be defined under $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)
|
|
||||||
# or under vendor/*/$(TARGET_DEVICE). Search in both places, but
|
|
||||||
# make sure only one exists.
|
|
||||||
# Real boards should always be associated with an OEM vendor.
|
|
||||||
board_config_mk := \
|
|
||||||
$(strip $(wildcard \
|
|
||||||
$(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk \
|
|
||||||
vendor/*/$(TARGET_DEVICE)/BoardConfig.mk \
|
|
||||||
))
|
|
||||||
ifeq ($(board_config_mk),)
|
|
||||||
$(error No config file found for TARGET_DEVICE $(TARGET_DEVICE))
|
|
||||||
endif
|
|
||||||
ifneq ($(words $(board_config_mk)),1)
|
|
||||||
$(error Multiple board config files for TARGET_DEVICE $(TARGET_DEVICE): $(board_config_mk))
|
|
||||||
endif
|
|
||||||
include $(board_config_mk)
|
|
||||||
TARGET_DEVICE_DIR := $(patsubst %/,%,$(dir $(board_config_mk)))
|
|
||||||
board_config_mk :=
|
|
||||||
|
|
||||||
# Clean up/verify variables defined by the board config file.
|
|
||||||
TARGET_BOOTLOADER_BOARD_NAME := $(strip $(TARGET_BOOTLOADER_BOARD_NAME))
|
|
||||||
TARGET_CPU_ABI := $(strip $(TARGET_CPU_ABI))
|
|
||||||
ifeq ($(TARGET_CPU_ABI),)
|
|
||||||
$(error No TARGET_CPU_ABI defined by board config: $(board_config_mk))
|
|
||||||
endif
|
|
||||||
|
|
||||||
#
|
|
||||||
# Include all of the makefiles in the system
|
|
||||||
#
|
|
||||||
|
|
||||||
ifneq ($(ONE_SHOT_MAKEFILE),)
|
ifneq ($(ONE_SHOT_MAKEFILE),)
|
||||||
# We've probably been invoked by the "mm" shell function
|
# We've probably been invoked by the "mm" shell function
|
||||||
# with a subdirectory's makefile.
|
# with a subdirectory's makefile.
|
||||||
@@ -465,14 +447,25 @@ include $(ONE_SHOT_MAKEFILE)
|
|||||||
# would have been with a normal make.
|
# would have been with a normal make.
|
||||||
CUSTOM_MODULES := $(sort $(call get-tagged-modules,$(ALL_MODULE_TAGS),))
|
CUSTOM_MODULES := $(sort $(call get-tagged-modules,$(ALL_MODULE_TAGS),))
|
||||||
FULL_BUILD :=
|
FULL_BUILD :=
|
||||||
INTERNAL_DEFAULT_DOCS_TARGETS :=
|
|
||||||
# Stub out the notice targets, which probably aren't defined
|
# Stub out the notice targets, which probably aren't defined
|
||||||
# when using ONE_SHOT_MAKEFILE.
|
# when using ONE_SHOT_MAKEFILE.
|
||||||
NOTICE-HOST-%: ;
|
NOTICE-HOST-%: ;
|
||||||
NOTICE-TARGET-%: ;
|
NOTICE-TARGET-%: ;
|
||||||
else
|
|
||||||
|
else # ONE_SHOT_MAKEFILE
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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 --prune=out --prune=.repo --prune=.git $(subdirs) Android.mk)
|
||||||
|
|
||||||
include $(subdir_makefiles)
|
include $(subdir_makefiles)
|
||||||
endif
|
endif # ONE_SHOT_MAKEFILE
|
||||||
|
|
||||||
# -------------------------------------------------------------------
|
# -------------------------------------------------------------------
|
||||||
# All module makefiles have been included at this point.
|
# All module makefiles have been included at this point.
|
||||||
# -------------------------------------------------------------------
|
# -------------------------------------------------------------------
|
||||||
@@ -673,7 +666,6 @@ droidcore: files \
|
|||||||
$(INSTALLED_BOOTIMAGE_TARGET) \
|
$(INSTALLED_BOOTIMAGE_TARGET) \
|
||||||
$(INSTALLED_RECOVERYIMAGE_TARGET) \
|
$(INSTALLED_RECOVERYIMAGE_TARGET) \
|
||||||
$(INSTALLED_USERDATAIMAGE_TARGET) \
|
$(INSTALLED_USERDATAIMAGE_TARGET) \
|
||||||
$(INTERNAL_DEFAULT_DOCS_TARGETS) \
|
|
||||||
$(INSTALLED_FILES_FILE)
|
$(INSTALLED_FILES_FILE)
|
||||||
|
|
||||||
# The actual files built by the droidcore target changes depending
|
# The actual files built by the droidcore target changes depending
|
||||||
|
@@ -53,13 +53,13 @@ $(foreach t,$(1), \
|
|||||||
$(eval LOCAL_MODULE := $(word 1,$(tw))) \
|
$(eval LOCAL_MODULE := $(word 1,$(tw))) \
|
||||||
$(eval LOCAL_SRC_FILES := $(word 2,$(tw))) \
|
$(eval LOCAL_SRC_FILES := $(word 2,$(tw))) \
|
||||||
, \
|
, \
|
||||||
$(eval LOCAL_MODULE := $(basename $(t))) \
|
$(eval LOCAL_MODULE := $(basename $(notdir $(t)))) \
|
||||||
$(eval LOCAL_SRC_FILES := $(t)) \
|
$(eval LOCAL_SRC_FILES := $(t)) \
|
||||||
) \
|
) \
|
||||||
$(if $(6), \
|
$(if $(6), \
|
||||||
$(eval LOCAL_BUILT_MODULE_STEM := $(6)) \
|
$(eval LOCAL_BUILT_MODULE_STEM := $(6)) \
|
||||||
, \
|
, \
|
||||||
$(eval LOCAL_BUILT_MODULE_STEM := $(LOCAL_SRC_FILES)) \
|
$(eval LOCAL_BUILT_MODULE_STEM := $(notdir $(LOCAL_SRC_FILES))) \
|
||||||
) \
|
) \
|
||||||
$(eval LOCAL_MODULE_SUFFIX := $(suffix $(LOCAL_SRC_FILES))) \
|
$(eval LOCAL_MODULE_SUFFIX := $(suffix $(LOCAL_SRC_FILES))) \
|
||||||
$(eval include $(BUILD_PREBUILT)) \
|
$(eval include $(BUILD_PREBUILT)) \
|
||||||
|
@@ -186,7 +186,9 @@ endef
|
|||||||
define _import-node
|
define _import-node
|
||||||
$(eval _include_stack := $(2) $$(_include_stack))
|
$(eval _include_stack := $(2) $$(_include_stack))
|
||||||
$(call clear-var-list, $(3))
|
$(call clear-var-list, $(3))
|
||||||
|
$(eval LOCAL_PATH := $(patsubst %/,%,$(dir $(2))))
|
||||||
$(eval include $(2))
|
$(eval include $(2))
|
||||||
|
$(eval LOCAL_PATH :=)
|
||||||
$(call copy-var-list, $(1).$(2), $(3))
|
$(call copy-var-list, $(1).$(2), $(3))
|
||||||
$(call clear-var-list, $(3))
|
$(call clear-var-list, $(3))
|
||||||
|
|
||||||
|
@@ -24,8 +24,15 @@ else
|
|||||||
else
|
else
|
||||||
ifeq ($(LOCAL_MODULE_CLASS),JAVA_LIBRARIES)
|
ifeq ($(LOCAL_MODULE_CLASS),JAVA_LIBRARIES)
|
||||||
# Stick the static java libraries with the regular java libraries.
|
# Stick the static java libraries with the regular java libraries.
|
||||||
|
module_leaf := $(notdir $(LOCAL_BUILT_MODULE))
|
||||||
|
# javalib.jar is the default name for the build module (and isn't meaningful)
|
||||||
|
# If that's what we have, substitute the module name instead. These files
|
||||||
|
# aren't included on the device, so this name is synthetic anyway.
|
||||||
|
ifeq ($(module_leaf),javalib.jar)
|
||||||
|
module_leaf := $(LOCAL_MODULE).jar
|
||||||
|
endif
|
||||||
module_installed_filename := \
|
module_installed_filename := \
|
||||||
$(patsubst $(PRODUCT_OUT)%,%,$($(my_prefix)OUT_JAVA_LIBRARIES))/$(notdir $(LOCAL_BUILT_MODULE))
|
$(patsubst $(PRODUCT_OUT)%,%,$($(my_prefix)OUT_JAVA_LIBRARIES))/$(module_leaf)
|
||||||
else
|
else
|
||||||
$(error Cannot determine where to install NOTICE file for $(LOCAL_MODULE))
|
$(error Cannot determine where to install NOTICE file for $(LOCAL_MODULE))
|
||||||
endif # JAVA_LIBRARIES
|
endif # JAVA_LIBRARIES
|
||||||
|
@@ -111,6 +111,11 @@ endif
|
|||||||
|
|
||||||
LOCAL_BUILT_MODULE_STEM := package.apk
|
LOCAL_BUILT_MODULE_STEM := package.apk
|
||||||
|
|
||||||
|
proguard_options_file := $(package_expected_intermediates_COMMON)/proguard_options
|
||||||
|
ifneq ($(strip $(LOCAL_PROGUARD_ENABLED)),custom)
|
||||||
|
LOCAL_PROGUARD_FLAGS := -include $(proguard_options_file) $(LOCAL_PROGUARD_FLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
# The dex files go in the package, so we don't
|
# The dex files go in the package, so we don't
|
||||||
# want to install them separately for this module.
|
# want to install them separately for this module.
|
||||||
old_DONT_INSTALL_DEX_FILES := $(DONT_INSTALL_DEX_FILES)
|
old_DONT_INSTALL_DEX_FILES := $(DONT_INSTALL_DEX_FILES)
|
||||||
@@ -143,6 +148,7 @@ endif
|
|||||||
|
|
||||||
$(R_file_stamp): PRIVATE_RESOURCE_PUBLICS_OUTPUT := \
|
$(R_file_stamp): PRIVATE_RESOURCE_PUBLICS_OUTPUT := \
|
||||||
$(intermediates.COMMON)/public_resources.xml
|
$(intermediates.COMMON)/public_resources.xml
|
||||||
|
$(R_file_stamp): PRIVATE_PROGUARD_OPTIONS_FILE := $(proguard_options_file)
|
||||||
$(R_file_stamp): $(all_res_assets) $(full_android_manifest) $(AAPT) | $(ACP)
|
$(R_file_stamp): $(all_res_assets) $(full_android_manifest) $(AAPT) | $(ACP)
|
||||||
@echo "target R.java/Manifest.java: $(PRIVATE_MODULE) ($@)"
|
@echo "target R.java/Manifest.java: $(PRIVATE_MODULE) ($@)"
|
||||||
@rm -f $@
|
@rm -f $@
|
||||||
@@ -164,6 +170,8 @@ $(R_file_stamp): $(all_res_assets) $(full_android_manifest) $(AAPT) | $(ACP)
|
|||||||
$(ACP) -fpt $$GENERATED_R_FILE $@ || exit 32; \
|
$(ACP) -fpt $$GENERATED_R_FILE $@ || exit 32; \
|
||||||
done; \
|
done; \
|
||||||
|
|
||||||
|
$(proguard_options_file): $(R_file_stamp)
|
||||||
|
|
||||||
ifdef LOCAL_EXPORT_PACKAGE_RESOURCES
|
ifdef LOCAL_EXPORT_PACKAGE_RESOURCES
|
||||||
# Put this module's resources into a PRODUCT-agnositc package that
|
# Put this module's resources into a PRODUCT-agnositc package that
|
||||||
# other packages can use to build their own PRODUCT-agnostic R.java (etc.)
|
# other packages can use to build their own PRODUCT-agnostic R.java (etc.)
|
||||||
|
@@ -28,8 +28,8 @@
|
|||||||
#
|
#
|
||||||
pathmap_INCL := \
|
pathmap_INCL := \
|
||||||
bluedroid:system/bluetooth/bluedroid/include \
|
bluedroid:system/bluetooth/bluedroid/include \
|
||||||
bluez-libs:external/bluez/libs/include \
|
bluez:external/bluetooth/bluez \
|
||||||
bluez-utils:external/bluez/utils \
|
glib:external/bluetooth/glib \
|
||||||
bootloader:bootable/bootloader/legacy/include \
|
bootloader:bootable/bootloader/legacy/include \
|
||||||
corecg:external/skia/include/core \
|
corecg:external/skia/include/core \
|
||||||
dbus:external/dbus \
|
dbus:external/dbus \
|
||||||
@@ -76,7 +76,6 @@ FRAMEWORKS_BASE_SUBDIRS := \
|
|||||||
$(addsuffix /java, \
|
$(addsuffix /java, \
|
||||||
core \
|
core \
|
||||||
graphics \
|
graphics \
|
||||||
im \
|
|
||||||
location \
|
location \
|
||||||
media \
|
media \
|
||||||
opengl \
|
opengl \
|
||||||
|
@@ -26,6 +26,8 @@ else
|
|||||||
prebuilt_module_is_a_library :=
|
prebuilt_module_is_a_library :=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
PACKAGES.$(LOCAL_MODULE).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
|
||||||
|
|
||||||
# Ensure that prebuilt .apks have been aligned.
|
# Ensure that prebuilt .apks have been aligned.
|
||||||
ifneq ($(filter APPS,$(LOCAL_MODULE_CLASS)),)
|
ifneq ($(filter APPS,$(LOCAL_MODULE_CLASS)),)
|
||||||
$(LOCAL_BUILT_MODULE) : $(LOCAL_PATH)/$(LOCAL_SRC_FILES) | $(ZIPALIGN)
|
$(LOCAL_BUILT_MODULE) : $(LOCAL_PATH)/$(LOCAL_SRC_FILES) | $(ZIPALIGN)
|
||||||
|
@@ -27,7 +27,7 @@ libsysutils.so 0xAF400000
|
|||||||
liba2dp.so 0xAEE00000
|
liba2dp.so 0xAEE00000
|
||||||
audio.so 0xAED00000
|
audio.so 0xAED00000
|
||||||
input.so 0xAEC00000
|
input.so 0xAEC00000
|
||||||
libhcid.so 0xAEB00000
|
libbluetoothd.so 0xAEB00000
|
||||||
libbluedroid.so 0xAEA00000
|
libbluedroid.so 0xAEA00000
|
||||||
libbluetooth.so 0xAE900000
|
libbluetooth.so 0xAE900000
|
||||||
libdbus.so 0xAE800000
|
libdbus.so 0xAE800000
|
||||||
@@ -50,8 +50,10 @@ libdvm.so 0xAD000000
|
|||||||
|
|
||||||
# graphics
|
# graphics
|
||||||
libpixelflinger.so 0xACF00000
|
libpixelflinger.so 0xACF00000
|
||||||
|
# libcorecg is for backward-compatibility with donut
|
||||||
libcorecg.so 0xACE00000
|
libcorecg.so 0xACE00000
|
||||||
libsurfaceflinger.so 0xACD00000
|
libsurfaceflinger.so 0xACD00000
|
||||||
|
libGLES_android.so 0xACC80000
|
||||||
libagl.so 0xACC00000
|
libagl.so 0xACC00000
|
||||||
|
|
||||||
libGLESv1_CM.so 0xACB00000
|
libGLESv1_CM.so 0xACB00000
|
||||||
@@ -60,15 +62,24 @@ libOpenVG_CM.so 0xAC900000
|
|||||||
libOpenVGU_CM.so 0xAC800000
|
libOpenVGU_CM.so 0xAC800000
|
||||||
libEGL.so 0xAC700000
|
libEGL.so 0xAC700000
|
||||||
|
|
||||||
|
libacc.so 0xAC600000
|
||||||
|
|
||||||
libexif.so 0xAC500000
|
libexif.so 0xAC500000
|
||||||
libui.so 0xAC400000
|
libui.so 0xAC400000
|
||||||
libsgl.so 0xAC000000
|
# libsgl is for backward-compatibility with donut
|
||||||
|
libsgl.so 0xAC200000
|
||||||
|
libskia.so 0xAC000000
|
||||||
|
librs_jni.so 0xABF00000
|
||||||
|
libRS.so 0xAB900000
|
||||||
|
|
||||||
|
|
||||||
# audio
|
# audio
|
||||||
libspeech.so 0xAB800000
|
libaudiopolicy.so 0xAB880000
|
||||||
|
libaudiopolicygeneric.so 0xAB800000
|
||||||
|
libsoundpool.so 0xAB780000
|
||||||
libaudio.so 0xAB700000
|
libaudio.so 0xAB700000
|
||||||
libsonivox.so 0xAB600000
|
libspeech.so 0xAB600000
|
||||||
libsoundpool.so 0xAB500000
|
libsonivox.so 0xAB500000
|
||||||
libvorbisidec.so 0xAB400000
|
libvorbisidec.so 0xAB400000
|
||||||
libmedia_jni.so 0xAB300000
|
libmedia_jni.so 0xAB300000
|
||||||
libmediaplayerservice.so 0xAB280000
|
libmediaplayerservice.so 0xAB280000
|
||||||
@@ -80,6 +91,7 @@ libaudioflinger.so 0xAB000000
|
|||||||
libsqlite.so 0xAAC00000
|
libsqlite.so 0xAAC00000
|
||||||
libexpat.so 0xAAB00000
|
libexpat.so 0xAAB00000
|
||||||
libwebcore.so 0xAA000000
|
libwebcore.so 0xAA000000
|
||||||
|
libbinder.so 0xA9D80000
|
||||||
libutils.so 0xA9D00000
|
libutils.so 0xA9D00000
|
||||||
libcameraservice.so 0xA9C80000
|
libcameraservice.so 0xA9C80000
|
||||||
libhardware.so 0xA9C70000
|
libhardware.so 0xA9C70000
|
||||||
@@ -89,7 +101,7 @@ libsystem_server.so 0xA9A00000
|
|||||||
libime.so 0xA9800000
|
libime.so 0xA9800000
|
||||||
libgps.so 0xA9700000
|
libgps.so 0xA9700000
|
||||||
libcamera.so 0xA9680000
|
libcamera.so 0xA9680000
|
||||||
libqcamera.so 0xA9400000
|
liboemcamera.so 0xA9400000
|
||||||
|
|
||||||
# pv libraries
|
# pv libraries
|
||||||
libpvasf.so 0xA7C26000
|
libpvasf.so 0xA7C26000
|
||||||
@@ -105,6 +117,7 @@ libomx_aacdec_sharedlibrary.so 0xA7700000
|
|||||||
libomx_amrdec_sharedlibrary.so 0xA76A0000
|
libomx_amrdec_sharedlibrary.so 0xA76A0000
|
||||||
libomx_amrenc_sharedlibrary.so 0xA7680000
|
libomx_amrenc_sharedlibrary.so 0xA7680000
|
||||||
libomx_avcdec_sharedlibrary.so 0xA7660000
|
libomx_avcdec_sharedlibrary.so 0xA7660000
|
||||||
|
libomx_avcenc_sharedlibrary.so 0xA7610000
|
||||||
libomx_m4vdec_sharedlibrary.so 0xA75C0000
|
libomx_m4vdec_sharedlibrary.so 0xA75C0000
|
||||||
libomx_m4venc_sharedlibrary.so 0xA7590000
|
libomx_m4venc_sharedlibrary.so 0xA7590000
|
||||||
libomx_mp3dec_sharedlibrary.so 0xA7450000
|
libomx_mp3dec_sharedlibrary.so 0xA7450000
|
||||||
@@ -149,3 +162,4 @@ librpc.so 0x9A400000
|
|||||||
libtrace_test.so 0x9A300000
|
libtrace_test.so 0x9A300000
|
||||||
libsrec_jni.so 0x9A200000
|
libsrec_jni.so 0x9A200000
|
||||||
libcerttool_jni.so 0x9A100000
|
libcerttool_jni.so 0x9A100000
|
||||||
|
|
||||||
|
@@ -68,7 +68,8 @@ _product_var_list := \
|
|||||||
PRODUCT_SDK_ADDON_NAME \
|
PRODUCT_SDK_ADDON_NAME \
|
||||||
PRODUCT_SDK_ADDON_COPY_FILES \
|
PRODUCT_SDK_ADDON_COPY_FILES \
|
||||||
PRODUCT_SDK_ADDON_COPY_MODULES \
|
PRODUCT_SDK_ADDON_COPY_MODULES \
|
||||||
PRODUCT_SDK_ADDON_DOC_MODULE
|
PRODUCT_SDK_ADDON_DOC_MODULE \
|
||||||
|
PRODUCT_DEFAULT_WIFI_CHANNELS
|
||||||
|
|
||||||
define dump-product
|
define dump-product
|
||||||
$(info ==== $(1) ====)\
|
$(info ==== $(1) ====)\
|
||||||
|
@@ -193,6 +193,12 @@ ifneq (,$(extra_locales))
|
|||||||
extra_locales :=
|
extra_locales :=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Default to medium-density assets.
|
||||||
|
# (Can be overridden in the device config, e.g.: PRODUCT_LOCALES += hdpi)
|
||||||
|
PRODUCT_LOCALES := $(strip \
|
||||||
|
$(PRODUCT_LOCALES) \
|
||||||
|
$(if $(filter %dpi,$(PRODUCT_LOCALES)),,mdpi))
|
||||||
|
|
||||||
# Assemble the list of options.
|
# Assemble the list of options.
|
||||||
PRODUCT_AAPT_CONFIG := $(PRODUCT_LOCALES)
|
PRODUCT_AAPT_CONFIG := $(PRODUCT_LOCALES)
|
||||||
|
|
||||||
@@ -214,6 +220,9 @@ ifndef PRODUCT_MANUFACTURER
|
|||||||
PRODUCT_MANUFACTURER := unknown
|
PRODUCT_MANUFACTURER := unknown
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
PRODUCT_DEFAULT_WIFI_CHANNELS := \
|
||||||
|
$(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEFAULT_WIFI_CHANNELS))
|
||||||
|
|
||||||
# Which policy should this product use
|
# Which policy should this product use
|
||||||
PRODUCT_POLICY := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_POLICY))
|
PRODUCT_POLICY := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_POLICY))
|
||||||
|
|
||||||
|
7
core/proguard.flags
Normal file
7
core/proguard.flags
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# see http://sourceforge.net/tracker/?func=detail&aid=2787465&group_id=54750&atid=474707
|
||||||
|
-optimizations !code/simplification/arithmetic
|
||||||
|
-allowaccessmodification
|
||||||
|
|
||||||
|
# Some classes in the libraries extend package private classes to chare common functionality
|
||||||
|
# that isn't explicitly part of the API
|
||||||
|
-dontskipnonpubliclibraryclasses
|
@@ -68,6 +68,8 @@ CTS_CASE_LIST := \
|
|||||||
CtsAppTestCases \
|
CtsAppTestCases \
|
||||||
CtsContentTestCases \
|
CtsContentTestCases \
|
||||||
CtsDatabaseTestCases \
|
CtsDatabaseTestCases \
|
||||||
|
CtsDpiTestCases \
|
||||||
|
CtsDpiTestCases2 \
|
||||||
CtsGestureTestCases \
|
CtsGestureTestCases \
|
||||||
CtsGraphicsTestCases \
|
CtsGraphicsTestCases \
|
||||||
CtsHardwareTestCases \
|
CtsHardwareTestCases \
|
||||||
@@ -77,6 +79,7 @@ CTS_CASE_LIST := \
|
|||||||
CtsPermissionTestCases \
|
CtsPermissionTestCases \
|
||||||
CtsPermission2TestCases \
|
CtsPermission2TestCases \
|
||||||
CtsProviderTestCases \
|
CtsProviderTestCases \
|
||||||
|
CtsSpeechTestCases \
|
||||||
CtsTelephonyTestCases \
|
CtsTelephonyTestCases \
|
||||||
CtsTextTestCases \
|
CtsTextTestCases \
|
||||||
CtsUtilTestCases \
|
CtsUtilTestCases \
|
||||||
|
@@ -15,21 +15,34 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
products_pdf := $(OUT_DIR)/products.pdf
|
products_pdf := $(OUT_DIR)/products.pdf
|
||||||
|
products_graph := $(products_pdf:%.pdf=%.dot)
|
||||||
|
|
||||||
# This rule doens't include any nodes that don't inherit from
|
$(products_graph):
|
||||||
|
@echo Product graph DOT: $@
|
||||||
|
$(hide) ( \
|
||||||
|
echo 'digraph {'; \
|
||||||
|
echo 'graph [ ratio=.5 ];'; \
|
||||||
|
$(foreach p,$(ALL_PRODUCTS), \
|
||||||
|
$(foreach d,$(PRODUCTS.$(strip $(p)).INHERITS_FROM), \
|
||||||
|
echo \"$(d)\" -\> \"$(p)\";)) \
|
||||||
|
$(foreach prod, \
|
||||||
|
$(sort $(foreach p,$(ALL_PRODUCTS), \
|
||||||
|
$(foreach d,$(PRODUCTS.$(strip $(p)).INHERITS_FROM), \
|
||||||
|
$(d))) \
|
||||||
|
$(foreach p,$(ALL_PRODUCTS),$(p))), \
|
||||||
|
echo \"$(prod)\" [ label=\"$(dir $(prod))\\n$(notdir $(prod))\"];) \
|
||||||
|
echo '}' \
|
||||||
|
) > $@
|
||||||
|
|
||||||
|
# This rule doesn't include any nodes that don't inherit from
|
||||||
# anything or don't have anything inherit from them, to make the
|
# anything or don't have anything inherit from them, to make the
|
||||||
# graph more readable. To add that, add this line to the rule
|
# graph more readable. To add that, add this line to the rule
|
||||||
# below:
|
# below:
|
||||||
# $(foreach p,$(ALL_PRODUCTS), echo \"$(p)\";) \
|
# $(foreach p,$(ALL_PRODUCTS), echo \"$(p)\";) \
|
||||||
|
|
||||||
$(products_pdf):
|
$(products_pdf): $(products_graph)
|
||||||
$(hide) ( \
|
@echo Product graph PDF: $@
|
||||||
echo 'digraph {'; \
|
dot -Tpdf -Nshape=box -o $@ $<
|
||||||
$(foreach p,$(ALL_PRODUCTS), \
|
|
||||||
$(foreach d,$(PRODUCTS.$(strip $(p)).INHERITS_FROM), \
|
|
||||||
echo \"$(d)\" -\> \"$(p)\";)) \
|
|
||||||
echo '}' \
|
|
||||||
) | dot -Tpdf -Nshape=box -o $@
|
|
||||||
|
|
||||||
product-graph: $(products_pdf)
|
product-graph: $(products_pdf)
|
||||||
|
|
||||||
|
@@ -41,7 +41,7 @@ ifeq "" "$(PLATFORM_VERSION)"
|
|||||||
# which is the version that we reveal to the end user.
|
# which is the version that we reveal to the end user.
|
||||||
# Update this value when the platform version changes (rather
|
# Update this value when the platform version changes (rather
|
||||||
# than overriding it somewhere else). Can be an arbitrary string.
|
# than overriding it somewhere else). Can be an arbitrary string.
|
||||||
PLATFORM_VERSION := 1.6
|
PLATFORM_VERSION := Eclair
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq "" "$(PLATFORM_SDK_VERSION)"
|
ifeq "" "$(PLATFORM_SDK_VERSION)"
|
||||||
@@ -53,13 +53,13 @@ ifeq "" "$(PLATFORM_SDK_VERSION)"
|
|||||||
# intermediate builds). During development, this number remains at the
|
# intermediate builds). During development, this number remains at the
|
||||||
# SDK version the branch is based on and PLATFORM_VERSION_CODENAME holds
|
# SDK version the branch is based on and PLATFORM_VERSION_CODENAME holds
|
||||||
# the code-name of the new development work.
|
# the code-name of the new development work.
|
||||||
PLATFORM_SDK_VERSION := 4
|
PLATFORM_SDK_VERSION := 5
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq "" "$(PLATFORM_VERSION_CODENAME)"
|
ifeq "" "$(PLATFORM_VERSION_CODENAME)"
|
||||||
# If the build is not a final release build, then this is the current
|
# This is the current development code-name, if the build is not a final
|
||||||
# development code-name. If this is a final release build, it is simply "REL".
|
# release build. If this is a final release build, it is simply "REL".
|
||||||
PLATFORM_VERSION_CODENAME := REL
|
PLATFORM_VERSION_CODENAME := Eclair
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq "" "$(DEFAULT_APP_TARGET_SDK)"
|
ifeq "" "$(DEFAULT_APP_TARGET_SDK)"
|
||||||
|
38
envsetup.sh
38
envsetup.sh
@@ -102,7 +102,7 @@ function setpaths()
|
|||||||
# and in with the new
|
# and in with the new
|
||||||
CODE_REVIEWS=
|
CODE_REVIEWS=
|
||||||
prebuiltdir=$(getprebuilt)
|
prebuiltdir=$(getprebuilt)
|
||||||
export ANDROID_EABI_TOOLCHAIN=$prebuiltdir/toolchain/arm-eabi-4.2.1/bin
|
export ANDROID_EABI_TOOLCHAIN=$prebuiltdir/toolchain/arm-eabi-4.4.0/bin
|
||||||
export ANDROID_TOOLCHAIN=$ANDROID_EABI_TOOLCHAIN
|
export ANDROID_TOOLCHAIN=$ANDROID_EABI_TOOLCHAIN
|
||||||
export ANDROID_QTOOLS=$T/development/emulator/qtools
|
export ANDROID_QTOOLS=$T/development/emulator/qtools
|
||||||
export ANDROID_BUILD_PATHS=:$(get_build_var ANDROID_BUILD_PATHS):$ANDROID_QTOOLS:$ANDROID_TOOLCHAIN:$ANDROID_EABI_TOOLCHAIN$CODE_REVIEWS
|
export ANDROID_BUILD_PATHS=:$(get_build_var ANDROID_BUILD_PATHS):$ANDROID_QTOOLS:$ANDROID_TOOLCHAIN:$ANDROID_EABI_TOOLCHAIN$CODE_REVIEWS
|
||||||
@@ -596,6 +596,8 @@ function mm()
|
|||||||
# Find the closest Android.mk file.
|
# Find the closest Android.mk file.
|
||||||
T=$(gettop)
|
T=$(gettop)
|
||||||
local M=$(findmakefile)
|
local M=$(findmakefile)
|
||||||
|
# Remove the path to top as the makefilepath needs to be relative
|
||||||
|
local M=`echo $M|sed 's:'$T'/::'`
|
||||||
if [ ! "$T" ]; then
|
if [ ! "$T" ]; then
|
||||||
echo "Couldn't locate the top of the tree. Try setting TOP."
|
echo "Couldn't locate the top of the tree. Try setting TOP."
|
||||||
elif [ ! "$M" ]; then
|
elif [ ! "$M" ]; then
|
||||||
@@ -634,6 +636,7 @@ function mmm()
|
|||||||
ARGS="$ARGS showcommands"
|
ARGS="$ARGS showcommands"
|
||||||
else
|
else
|
||||||
echo "No Android.mk in $DIR."
|
echo "No Android.mk in $DIR."
|
||||||
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -653,6 +656,26 @@ function croot()
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cproj()
|
||||||
|
{
|
||||||
|
TOPFILE=build/core/envsetup.mk
|
||||||
|
# We redirect cd to /dev/null in case it's aliased to
|
||||||
|
# a command that prints something as a side-effect
|
||||||
|
# (like pushd)
|
||||||
|
local HERE=$PWD
|
||||||
|
T=
|
||||||
|
while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
|
||||||
|
T=$PWD
|
||||||
|
if [ -f "$T/Android.mk" ]; then
|
||||||
|
cd $T
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
cd .. > /dev/null
|
||||||
|
done
|
||||||
|
cd $HERE > /dev/null
|
||||||
|
echo "can't find Android.mk"
|
||||||
|
}
|
||||||
|
|
||||||
function pid()
|
function pid()
|
||||||
{
|
{
|
||||||
local EXE="$1"
|
local EXE="$1"
|
||||||
@@ -718,14 +741,14 @@ case `uname -s` in
|
|||||||
Darwin)
|
Darwin)
|
||||||
function sgrep()
|
function sgrep()
|
||||||
{
|
{
|
||||||
find -E . -type f -iregex '.*\.(c|h|cpp|S|java|xml)' -print0 | xargs -0 grep --color -n "$@"
|
find -E . -type f -iregex '.*\.(c|h|cpp|S|java|xml|sh|mk)' -print0 | xargs -0 grep --color -n "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
function sgrep()
|
function sgrep()
|
||||||
{
|
{
|
||||||
find . -type f -iregex '.*\.\(c\|h\|cpp\|S\|java\|xml\)' -print0 | xargs -0 grep --color -n "$@"
|
find . -type f -iregex '.*\.\(c\|h\|cpp\|S\|java\|xml\|sh\|mk\)' -print0 | xargs -0 grep --color -n "$@"
|
||||||
}
|
}
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -944,14 +967,7 @@ function runtest()
|
|||||||
echo "Couldn't locate the top of the tree. Try setting TOP." >&2
|
echo "Couldn't locate the top of the tree. Try setting TOP." >&2
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
(cd "$T" && development/testrunner/runtest.py $@)
|
("$T"/development/testrunner/runtest.py $@)
|
||||||
}
|
|
||||||
|
|
||||||
# TODO: Remove this some time after 1 June 2009
|
|
||||||
function runtest_py()
|
|
||||||
{
|
|
||||||
echo "runtest_py is obsolete; use runtest instead" >&2
|
|
||||||
return 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function godir () {
|
function godir () {
|
||||||
|
1103
history/cupcake.txt
Normal file
1103
history/cupcake.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -20,11 +20,8 @@ else
|
|||||||
INSTALLED_KERNEL_TARGET :=
|
INSTALLED_KERNEL_TARGET :=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(strip $(TARGET_NO_RADIOIMAGE)),true)
|
# Use the add-radio-file function to add values to this variable.
|
||||||
INSTALLED_RADIOIMAGE_TARGET := $(PRODUCT_OUT)/radio.img
|
|
||||||
else
|
|
||||||
INSTALLED_RADIOIMAGE_TARGET :=
|
INSTALLED_RADIOIMAGE_TARGET :=
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq (,$(wildcard $(TARGET_DEVICE_DIR)/AndroidBoard.mk))
|
ifeq (,$(wildcard $(TARGET_DEVICE_DIR)/AndroidBoard.mk))
|
||||||
ifeq (,$(wildcard $(TARGET_DEVICE_DIR)/Android.mk))
|
ifeq (,$(wildcard $(TARGET_DEVICE_DIR)/Android.mk))
|
||||||
|
@@ -6,7 +6,6 @@
|
|||||||
# The generic product target doesn't have any hardware-specific pieces.
|
# The generic product target doesn't have any hardware-specific pieces.
|
||||||
TARGET_NO_BOOTLOADER := true
|
TARGET_NO_BOOTLOADER := true
|
||||||
TARGET_NO_KERNEL := true
|
TARGET_NO_KERNEL := true
|
||||||
TARGET_NO_RADIOIMAGE := true
|
|
||||||
TARGET_CPU_ABI := armeabi
|
TARGET_CPU_ABI := armeabi
|
||||||
HAVE_HTC_AUDIO_DRIVER := true
|
HAVE_HTC_AUDIO_DRIVER := true
|
||||||
BOARD_USES_GENERIC_AUDIO := true
|
BOARD_USES_GENERIC_AUDIO := true
|
||||||
|
@@ -3,7 +3,8 @@ PRODUCT_NAME :=
|
|||||||
PRODUCT_DEVICE :=
|
PRODUCT_DEVICE :=
|
||||||
PRODUCT_POLICY := android.policy_phone
|
PRODUCT_POLICY := android.policy_phone
|
||||||
PRODUCT_PROPERTY_OVERRIDES := \
|
PRODUCT_PROPERTY_OVERRIDES := \
|
||||||
ro.config.notification_sound=F1_New_SMS.ogg
|
ro.config.notification_sound=OnTheHunt.ogg \
|
||||||
|
ro.config.alarm_alert=Alarm_Classic.ogg
|
||||||
|
|
||||||
PRODUCT_PACKAGES := \
|
PRODUCT_PACKAGES := \
|
||||||
framework-res \
|
framework-res \
|
||||||
@@ -25,4 +26,3 @@ PRODUCT_PACKAGES := \
|
|||||||
UserDictionaryProvider \
|
UserDictionaryProvider \
|
||||||
PackageInstaller \
|
PackageInstaller \
|
||||||
Bugreport
|
Bugreport
|
||||||
|
|
||||||
|
@@ -3,11 +3,17 @@
|
|||||||
# you should derive from generic_with_google.mk
|
# you should derive from generic_with_google.mk
|
||||||
|
|
||||||
PRODUCT_PACKAGES := \
|
PRODUCT_PACKAGES := \
|
||||||
|
AccountAndSyncSettings \
|
||||||
AlarmClock \
|
AlarmClock \
|
||||||
AlarmProvider \
|
AlarmProvider \
|
||||||
|
Bluetooth \
|
||||||
|
Calculator \
|
||||||
Calendar \
|
Calendar \
|
||||||
Camera \
|
Camera \
|
||||||
|
CertInstaller \
|
||||||
DrmProvider \
|
DrmProvider \
|
||||||
|
Email \
|
||||||
|
Gallery \
|
||||||
LatinIME \
|
LatinIME \
|
||||||
Mms \
|
Mms \
|
||||||
Music \
|
Music \
|
||||||
@@ -15,7 +21,6 @@ PRODUCT_PACKAGES := \
|
|||||||
Sync \
|
Sync \
|
||||||
Updater \
|
Updater \
|
||||||
CalendarProvider \
|
CalendarProvider \
|
||||||
SubscribedFeedsProvider \
|
|
||||||
SyncProvider
|
SyncProvider
|
||||||
|
|
||||||
$(call inherit-product, $(SRC_TARGET_DIR)/product/core.mk)
|
$(call inherit-product, $(SRC_TARGET_DIR)/product/core.mk)
|
||||||
|
@@ -4,13 +4,16 @@
|
|||||||
# from generic.mk
|
# from generic.mk
|
||||||
|
|
||||||
PRODUCT_PACKAGES := \
|
PRODUCT_PACKAGES := \
|
||||||
GoogleContactsProvider \
|
ContactsProvider \
|
||||||
|
GoogleContactsSyncAdapter \
|
||||||
GoogleSubscribedFeedsProvider \
|
GoogleSubscribedFeedsProvider \
|
||||||
com.google.android.gtalkservice \
|
com.google.android.gtalkservice \
|
||||||
|
com.google.android.datamessaging \
|
||||||
com.google.android.maps
|
com.google.android.maps
|
||||||
|
|
||||||
PRODUCT_COPY_FILES := \
|
PRODUCT_COPY_FILES := \
|
||||||
vendor/google/frameworks/maps/com.google.android.maps.xml:system/etc/permissions/com.google.android.maps.xml \
|
vendor/google/frameworks/maps/com.google.android.maps.xml:system/etc/permissions/com.google.android.maps.xml \
|
||||||
|
vendor/google/frameworks/datamessaging/com.google.android.datamessaging.xml:system/etc/permissions/com.google.android.datamessaging.xml \
|
||||||
vendor/google/apps/GTalkService/com.google.android.gtalkservice.xml:system/etc/permissions/com.google.android.gtalkservice.xml
|
vendor/google/apps/GTalkService/com.google.android.gtalkservice.xml:system/etc/permissions/com.google.android.gtalkservice.xml
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
|
|
||||||
PRODUCT_POLICY := android.policy_phone
|
PRODUCT_POLICY := android.policy_phone
|
||||||
PRODUCT_PROPERTY_OVERRIDES := \
|
PRODUCT_PROPERTY_OVERRIDES := \
|
||||||
ro.config.notification_sound=F1_New_SMS.ogg
|
ro.config.notification_sound=OnTheHunt.ogg \
|
||||||
|
ro.config.alarm_alert=Alarm_Classic.ogg
|
||||||
PRODUCT_BRAND := generic
|
PRODUCT_BRAND := generic
|
||||||
PRODUCT_NAME := min_dev
|
PRODUCT_NAME := min_dev
|
||||||
PRODUCT_DEVICE := generic
|
PRODUCT_DEVICE := generic
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
PRODUCT_PROPERTY_OVERRIDES :=
|
PRODUCT_PROPERTY_OVERRIDES :=
|
||||||
|
|
||||||
PRODUCT_PACKAGES := \
|
PRODUCT_PACKAGES := \
|
||||||
|
AccountAndSyncSettings \
|
||||||
AlarmClock \
|
AlarmClock \
|
||||||
Camera \
|
Camera \
|
||||||
Calculator \
|
Calculator \
|
||||||
@@ -23,12 +24,15 @@ PRODUCT_PACKAGES := \
|
|||||||
libWnnEngDic \
|
libWnnEngDic \
|
||||||
libWnnJpnDic \
|
libWnnJpnDic \
|
||||||
libwnndict \
|
libwnndict \
|
||||||
|
CertInstaller \
|
||||||
|
LiveWallpapersPicker \
|
||||||
ApiDemos \
|
ApiDemos \
|
||||||
GestureBuilder \
|
GestureBuilder \
|
||||||
SoftKeyboard
|
SoftKeyboard
|
||||||
|
|
||||||
PRODUCT_COPY_FILES := \
|
PRODUCT_COPY_FILES := \
|
||||||
development/data/etc/vold.conf:system/etc/vold.conf
|
development/data/etc/vold.conf:system/etc/vold.conf \
|
||||||
|
frameworks/base/data/etc/android.hardware.camera.autofocus.xml:system/etc/permissions/android.hardware.camera.autofocus.xml
|
||||||
|
|
||||||
$(call inherit-product, $(SRC_TARGET_DIR)/product/core.mk)
|
$(call inherit-product, $(SRC_TARGET_DIR)/product/core.mk)
|
||||||
|
|
||||||
@@ -37,6 +41,9 @@ PRODUCT_BRAND := generic
|
|||||||
PRODUCT_NAME := sdk
|
PRODUCT_NAME := sdk
|
||||||
PRODUCT_DEVICE := generic
|
PRODUCT_DEVICE := generic
|
||||||
PRODUCT_LOCALES := \
|
PRODUCT_LOCALES := \
|
||||||
|
ldpi \
|
||||||
|
hdpi \
|
||||||
|
mdpi \
|
||||||
en_US \
|
en_US \
|
||||||
en_GB \
|
en_GB \
|
||||||
en_CA \
|
en_CA \
|
||||||
@@ -64,3 +71,10 @@ PRODUCT_LOCALES := \
|
|||||||
ru_RU \
|
ru_RU \
|
||||||
ko_KR
|
ko_KR
|
||||||
|
|
||||||
|
# include available languages for TTS in the system image
|
||||||
|
include external/svox/pico/lang/PicoLangDeDeInSystem.mk
|
||||||
|
include external/svox/pico/lang/PicoLangEnGBInSystem.mk
|
||||||
|
include external/svox/pico/lang/PicoLangEnUsInSystem.mk
|
||||||
|
include external/svox/pico/lang/PicoLangEsEsInSystem.mk
|
||||||
|
include external/svox/pico/lang/PicoLangFrFrInSystem.mk
|
||||||
|
include external/svox/pico/lang/PicoLangItItInSystem.mk
|
||||||
|
222
tools/adbs
Executable file
222
tools/adbs
Executable file
@@ -0,0 +1,222 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# Copyright (C) 2009 The Android Open Source Project
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the 'License');
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an 'AS IS' BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import string
|
||||||
|
import sys
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# match "#00 pc 0003f52e /system/lib/libdvm.so" for example
|
||||||
|
###############################################################################
|
||||||
|
trace_line = re.compile("(.*)(\#[0-9]+) (..) ([0-9a-f]{8}) ([^\r\n \t]*)")
|
||||||
|
|
||||||
|
# returns a list containing the function name and the file/lineno
|
||||||
|
def CallAddr2Line(lib, addr):
|
||||||
|
global symbols_dir
|
||||||
|
global addr2line_cmd
|
||||||
|
global cppfilt_cmd
|
||||||
|
|
||||||
|
if lib != "":
|
||||||
|
cmd = addr2line_cmd + \
|
||||||
|
" -f -e " + symbols_dir + lib + " 0x" + addr
|
||||||
|
stream = os.popen(cmd)
|
||||||
|
lines = stream.readlines()
|
||||||
|
list = map(string.strip, lines)
|
||||||
|
else:
|
||||||
|
list = []
|
||||||
|
if list != []:
|
||||||
|
# Name like "move_forward_type<JavaVMOption>" causes troubles
|
||||||
|
mangled_name = re.sub('<', '\<', list[0]);
|
||||||
|
mangled_name = re.sub('>', '\>', mangled_name);
|
||||||
|
cmd = cppfilt_cmd + " " + mangled_name
|
||||||
|
stream = os.popen(cmd)
|
||||||
|
list[0] = stream.readline()
|
||||||
|
stream.close()
|
||||||
|
list = map(string.strip, list)
|
||||||
|
else:
|
||||||
|
list = [ "(unknown)", "(unknown)" ]
|
||||||
|
return list
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# similar to CallAddr2Line, but using objdump to find out the name of the
|
||||||
|
# containing function of the specified address
|
||||||
|
###############################################################################
|
||||||
|
def CallObjdump(lib, addr):
|
||||||
|
global objdump_cmd
|
||||||
|
global symbols_dir
|
||||||
|
|
||||||
|
unknown = "(unknown)"
|
||||||
|
uname = os.uname()[0]
|
||||||
|
if uname == "Darwin":
|
||||||
|
proc = os.uname()[-1]
|
||||||
|
if proc == "i386":
|
||||||
|
uname = "darwin-x86"
|
||||||
|
else:
|
||||||
|
uname = "darwin-ppc"
|
||||||
|
elif uname == "Linux":
|
||||||
|
uname = "linux-x86"
|
||||||
|
if lib != "":
|
||||||
|
next_addr = string.atoi(addr, 16) + 1
|
||||||
|
cmd = objdump_cmd \
|
||||||
|
+ " -C -d --start-address=0x" + addr + " --stop-address=" \
|
||||||
|
+ str(next_addr) \
|
||||||
|
+ " " + symbols_dir + lib
|
||||||
|
stream = os.popen(cmd)
|
||||||
|
lines = stream.readlines()
|
||||||
|
map(string.strip, lines)
|
||||||
|
stream.close()
|
||||||
|
else:
|
||||||
|
return unknown
|
||||||
|
|
||||||
|
# output looks like
|
||||||
|
#
|
||||||
|
# file format elf32-littlearm
|
||||||
|
#
|
||||||
|
# Disassembly of section .text:
|
||||||
|
#
|
||||||
|
# 0000833c <func+0x4>:
|
||||||
|
# 833c: 701a strb r2, [r3, #0]
|
||||||
|
#
|
||||||
|
# we want to extract the "func" part
|
||||||
|
num_lines = len(lines)
|
||||||
|
if num_lines < 2:
|
||||||
|
return unknown
|
||||||
|
func_name = lines[num_lines-2]
|
||||||
|
func_regexp = re.compile("(^.*\<)(.*)(\+.*\>:$)")
|
||||||
|
components = func_regexp.match(func_name)
|
||||||
|
if components is None:
|
||||||
|
return unknown
|
||||||
|
return components.group(2)
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# determine the symbols directory in the local build
|
||||||
|
###############################################################################
|
||||||
|
def FindSymbolsDir():
|
||||||
|
global symbols_dir
|
||||||
|
|
||||||
|
try:
|
||||||
|
path = os.environ['ANDROID_PRODUCT_OUT'] + "/symbols"
|
||||||
|
except:
|
||||||
|
cmd = "CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core " \
|
||||||
|
+ "SRC_TARGET_DIR=build/target make -f build/core/envsetup.mk " \
|
||||||
|
+ "dumpvar-abs-TARGET_OUT_UNSTRIPPED"
|
||||||
|
stream = os.popen(cmd)
|
||||||
|
str = stream.read()
|
||||||
|
stream.close()
|
||||||
|
path = str.strip()
|
||||||
|
|
||||||
|
if (not os.path.exists(path)):
|
||||||
|
print path + " not found!"
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
symbols_dir = path
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# determine the path of binutils
|
||||||
|
###############################################################################
|
||||||
|
def SetupToolsPath():
|
||||||
|
global addr2line_cmd
|
||||||
|
global objdump_cmd
|
||||||
|
global cppfilt_cmd
|
||||||
|
global symbols_dir
|
||||||
|
|
||||||
|
uname = os.uname()[0]
|
||||||
|
if uname == "Darwin":
|
||||||
|
proc = os.uname()[-1]
|
||||||
|
if proc == "i386":
|
||||||
|
uname = "darwin-x86"
|
||||||
|
else:
|
||||||
|
uname = "darwin-ppc"
|
||||||
|
elif uname == "Linux":
|
||||||
|
uname = "linux-x86"
|
||||||
|
prefix = "./prebuilt/" + uname + "/toolchain/arm-eabi-4.4.0/bin/"
|
||||||
|
addr2line_cmd = prefix + "arm-eabi-addr2line"
|
||||||
|
|
||||||
|
if (not os.path.exists(addr2line_cmd)):
|
||||||
|
try:
|
||||||
|
prefix = os.environ['ANDROID_BUILD_TOP'] + "/prebuilt/" + uname + \
|
||||||
|
"/toolchain/arm-eabi-4.4.0/bin/"
|
||||||
|
except:
|
||||||
|
prefix = "";
|
||||||
|
|
||||||
|
addr2line_cmd = prefix + "arm-eabi-addr2line"
|
||||||
|
if (not os.path.exists(addr2line_cmd)):
|
||||||
|
print addr2line_cmd + " not found!"
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
objdump_cmd = prefix + "arm-eabi-objdump"
|
||||||
|
cppfilt_cmd = prefix + "arm-eabi-c++filt"
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# look up the function and file/line number for a raw stack trace line
|
||||||
|
# groups[0]: log tag
|
||||||
|
# groups[1]: stack level
|
||||||
|
# groups[2]: "pc"
|
||||||
|
# groups[3]: code address
|
||||||
|
# groups[4]: library name
|
||||||
|
###############################################################################
|
||||||
|
def SymbolTranslation(groups):
|
||||||
|
lib_name = groups[4]
|
||||||
|
code_addr = groups[3]
|
||||||
|
caller = CallObjdump(lib_name, code_addr)
|
||||||
|
func_line_pair = CallAddr2Line(lib_name, code_addr)
|
||||||
|
|
||||||
|
# If a callee is inlined to the caller, objdump will see the caller's
|
||||||
|
# address but addr2line will report the callee's address. So the printed
|
||||||
|
# format is desgined to be "caller<-callee file:line"
|
||||||
|
if (func_line_pair[0] != caller):
|
||||||
|
print groups[0] + groups[1] + " " + caller + "<-" + \
|
||||||
|
' '.join(func_line_pair[:]) + " "
|
||||||
|
else:
|
||||||
|
print groups[0] + groups[1] + " " + ' '.join(func_line_pair[:]) + " "
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# pass the options to adb
|
||||||
|
adb_cmd = "adb " + ' '.join(sys.argv[1:])
|
||||||
|
|
||||||
|
# setup addr2line_cmd and objdump_cmd
|
||||||
|
SetupToolsPath()
|
||||||
|
|
||||||
|
# setup the symbols directory
|
||||||
|
FindSymbolsDir()
|
||||||
|
|
||||||
|
# invoke the adb command and filter its output
|
||||||
|
stream = os.popen(adb_cmd)
|
||||||
|
while (True):
|
||||||
|
line = stream.readline()
|
||||||
|
|
||||||
|
# EOF reached
|
||||||
|
if (line == ''):
|
||||||
|
break
|
||||||
|
|
||||||
|
# remove the trailing \n
|
||||||
|
line = line.strip()
|
||||||
|
|
||||||
|
# see if this is a stack trace line
|
||||||
|
match = trace_line.match(line)
|
||||||
|
if (match):
|
||||||
|
groups = match.groups()
|
||||||
|
# translate raw address into symbols
|
||||||
|
SymbolTranslation(groups)
|
||||||
|
else:
|
||||||
|
print line
|
||||||
|
|
||||||
|
# adb itself aborts
|
||||||
|
stream.close()
|
@@ -140,6 +140,7 @@ public class ApiCheck {
|
|||||||
mApi = new ApiInfo();
|
mApi = new ApiInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void startElement(String uri, String localName, String qName,
|
public void startElement(String uri, String localName, String qName,
|
||||||
Attributes attributes) {
|
Attributes attributes) {
|
||||||
if (qName.equals("package")) {
|
if (qName.equals("package")) {
|
||||||
@@ -218,6 +219,8 @@ public class ApiCheck {
|
|||||||
mCurrentClass.addInterface(attributes.getValue("name"));
|
mCurrentClass.addInterface(attributes.getValue("name"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void endElement(String uri, String localName, String qName) {
|
public void endElement(String uri, String localName, String qName) {
|
||||||
if (qName.equals("method")) {
|
if (qName.equals("method")) {
|
||||||
mCurrentClass.addMethod((MethodInfo) mCurrentMethod);
|
mCurrentClass.addMethod((MethodInfo) mCurrentMethod);
|
||||||
|
@@ -41,6 +41,7 @@ public class Errors
|
|||||||
return this.msg.compareTo(that.msg);
|
return this.msg.compareTo(that.msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return this.pos.toString() + this.msg;
|
return this.pos.toString() + this.msg;
|
||||||
}
|
}
|
||||||
|
@@ -80,6 +80,7 @@ public class SourcePositionInfo implements Comparable
|
|||||||
return new SourcePositionInfo(that.file, line, 0);
|
return new SourcePositionInfo(that.file, line, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
if (this.file == null) {
|
if (this.file == null) {
|
||||||
|
@@ -17,7 +17,7 @@ ifneq ($(TARGET_SIMULATOR),true)
|
|||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
LOCAL_SRC_FILES := applypatch.c bsdiff.c freecache.c imgpatch.c utils.c
|
LOCAL_SRC_FILES := applypatch.c bspatch.c freecache.c imgpatch.c utils.c
|
||||||
LOCAL_MODULE := libapplypatch
|
LOCAL_MODULE := libapplypatch
|
||||||
LOCAL_MODULE_TAGS := eng
|
LOCAL_MODULE_TAGS := eng
|
||||||
LOCAL_C_INCLUDES += external/bzip2 external/zlib bootable/recovery
|
LOCAL_C_INCLUDES += external/bzip2 external/zlib bootable/recovery
|
||||||
@@ -47,12 +47,12 @@ include $(BUILD_EXECUTABLE)
|
|||||||
|
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
LOCAL_SRC_FILES := imgdiff.c utils.c
|
LOCAL_SRC_FILES := imgdiff.c utils.c bsdiff.c
|
||||||
LOCAL_MODULE := imgdiff
|
LOCAL_MODULE := imgdiff
|
||||||
LOCAL_FORCE_STATIC_EXECUTABLE := true
|
LOCAL_FORCE_STATIC_EXECUTABLE := true
|
||||||
LOCAL_MODULE_TAGS := eng
|
LOCAL_MODULE_TAGS := eng
|
||||||
LOCAL_C_INCLUDES += external/zlib
|
LOCAL_C_INCLUDES += external/zlib external/bzip2
|
||||||
LOCAL_STATIC_LIBRARIES += libz
|
LOCAL_STATIC_LIBRARIES += libz libbz
|
||||||
|
|
||||||
include $(BUILD_HOST_EXECUTABLE)
|
include $(BUILD_HOST_EXECUTABLE)
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2008 The Android Open Source Project
|
* Copyright (C) 2009 The Android Open Source Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -14,239 +14,397 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// This file is a nearly line-for-line copy of bspatch.c from the
|
/*
|
||||||
// bsdiff-4.3 distribution; the primary differences being how the
|
* Most of this code comes from bsdiff.c from the bsdiff-4.3
|
||||||
// input and output data are read and the error handling. Running
|
* distribution, which is:
|
||||||
// applypatch with the -l option will display the bsdiff license
|
*/
|
||||||
// notice.
|
|
||||||
|
|
||||||
#include <stdio.h>
|
/*-
|
||||||
#include <sys/stat.h>
|
* Copyright 2003-2005 Colin Percival
|
||||||
#include <errno.h>
|
* All rights reserved
|
||||||
#include <unistd.h>
|
*
|
||||||
#include <string.h>
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted providing that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <bzlib.h>
|
#include <bzlib.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "mincrypt/sha.h"
|
#define MIN(x,y) (((x)<(y)) ? (x) : (y))
|
||||||
#include "applypatch.h"
|
|
||||||
|
|
||||||
void ShowBSDiffLicense() {
|
static void split(off_t *I,off_t *V,off_t start,off_t len,off_t h)
|
||||||
puts("The bsdiff library used herein is:\n"
|
{
|
||||||
"\n"
|
off_t i,j,k,x,tmp,jj,kk;
|
||||||
"Copyright 2003-2005 Colin Percival\n"
|
|
||||||
"All rights reserved\n"
|
if(len<16) {
|
||||||
"\n"
|
for(k=start;k<start+len;k+=j) {
|
||||||
"Redistribution and use in source and binary forms, with or without\n"
|
j=1;x=V[I[k]+h];
|
||||||
"modification, are permitted providing that the following conditions\n"
|
for(i=1;k+i<start+len;i++) {
|
||||||
"are met:\n"
|
if(V[I[k+i]+h]<x) {
|
||||||
"1. Redistributions of source code must retain the above copyright\n"
|
x=V[I[k+i]+h];
|
||||||
" notice, this list of conditions and the following disclaimer.\n"
|
j=0;
|
||||||
"2. Redistributions in binary form must reproduce the above copyright\n"
|
};
|
||||||
" notice, this list of conditions and the following disclaimer in the\n"
|
if(V[I[k+i]+h]==x) {
|
||||||
" documentation and/or other materials provided with the distribution.\n"
|
tmp=I[k+j];I[k+j]=I[k+i];I[k+i]=tmp;
|
||||||
"\n"
|
j++;
|
||||||
"THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n"
|
};
|
||||||
"IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n"
|
};
|
||||||
"WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n"
|
for(i=0;i<j;i++) V[I[k+i]]=k+j-1;
|
||||||
"ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\n"
|
if(j==1) I[k]=-1;
|
||||||
"DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n"
|
};
|
||||||
"DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n"
|
return;
|
||||||
"OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n"
|
};
|
||||||
"HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n"
|
|
||||||
"STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\n"
|
x=V[I[start+len/2]+h];
|
||||||
"IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n"
|
jj=0;kk=0;
|
||||||
"POSSIBILITY OF SUCH DAMAGE.\n"
|
for(i=start;i<start+len;i++) {
|
||||||
"\n------------------\n\n"
|
if(V[I[i]+h]<x) jj++;
|
||||||
"This program uses Julian R Seward's \"libbzip2\" library, available\n"
|
if(V[I[i]+h]==x) kk++;
|
||||||
"from http://www.bzip.org/.\n"
|
};
|
||||||
);
|
jj+=start;kk+=jj;
|
||||||
|
|
||||||
|
i=start;j=0;k=0;
|
||||||
|
while(i<jj) {
|
||||||
|
if(V[I[i]+h]<x) {
|
||||||
|
i++;
|
||||||
|
} else if(V[I[i]+h]==x) {
|
||||||
|
tmp=I[i];I[i]=I[jj+j];I[jj+j]=tmp;
|
||||||
|
j++;
|
||||||
|
} else {
|
||||||
|
tmp=I[i];I[i]=I[kk+k];I[kk+k]=tmp;
|
||||||
|
k++;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
while(jj+j<kk) {
|
||||||
|
if(V[I[jj+j]+h]==x) {
|
||||||
|
j++;
|
||||||
|
} else {
|
||||||
|
tmp=I[jj+j];I[jj+j]=I[kk+k];I[kk+k]=tmp;
|
||||||
|
k++;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if(jj>start) split(I,V,start,jj-start,h);
|
||||||
|
|
||||||
|
for(i=0;i<kk-jj;i++) V[I[jj+i]]=kk-1;
|
||||||
|
if(jj==kk-1) I[jj]=-1;
|
||||||
|
|
||||||
|
if(start+len>kk) split(I,V,kk,start+len-kk,h);
|
||||||
}
|
}
|
||||||
|
|
||||||
static off_t offtin(u_char *buf)
|
static void qsufsort(off_t *I,off_t *V,u_char *old,off_t oldsize)
|
||||||
|
{
|
||||||
|
off_t buckets[256];
|
||||||
|
off_t i,h,len;
|
||||||
|
|
||||||
|
for(i=0;i<256;i++) buckets[i]=0;
|
||||||
|
for(i=0;i<oldsize;i++) buckets[old[i]]++;
|
||||||
|
for(i=1;i<256;i++) buckets[i]+=buckets[i-1];
|
||||||
|
for(i=255;i>0;i--) buckets[i]=buckets[i-1];
|
||||||
|
buckets[0]=0;
|
||||||
|
|
||||||
|
for(i=0;i<oldsize;i++) I[++buckets[old[i]]]=i;
|
||||||
|
I[0]=oldsize;
|
||||||
|
for(i=0;i<oldsize;i++) V[i]=buckets[old[i]];
|
||||||
|
V[oldsize]=0;
|
||||||
|
for(i=1;i<256;i++) if(buckets[i]==buckets[i-1]+1) I[buckets[i]]=-1;
|
||||||
|
I[0]=-1;
|
||||||
|
|
||||||
|
for(h=1;I[0]!=-(oldsize+1);h+=h) {
|
||||||
|
len=0;
|
||||||
|
for(i=0;i<oldsize+1;) {
|
||||||
|
if(I[i]<0) {
|
||||||
|
len-=I[i];
|
||||||
|
i-=I[i];
|
||||||
|
} else {
|
||||||
|
if(len) I[i-len]=-len;
|
||||||
|
len=V[I[i]]+1-i;
|
||||||
|
split(I,V,i,len,h);
|
||||||
|
i+=len;
|
||||||
|
len=0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if(len) I[i-len]=-len;
|
||||||
|
};
|
||||||
|
|
||||||
|
for(i=0;i<oldsize+1;i++) I[V[i]]=i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static off_t matchlen(u_char *old,off_t oldsize,u_char *new,off_t newsize)
|
||||||
|
{
|
||||||
|
off_t i;
|
||||||
|
|
||||||
|
for(i=0;(i<oldsize)&&(i<newsize);i++)
|
||||||
|
if(old[i]!=new[i]) break;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static off_t search(off_t *I,u_char *old,off_t oldsize,
|
||||||
|
u_char *new,off_t newsize,off_t st,off_t en,off_t *pos)
|
||||||
|
{
|
||||||
|
off_t x,y;
|
||||||
|
|
||||||
|
if(en-st<2) {
|
||||||
|
x=matchlen(old+I[st],oldsize-I[st],new,newsize);
|
||||||
|
y=matchlen(old+I[en],oldsize-I[en],new,newsize);
|
||||||
|
|
||||||
|
if(x>y) {
|
||||||
|
*pos=I[st];
|
||||||
|
return x;
|
||||||
|
} else {
|
||||||
|
*pos=I[en];
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
x=st+(en-st)/2;
|
||||||
|
if(memcmp(old+I[x],new,MIN(oldsize-I[x],newsize))<0) {
|
||||||
|
return search(I,old,oldsize,new,newsize,x,en,pos);
|
||||||
|
} else {
|
||||||
|
return search(I,old,oldsize,new,newsize,st,x,pos);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static void offtout(off_t x,u_char *buf)
|
||||||
{
|
{
|
||||||
off_t y;
|
off_t y;
|
||||||
|
|
||||||
y=buf[7]&0x7F;
|
if(x<0) y=-x; else y=x;
|
||||||
y=y*256;y+=buf[6];
|
|
||||||
y=y*256;y+=buf[5];
|
|
||||||
y=y*256;y+=buf[4];
|
|
||||||
y=y*256;y+=buf[3];
|
|
||||||
y=y*256;y+=buf[2];
|
|
||||||
y=y*256;y+=buf[1];
|
|
||||||
y=y*256;y+=buf[0];
|
|
||||||
|
|
||||||
if(buf[7]&0x80) y=-y;
|
buf[0]=y%256;y-=buf[0];
|
||||||
|
y=y/256;buf[1]=y%256;y-=buf[1];
|
||||||
|
y=y/256;buf[2]=y%256;y-=buf[2];
|
||||||
|
y=y/256;buf[3]=y%256;y-=buf[3];
|
||||||
|
y=y/256;buf[4]=y%256;y-=buf[4];
|
||||||
|
y=y/256;buf[5]=y%256;y-=buf[5];
|
||||||
|
y=y/256;buf[6]=y%256;y-=buf[6];
|
||||||
|
y=y/256;buf[7]=y%256;
|
||||||
|
|
||||||
return y;
|
if(x<0) buf[7]|=0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is main() from bsdiff.c, with the following changes:
|
||||||
|
//
|
||||||
|
// - old, oldsize, new, newsize are arguments; we don't load this
|
||||||
|
// data from files. old and new are owned by the caller; we
|
||||||
|
// don't free them at the end.
|
||||||
|
//
|
||||||
|
// - the "I" block of memory is owned by the caller, who passes a
|
||||||
|
// pointer to *I, which can be NULL. This way if we call
|
||||||
|
// bsdiff() multiple times with the same 'old' data, we only do
|
||||||
|
// the qsufsort() step the first time.
|
||||||
|
//
|
||||||
|
int bsdiff(u_char* old, off_t oldsize, off_t** IP, u_char* new, off_t newsize,
|
||||||
|
const char* patch_filename)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
off_t *I;
|
||||||
|
off_t scan,pos,len;
|
||||||
|
off_t lastscan,lastpos,lastoffset;
|
||||||
|
off_t oldscore,scsc;
|
||||||
|
off_t s,Sf,lenf,Sb,lenb;
|
||||||
|
off_t overlap,Ss,lens;
|
||||||
|
off_t i;
|
||||||
|
off_t dblen,eblen;
|
||||||
|
u_char *db,*eb;
|
||||||
|
u_char buf[8];
|
||||||
|
u_char header[32];
|
||||||
|
FILE * pf;
|
||||||
|
BZFILE * pfbz2;
|
||||||
|
int bz2err;
|
||||||
|
|
||||||
int ApplyBSDiffPatch(const unsigned char* old_data, ssize_t old_size,
|
if (*IP == NULL) {
|
||||||
const char* patch_filename, ssize_t patch_offset,
|
off_t* V;
|
||||||
SinkFn sink, void* token, SHA_CTX* ctx) {
|
*IP = malloc((oldsize+1) * sizeof(off_t));
|
||||||
|
V = malloc((oldsize+1) * sizeof(off_t));
|
||||||
|
qsufsort(*IP, V, old, oldsize);
|
||||||
|
free(V);
|
||||||
|
}
|
||||||
|
I = *IP;
|
||||||
|
|
||||||
unsigned char* new_data;
|
if(((db=malloc(newsize+1))==NULL) ||
|
||||||
ssize_t new_size;
|
((eb=malloc(newsize+1))==NULL)) err(1,NULL);
|
||||||
if (ApplyBSDiffPatchMem(old_data, old_size, patch_filename, patch_offset,
|
dblen=0;
|
||||||
&new_data, &new_size) != 0) {
|
eblen=0;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sink(new_data, new_size, token) < new_size) {
|
/* Create the patch file */
|
||||||
fprintf(stderr, "short write of output: %d (%s)\n", errno, strerror(errno));
|
if ((pf = fopen(patch_filename, "w")) == NULL)
|
||||||
return 1;
|
err(1, "%s", patch_filename);
|
||||||
}
|
|
||||||
if (ctx) {
|
/* Header is
|
||||||
SHA_update(ctx, new_data, new_size);
|
0 8 "BSDIFF40"
|
||||||
}
|
8 8 length of bzip2ed ctrl block
|
||||||
free(new_data);
|
16 8 length of bzip2ed diff block
|
||||||
|
24 8 length of new file */
|
||||||
return 0;
|
/* File is
|
||||||
}
|
0 32 Header
|
||||||
|
32 ?? Bzip2ed ctrl block
|
||||||
int ApplyBSDiffPatchMem(const unsigned char* old_data, ssize_t old_size,
|
?? ?? Bzip2ed diff block
|
||||||
const char* patch_filename, ssize_t patch_offset,
|
?? ?? Bzip2ed extra block */
|
||||||
unsigned char** new_data, ssize_t* new_size) {
|
memcpy(header,"BSDIFF40",8);
|
||||||
|
offtout(0, header + 8);
|
||||||
FILE* f;
|
offtout(0, header + 16);
|
||||||
if ((f = fopen(patch_filename, "rb")) == NULL) {
|
offtout(newsize, header + 24);
|
||||||
fprintf(stderr, "failed to open patch file\n");
|
if (fwrite(header, 32, 1, pf) != 1)
|
||||||
return 1;
|
err(1, "fwrite(%s)", patch_filename);
|
||||||
}
|
|
||||||
|
/* Compute the differences, writing ctrl as we go */
|
||||||
// File format:
|
if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
|
||||||
// 0 8 "BSDIFF40"
|
errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
|
||||||
// 8 8 X
|
scan=0;len=0;
|
||||||
// 16 8 Y
|
lastscan=0;lastpos=0;lastoffset=0;
|
||||||
// 24 8 sizeof(newfile)
|
while(scan<newsize) {
|
||||||
// 32 X bzip2(control block)
|
oldscore=0;
|
||||||
// 32+X Y bzip2(diff block)
|
|
||||||
// 32+X+Y ??? bzip2(extra block)
|
for(scsc=scan+=len;scan<newsize;scan++) {
|
||||||
// with control block a set of triples (x,y,z) meaning "add x bytes
|
len=search(I,old,oldsize,new+scan,newsize-scan,
|
||||||
// from oldfile to x bytes from the diff block; copy y bytes from the
|
0,oldsize,&pos);
|
||||||
// extra block; seek forwards in oldfile by z bytes".
|
|
||||||
|
for(;scsc<scan+len;scsc++)
|
||||||
fseek(f, patch_offset, SEEK_SET);
|
if((scsc+lastoffset<oldsize) &&
|
||||||
|
(old[scsc+lastoffset] == new[scsc]))
|
||||||
unsigned char header[32];
|
oldscore++;
|
||||||
if (fread(header, 1, 32, f) < 32) {
|
|
||||||
fprintf(stderr, "failed to read patch file header\n");
|
if(((len==oldscore) && (len!=0)) ||
|
||||||
return 1;
|
(len>oldscore+8)) break;
|
||||||
}
|
|
||||||
|
if((scan+lastoffset<oldsize) &&
|
||||||
if (memcmp(header, "BSDIFF40", 8) != 0) {
|
(old[scan+lastoffset] == new[scan]))
|
||||||
fprintf(stderr, "corrupt bsdiff patch file header (magic number)\n");
|
oldscore--;
|
||||||
return 1;
|
};
|
||||||
}
|
|
||||||
|
if((len!=oldscore) || (scan==newsize)) {
|
||||||
ssize_t ctrl_len, data_len;
|
s=0;Sf=0;lenf=0;
|
||||||
ctrl_len = offtin(header+8);
|
for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) {
|
||||||
data_len = offtin(header+16);
|
if(old[lastpos+i]==new[lastscan+i]) s++;
|
||||||
*new_size = offtin(header+24);
|
i++;
|
||||||
|
if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; };
|
||||||
if (ctrl_len < 0 || data_len < 0 || *new_size < 0) {
|
};
|
||||||
fprintf(stderr, "corrupt patch file header (data lengths)\n");
|
|
||||||
return 1;
|
lenb=0;
|
||||||
}
|
if(scan<newsize) {
|
||||||
|
s=0;Sb=0;
|
||||||
fclose(f);
|
for(i=1;(scan>=lastscan+i)&&(pos>=i);i++) {
|
||||||
|
if(old[pos-i]==new[scan-i]) s++;
|
||||||
int bzerr;
|
if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; };
|
||||||
|
};
|
||||||
#define OPEN_AT(f, bzf, offset) \
|
};
|
||||||
FILE* f; \
|
|
||||||
BZFILE* bzf; \
|
if(lastscan+lenf>scan-lenb) {
|
||||||
if ((f = fopen(patch_filename, "rb")) == NULL) { \
|
overlap=(lastscan+lenf)-(scan-lenb);
|
||||||
fprintf(stderr, "failed to open patch file\n"); \
|
s=0;Ss=0;lens=0;
|
||||||
return 1; \
|
for(i=0;i<overlap;i++) {
|
||||||
} \
|
if(new[lastscan+lenf-overlap+i]==
|
||||||
if (fseeko(f, offset+patch_offset, SEEK_SET)) { \
|
old[lastpos+lenf-overlap+i]) s++;
|
||||||
fprintf(stderr, "failed to seek in patch file\n"); \
|
if(new[scan-lenb+i]==
|
||||||
return 1; \
|
old[pos-lenb+i]) s--;
|
||||||
} \
|
if(s>Ss) { Ss=s; lens=i+1; };
|
||||||
if ((bzf = BZ2_bzReadOpen(&bzerr, f, 0, 0, NULL, 0)) == NULL) { \
|
};
|
||||||
fprintf(stderr, "failed to bzReadOpen in patch file (%d)\n", bzerr); \
|
|
||||||
return 1; \
|
lenf+=lens-overlap;
|
||||||
}
|
lenb-=lens;
|
||||||
|
};
|
||||||
OPEN_AT(cpf, cpfbz2, 32);
|
|
||||||
OPEN_AT(dpf, dpfbz2, 32+ctrl_len);
|
for(i=0;i<lenf;i++)
|
||||||
OPEN_AT(epf, epfbz2, 32+ctrl_len+data_len);
|
db[dblen+i]=new[lastscan+i]-old[lastpos+i];
|
||||||
|
for(i=0;i<(scan-lenb)-(lastscan+lenf);i++)
|
||||||
#undef OPEN_AT
|
eb[eblen+i]=new[lastscan+lenf+i];
|
||||||
|
|
||||||
*new_data = malloc(*new_size);
|
dblen+=lenf;
|
||||||
if (*new_data == NULL) {
|
eblen+=(scan-lenb)-(lastscan+lenf);
|
||||||
fprintf(stderr, "failed to allocate %d bytes of memory for output file\n",
|
|
||||||
(int)*new_size);
|
offtout(lenf,buf);
|
||||||
return 1;
|
BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
|
||||||
}
|
if (bz2err != BZ_OK)
|
||||||
|
errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
|
||||||
off_t oldpos = 0, newpos = 0;
|
|
||||||
off_t ctrl[3];
|
offtout((scan-lenb)-(lastscan+lenf),buf);
|
||||||
off_t len_read;
|
BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
|
||||||
int i;
|
if (bz2err != BZ_OK)
|
||||||
unsigned char buf[8];
|
errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
|
||||||
while (newpos < *new_size) {
|
|
||||||
// Read control data
|
offtout((pos-lenb)-(lastpos+lenf),buf);
|
||||||
for (i = 0; i < 3; ++i) {
|
BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
|
||||||
len_read = BZ2_bzRead(&bzerr, cpfbz2, buf, 8);
|
if (bz2err != BZ_OK)
|
||||||
if (len_read < 8 || !(bzerr == BZ_OK || bzerr == BZ_STREAM_END)) {
|
errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
|
||||||
fprintf(stderr, "corrupt patch (read control)\n");
|
|
||||||
return 1;
|
lastscan=scan-lenb;
|
||||||
}
|
lastpos=pos-lenb;
|
||||||
ctrl[i] = offtin(buf);
|
lastoffset=pos-scan;
|
||||||
}
|
};
|
||||||
|
};
|
||||||
// Sanity check
|
BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
|
||||||
if (newpos + ctrl[0] > *new_size) {
|
if (bz2err != BZ_OK)
|
||||||
fprintf(stderr, "corrupt patch (new file overrun)\n");
|
errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
|
||||||
return 1;
|
|
||||||
}
|
/* Compute size of compressed ctrl data */
|
||||||
|
if ((len = ftello(pf)) == -1)
|
||||||
// Read diff string
|
err(1, "ftello");
|
||||||
len_read = BZ2_bzRead(&bzerr, dpfbz2, *new_data + newpos, ctrl[0]);
|
offtout(len-32, header + 8);
|
||||||
if (len_read < ctrl[0] || !(bzerr == BZ_OK || bzerr == BZ_STREAM_END)) {
|
|
||||||
fprintf(stderr, "corrupt patch (read diff)\n");
|
/* Write compressed diff data */
|
||||||
return 1;
|
if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
|
||||||
}
|
errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
|
||||||
|
BZ2_bzWrite(&bz2err, pfbz2, db, dblen);
|
||||||
// Add old data to diff string
|
if (bz2err != BZ_OK)
|
||||||
for (i = 0; i < ctrl[0]; ++i) {
|
errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
|
||||||
if ((oldpos+i >= 0) && (oldpos+i < old_size)) {
|
BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
|
||||||
(*new_data)[newpos+i] += old_data[oldpos+i];
|
if (bz2err != BZ_OK)
|
||||||
}
|
errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
|
||||||
}
|
|
||||||
|
/* Compute size of compressed diff data */
|
||||||
// Adjust pointers
|
if ((newsize = ftello(pf)) == -1)
|
||||||
newpos += ctrl[0];
|
err(1, "ftello");
|
||||||
oldpos += ctrl[0];
|
offtout(newsize - len, header + 16);
|
||||||
|
|
||||||
// Sanity check
|
/* Write compressed extra data */
|
||||||
if (newpos + ctrl[1] > *new_size) {
|
if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
|
||||||
fprintf(stderr, "corrupt patch (new file overrun)\n");
|
errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
|
||||||
return 1;
|
BZ2_bzWrite(&bz2err, pfbz2, eb, eblen);
|
||||||
}
|
if (bz2err != BZ_OK)
|
||||||
|
errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
|
||||||
// Read extra string
|
BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
|
||||||
len_read = BZ2_bzRead(&bzerr, epfbz2, *new_data + newpos, ctrl[1]);
|
if (bz2err != BZ_OK)
|
||||||
if (len_read < ctrl[1] || !(bzerr == BZ_OK || bzerr == BZ_STREAM_END)) {
|
errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
|
||||||
fprintf(stderr, "corrupt patch (read extra)\n");
|
|
||||||
return 1;
|
/* Seek to the beginning, write the header, and close the file */
|
||||||
}
|
if (fseeko(pf, 0, SEEK_SET))
|
||||||
|
err(1, "fseeko");
|
||||||
// Adjust pointers
|
if (fwrite(header, 32, 1, pf) != 1)
|
||||||
newpos += ctrl[1];
|
err(1, "fwrite(%s)", patch_filename);
|
||||||
oldpos += ctrl[2];
|
if (fclose(pf))
|
||||||
}
|
err(1, "fclose");
|
||||||
|
|
||||||
BZ2_bzReadClose(&bzerr, cpfbz2);
|
/* Free the memory we used */
|
||||||
BZ2_bzReadClose(&bzerr, dpfbz2);
|
free(db);
|
||||||
BZ2_bzReadClose(&bzerr, epfbz2);
|
free(eb);
|
||||||
fclose(cpf);
|
|
||||||
fclose(dpf);
|
|
||||||
fclose(epf);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
252
tools/applypatch/bspatch.c
Normal file
252
tools/applypatch/bspatch.c
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2008 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This file is a nearly line-for-line copy of bspatch.c from the
|
||||||
|
// bsdiff-4.3 distribution; the primary differences being how the
|
||||||
|
// input and output data are read and the error handling. Running
|
||||||
|
// applypatch with the -l option will display the bsdiff license
|
||||||
|
// notice.
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <bzlib.h>
|
||||||
|
|
||||||
|
#include "mincrypt/sha.h"
|
||||||
|
#include "applypatch.h"
|
||||||
|
|
||||||
|
void ShowBSDiffLicense() {
|
||||||
|
puts("The bsdiff library used herein is:\n"
|
||||||
|
"\n"
|
||||||
|
"Copyright 2003-2005 Colin Percival\n"
|
||||||
|
"All rights reserved\n"
|
||||||
|
"\n"
|
||||||
|
"Redistribution and use in source and binary forms, with or without\n"
|
||||||
|
"modification, are permitted providing that the following conditions\n"
|
||||||
|
"are met:\n"
|
||||||
|
"1. Redistributions of source code must retain the above copyright\n"
|
||||||
|
" notice, this list of conditions and the following disclaimer.\n"
|
||||||
|
"2. Redistributions in binary form must reproduce the above copyright\n"
|
||||||
|
" notice, this list of conditions and the following disclaimer in the\n"
|
||||||
|
" documentation and/or other materials provided with the distribution.\n"
|
||||||
|
"\n"
|
||||||
|
"THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n"
|
||||||
|
"IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n"
|
||||||
|
"WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n"
|
||||||
|
"ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\n"
|
||||||
|
"DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n"
|
||||||
|
"DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n"
|
||||||
|
"OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n"
|
||||||
|
"HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n"
|
||||||
|
"STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\n"
|
||||||
|
"IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n"
|
||||||
|
"POSSIBILITY OF SUCH DAMAGE.\n"
|
||||||
|
"\n------------------\n\n"
|
||||||
|
"This program uses Julian R Seward's \"libbzip2\" library, available\n"
|
||||||
|
"from http://www.bzip.org/.\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static off_t offtin(u_char *buf)
|
||||||
|
{
|
||||||
|
off_t y;
|
||||||
|
|
||||||
|
y=buf[7]&0x7F;
|
||||||
|
y=y*256;y+=buf[6];
|
||||||
|
y=y*256;y+=buf[5];
|
||||||
|
y=y*256;y+=buf[4];
|
||||||
|
y=y*256;y+=buf[3];
|
||||||
|
y=y*256;y+=buf[2];
|
||||||
|
y=y*256;y+=buf[1];
|
||||||
|
y=y*256;y+=buf[0];
|
||||||
|
|
||||||
|
if(buf[7]&0x80) y=-y;
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ApplyBSDiffPatch(const unsigned char* old_data, ssize_t old_size,
|
||||||
|
const char* patch_filename, ssize_t patch_offset,
|
||||||
|
SinkFn sink, void* token, SHA_CTX* ctx) {
|
||||||
|
|
||||||
|
unsigned char* new_data;
|
||||||
|
ssize_t new_size;
|
||||||
|
if (ApplyBSDiffPatchMem(old_data, old_size, patch_filename, patch_offset,
|
||||||
|
&new_data, &new_size) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sink(new_data, new_size, token) < new_size) {
|
||||||
|
fprintf(stderr, "short write of output: %d (%s)\n", errno, strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (ctx) {
|
||||||
|
SHA_update(ctx, new_data, new_size);
|
||||||
|
}
|
||||||
|
free(new_data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ApplyBSDiffPatchMem(const unsigned char* old_data, ssize_t old_size,
|
||||||
|
const char* patch_filename, ssize_t patch_offset,
|
||||||
|
unsigned char** new_data, ssize_t* new_size) {
|
||||||
|
|
||||||
|
FILE* f;
|
||||||
|
if ((f = fopen(patch_filename, "rb")) == NULL) {
|
||||||
|
fprintf(stderr, "failed to open patch file\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// File format:
|
||||||
|
// 0 8 "BSDIFF40"
|
||||||
|
// 8 8 X
|
||||||
|
// 16 8 Y
|
||||||
|
// 24 8 sizeof(newfile)
|
||||||
|
// 32 X bzip2(control block)
|
||||||
|
// 32+X Y bzip2(diff block)
|
||||||
|
// 32+X+Y ??? bzip2(extra block)
|
||||||
|
// with control block a set of triples (x,y,z) meaning "add x bytes
|
||||||
|
// from oldfile to x bytes from the diff block; copy y bytes from the
|
||||||
|
// extra block; seek forwards in oldfile by z bytes".
|
||||||
|
|
||||||
|
fseek(f, patch_offset, SEEK_SET);
|
||||||
|
|
||||||
|
unsigned char header[32];
|
||||||
|
if (fread(header, 1, 32, f) < 32) {
|
||||||
|
fprintf(stderr, "failed to read patch file header\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(header, "BSDIFF40", 8) != 0) {
|
||||||
|
fprintf(stderr, "corrupt bsdiff patch file header (magic number)\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t ctrl_len, data_len;
|
||||||
|
ctrl_len = offtin(header+8);
|
||||||
|
data_len = offtin(header+16);
|
||||||
|
*new_size = offtin(header+24);
|
||||||
|
|
||||||
|
if (ctrl_len < 0 || data_len < 0 || *new_size < 0) {
|
||||||
|
fprintf(stderr, "corrupt patch file header (data lengths)\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
int bzerr;
|
||||||
|
|
||||||
|
#define OPEN_AT(f, bzf, offset) \
|
||||||
|
FILE* f; \
|
||||||
|
BZFILE* bzf; \
|
||||||
|
if ((f = fopen(patch_filename, "rb")) == NULL) { \
|
||||||
|
fprintf(stderr, "failed to open patch file\n"); \
|
||||||
|
return 1; \
|
||||||
|
} \
|
||||||
|
if (fseeko(f, offset+patch_offset, SEEK_SET)) { \
|
||||||
|
fprintf(stderr, "failed to seek in patch file\n"); \
|
||||||
|
return 1; \
|
||||||
|
} \
|
||||||
|
if ((bzf = BZ2_bzReadOpen(&bzerr, f, 0, 0, NULL, 0)) == NULL) { \
|
||||||
|
fprintf(stderr, "failed to bzReadOpen in patch file (%d)\n", bzerr); \
|
||||||
|
return 1; \
|
||||||
|
}
|
||||||
|
|
||||||
|
OPEN_AT(cpf, cpfbz2, 32);
|
||||||
|
OPEN_AT(dpf, dpfbz2, 32+ctrl_len);
|
||||||
|
OPEN_AT(epf, epfbz2, 32+ctrl_len+data_len);
|
||||||
|
|
||||||
|
#undef OPEN_AT
|
||||||
|
|
||||||
|
*new_data = malloc(*new_size);
|
||||||
|
if (*new_data == NULL) {
|
||||||
|
fprintf(stderr, "failed to allocate %d bytes of memory for output file\n",
|
||||||
|
(int)*new_size);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t oldpos = 0, newpos = 0;
|
||||||
|
off_t ctrl[3];
|
||||||
|
off_t len_read;
|
||||||
|
int i;
|
||||||
|
unsigned char buf[8];
|
||||||
|
while (newpos < *new_size) {
|
||||||
|
// Read control data
|
||||||
|
for (i = 0; i < 3; ++i) {
|
||||||
|
len_read = BZ2_bzRead(&bzerr, cpfbz2, buf, 8);
|
||||||
|
if (len_read < 8 || !(bzerr == BZ_OK || bzerr == BZ_STREAM_END)) {
|
||||||
|
fprintf(stderr, "corrupt patch (read control)\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ctrl[i] = offtin(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity check
|
||||||
|
if (newpos + ctrl[0] > *new_size) {
|
||||||
|
fprintf(stderr, "corrupt patch (new file overrun)\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read diff string
|
||||||
|
len_read = BZ2_bzRead(&bzerr, dpfbz2, *new_data + newpos, ctrl[0]);
|
||||||
|
if (len_read < ctrl[0] || !(bzerr == BZ_OK || bzerr == BZ_STREAM_END)) {
|
||||||
|
fprintf(stderr, "corrupt patch (read diff)\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add old data to diff string
|
||||||
|
for (i = 0; i < ctrl[0]; ++i) {
|
||||||
|
if ((oldpos+i >= 0) && (oldpos+i < old_size)) {
|
||||||
|
(*new_data)[newpos+i] += old_data[oldpos+i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust pointers
|
||||||
|
newpos += ctrl[0];
|
||||||
|
oldpos += ctrl[0];
|
||||||
|
|
||||||
|
// Sanity check
|
||||||
|
if (newpos + ctrl[1] > *new_size) {
|
||||||
|
fprintf(stderr, "corrupt patch (new file overrun)\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read extra string
|
||||||
|
len_read = BZ2_bzRead(&bzerr, epfbz2, *new_data + newpos, ctrl[1]);
|
||||||
|
if (len_read < ctrl[1] || !(bzerr == BZ_OK || bzerr == BZ_STREAM_END)) {
|
||||||
|
fprintf(stderr, "corrupt patch (read extra)\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust pointers
|
||||||
|
newpos += ctrl[1];
|
||||||
|
oldpos += ctrl[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
BZ2_bzReadClose(&bzerr, cpfbz2);
|
||||||
|
BZ2_bzReadClose(&bzerr, dpfbz2);
|
||||||
|
BZ2_bzReadClose(&bzerr, epfbz2);
|
||||||
|
fclose(cpf);
|
||||||
|
fclose(dpf);
|
||||||
|
fclose(epf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -119,6 +119,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
#include "imgdiff.h"
|
#include "imgdiff.h"
|
||||||
@@ -134,6 +135,8 @@ typedef struct {
|
|||||||
size_t source_start;
|
size_t source_start;
|
||||||
size_t source_len;
|
size_t source_len;
|
||||||
|
|
||||||
|
off_t* I; // used by bsdiff
|
||||||
|
|
||||||
// --- for CHUNK_DEFLATE chunks only: ---
|
// --- for CHUNK_DEFLATE chunks only: ---
|
||||||
|
|
||||||
// original (compressed) deflate data
|
// original (compressed) deflate data
|
||||||
@@ -167,6 +170,10 @@ static int fileentry_compare(const void* a, const void* b) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// from bsdiff.c
|
||||||
|
int bsdiff(u_char* old, off_t oldsize, off_t** IP, u_char* new, off_t newsize,
|
||||||
|
const char* patch_filename);
|
||||||
|
|
||||||
unsigned char* ReadZip(const char* filename,
|
unsigned char* ReadZip(const char* filename,
|
||||||
int* num_chunks, ImageChunk** chunks,
|
int* num_chunks, ImageChunk** chunks,
|
||||||
int include_pseudo_chunk) {
|
int include_pseudo_chunk) {
|
||||||
@@ -278,6 +285,7 @@ unsigned char* ReadZip(const char* filename,
|
|||||||
curr->len = st.st_size;
|
curr->len = st.st_size;
|
||||||
curr->data = img;
|
curr->data = img;
|
||||||
curr->filename = NULL;
|
curr->filename = NULL;
|
||||||
|
curr->I = NULL;
|
||||||
++curr;
|
++curr;
|
||||||
++*num_chunks;
|
++*num_chunks;
|
||||||
}
|
}
|
||||||
@@ -292,6 +300,7 @@ unsigned char* ReadZip(const char* filename,
|
|||||||
curr->deflate_len = temp_entries[nextentry].deflate_len;
|
curr->deflate_len = temp_entries[nextentry].deflate_len;
|
||||||
curr->deflate_data = img + pos;
|
curr->deflate_data = img + pos;
|
||||||
curr->filename = temp_entries[nextentry].filename;
|
curr->filename = temp_entries[nextentry].filename;
|
||||||
|
curr->I = NULL;
|
||||||
|
|
||||||
curr->len = temp_entries[nextentry].uncomp_len;
|
curr->len = temp_entries[nextentry].uncomp_len;
|
||||||
curr->data = malloc(curr->len);
|
curr->data = malloc(curr->len);
|
||||||
@@ -336,6 +345,7 @@ unsigned char* ReadZip(const char* filename,
|
|||||||
}
|
}
|
||||||
curr->data = img + pos;
|
curr->data = img + pos;
|
||||||
curr->filename = NULL;
|
curr->filename = NULL;
|
||||||
|
curr->I = NULL;
|
||||||
pos += curr->len;
|
pos += curr->len;
|
||||||
|
|
||||||
++*num_chunks;
|
++*num_chunks;
|
||||||
@@ -400,6 +410,7 @@ unsigned char* ReadImage(const char* filename,
|
|||||||
curr->type = CHUNK_NORMAL;
|
curr->type = CHUNK_NORMAL;
|
||||||
curr->len = GZIP_HEADER_LEN;
|
curr->len = GZIP_HEADER_LEN;
|
||||||
curr->data = p;
|
curr->data = p;
|
||||||
|
curr->I = NULL;
|
||||||
|
|
||||||
pos += curr->len;
|
pos += curr->len;
|
||||||
p += curr->len;
|
p += curr->len;
|
||||||
@@ -407,6 +418,7 @@ unsigned char* ReadImage(const char* filename,
|
|||||||
|
|
||||||
curr->type = CHUNK_DEFLATE;
|
curr->type = CHUNK_DEFLATE;
|
||||||
curr->filename = NULL;
|
curr->filename = NULL;
|
||||||
|
curr->I = NULL;
|
||||||
|
|
||||||
// We must decompress this chunk in order to discover where it
|
// We must decompress this chunk in order to discover where it
|
||||||
// ends, and so we can put the uncompressed data and its length
|
// ends, and so we can put the uncompressed data and its length
|
||||||
@@ -452,6 +464,7 @@ unsigned char* ReadImage(const char* filename,
|
|||||||
curr->start = pos;
|
curr->start = pos;
|
||||||
curr->len = GZIP_FOOTER_LEN;
|
curr->len = GZIP_FOOTER_LEN;
|
||||||
curr->data = img+pos;
|
curr->data = img+pos;
|
||||||
|
curr->I = NULL;
|
||||||
|
|
||||||
pos += curr->len;
|
pos += curr->len;
|
||||||
p += curr->len;
|
p += curr->len;
|
||||||
@@ -475,6 +488,7 @@ unsigned char* ReadImage(const char* filename,
|
|||||||
*chunks = realloc(*chunks, *num_chunks * sizeof(ImageChunk));
|
*chunks = realloc(*chunks, *num_chunks * sizeof(ImageChunk));
|
||||||
ImageChunk* curr = *chunks + (*num_chunks-1);
|
ImageChunk* curr = *chunks + (*num_chunks-1);
|
||||||
curr->start = pos;
|
curr->start = pos;
|
||||||
|
curr->I = NULL;
|
||||||
|
|
||||||
// 'pos' is not the offset of the start of a gzip chunk, so scan
|
// 'pos' is not the offset of the start of a gzip chunk, so scan
|
||||||
// forward until we find a gzip header.
|
// forward until we find a gzip header.
|
||||||
@@ -591,43 +605,12 @@ unsigned char* MakePatch(ImageChunk* src, ImageChunk* tgt, size_t* size) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char stemp[] = "/tmp/imgdiff-src-XXXXXX";
|
|
||||||
char ttemp[] = "/tmp/imgdiff-tgt-XXXXXX";
|
|
||||||
char ptemp[] = "/tmp/imgdiff-patch-XXXXXX";
|
char ptemp[] = "/tmp/imgdiff-patch-XXXXXX";
|
||||||
mkstemp(stemp);
|
|
||||||
mkstemp(ttemp);
|
|
||||||
mkstemp(ptemp);
|
mkstemp(ptemp);
|
||||||
|
|
||||||
FILE* f = fopen(stemp, "wb");
|
int r = bsdiff(src->data, src->len, &(src->I), tgt->data, tgt->len, ptemp);
|
||||||
if (f == NULL) {
|
if (r != 0) {
|
||||||
fprintf(stderr, "failed to open src chunk %s: %s\n",
|
fprintf(stderr, "bsdiff() failed: %d\n", r);
|
||||||
stemp, strerror(errno));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (fwrite(src->data, 1, src->len, f) != src->len) {
|
|
||||||
fprintf(stderr, "failed to write src chunk to %s: %s\n",
|
|
||||||
stemp, strerror(errno));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
f = fopen(ttemp, "wb");
|
|
||||||
if (f == NULL) {
|
|
||||||
fprintf(stderr, "failed to open tgt chunk %s: %s\n",
|
|
||||||
ttemp, strerror(errno));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (fwrite(tgt->data, 1, tgt->len, f) != tgt->len) {
|
|
||||||
fprintf(stderr, "failed to write tgt chunk to %s: %s\n",
|
|
||||||
ttemp, strerror(errno));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
char cmd[200];
|
|
||||||
sprintf(cmd, "bsdiff %s %s %s", stemp, ttemp, ptemp);
|
|
||||||
if (system(cmd) != 0) {
|
|
||||||
fprintf(stderr, "failed to run bsdiff: %s\n", strerror(errno));
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -641,8 +624,6 @@ unsigned char* MakePatch(ImageChunk* src, ImageChunk* tgt, size_t* size) {
|
|||||||
unsigned char* data = malloc(st.st_size);
|
unsigned char* data = malloc(st.st_size);
|
||||||
|
|
||||||
if (tgt->type == CHUNK_NORMAL && tgt->len <= st.st_size) {
|
if (tgt->type == CHUNK_NORMAL && tgt->len <= st.st_size) {
|
||||||
unlink(stemp);
|
|
||||||
unlink(ttemp);
|
|
||||||
unlink(ptemp);
|
unlink(ptemp);
|
||||||
|
|
||||||
tgt->type = CHUNK_RAW;
|
tgt->type = CHUNK_RAW;
|
||||||
@@ -652,7 +633,7 @@ unsigned char* MakePatch(ImageChunk* src, ImageChunk* tgt, size_t* size) {
|
|||||||
|
|
||||||
*size = st.st_size;
|
*size = st.st_size;
|
||||||
|
|
||||||
f = fopen(ptemp, "rb");
|
FILE* f = fopen(ptemp, "rb");
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
fprintf(stderr, "failed to open patch %s: %s\n", ptemp, strerror(errno));
|
fprintf(stderr, "failed to open patch %s: %s\n", ptemp, strerror(errno));
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -663,8 +644,6 @@ unsigned char* MakePatch(ImageChunk* src, ImageChunk* tgt, size_t* size) {
|
|||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
unlink(stemp);
|
|
||||||
unlink(ttemp);
|
|
||||||
unlink(ptemp);
|
unlink(ptemp);
|
||||||
|
|
||||||
tgt->source_start = src->start;
|
tgt->source_start = src->start;
|
||||||
@@ -784,6 +763,14 @@ ImageChunk* FindChunkByName(const char* name,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DumpChunks(ImageChunk* chunks, int num_chunks) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < num_chunks; ++i) {
|
||||||
|
printf("chunk %d: type %d start %d len %d\n",
|
||||||
|
i, chunks[i].type, chunks[i].start, chunks[i].len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
if (argc != 4 && argc != 5) {
|
if (argc != 4 && argc != 5) {
|
||||||
usage:
|
usage:
|
||||||
@@ -829,14 +816,29 @@ int main(int argc, char** argv) {
|
|||||||
// Verify that the source and target images have the same chunk
|
// Verify that the source and target images have the same chunk
|
||||||
// structure (ie, the same sequence of deflate and normal chunks).
|
// structure (ie, the same sequence of deflate and normal chunks).
|
||||||
|
|
||||||
|
if (!zip_mode) {
|
||||||
|
// Merge the gzip header and footer in with any adjacent
|
||||||
|
// normal chunks.
|
||||||
|
MergeAdjacentNormalChunks(tgt_chunks, &num_tgt_chunks);
|
||||||
|
MergeAdjacentNormalChunks(src_chunks, &num_src_chunks);
|
||||||
|
}
|
||||||
|
|
||||||
if (num_src_chunks != num_tgt_chunks) {
|
if (num_src_chunks != num_tgt_chunks) {
|
||||||
fprintf(stderr, "source and target don't have same number of chunks!\n");
|
fprintf(stderr, "source and target don't have same number of chunks!\n");
|
||||||
|
printf("source chunks:\n");
|
||||||
|
DumpChunks(src_chunks, num_src_chunks);
|
||||||
|
printf("target chunks:\n");
|
||||||
|
DumpChunks(tgt_chunks, num_tgt_chunks);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
for (i = 0; i < num_src_chunks; ++i) {
|
for (i = 0; i < num_src_chunks; ++i) {
|
||||||
if (src_chunks[i].type != tgt_chunks[i].type) {
|
if (src_chunks[i].type != tgt_chunks[i].type) {
|
||||||
fprintf(stderr, "source and target don't have same chunk "
|
fprintf(stderr, "source and target don't have same chunk "
|
||||||
"structure! (chunk %d)\n", i);
|
"structure! (chunk %d)\n", i);
|
||||||
|
printf("source chunks:\n");
|
||||||
|
DumpChunks(src_chunks, num_src_chunks);
|
||||||
|
printf("target chunks:\n");
|
||||||
|
DumpChunks(tgt_chunks, num_tgt_chunks);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,11 +7,14 @@
|
|||||||
|
|
||||||
typedef struct mapentry mapentry;
|
typedef struct mapentry mapentry;
|
||||||
|
|
||||||
|
#define MAX_ALIASES 10
|
||||||
|
|
||||||
struct mapentry
|
struct mapentry
|
||||||
{
|
{
|
||||||
mapentry *next;
|
mapentry *next;
|
||||||
unsigned base;
|
unsigned base;
|
||||||
char name[0];
|
char *names[MAX_ALIASES];
|
||||||
|
int num_names;
|
||||||
};
|
};
|
||||||
|
|
||||||
static mapentry *maplist = 0;
|
static mapentry *maplist = 0;
|
||||||
@@ -22,14 +25,13 @@ static mapentry *maplist = 0;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define PRELINK_MIN 0x90000000
|
#define PRELINK_MIN 0x90000000
|
||||||
#define PRELINK_MAX 0xB0000000
|
#define PRELINK_MAX 0xBFFFFFFF
|
||||||
|
|
||||||
void pm_init(const char *file)
|
void pm_init(const char *file)
|
||||||
{
|
{
|
||||||
unsigned line = 0;
|
unsigned line = 0;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
char *x;
|
char *x;
|
||||||
unsigned n;
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
mapentry *me;
|
mapentry *me;
|
||||||
unsigned last = -1UL;
|
unsigned last = -1UL;
|
||||||
@@ -65,16 +67,34 @@ void pm_init(const char *file)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = strtoul(x, 0, 16);
|
if (isalpha(*x)) {
|
||||||
/* Note that this is not the only bounds check. If a library's size
|
/* Assume that this is an alias, and look through the list of
|
||||||
exceeds its slot as defined in the prelink map, the prelinker will
|
already-installed libraries.
|
||||||
exit with an error. See pm_report_library_size_in_memory().
|
*/
|
||||||
|
me = maplist;
|
||||||
|
while(me) {
|
||||||
|
/* The strlen() call ignores the newline at the end of x */
|
||||||
|
if (!strncmp(me->names[0], x, strlen(me->names[0]))) {
|
||||||
|
PRINT("Aliasing library %s to %s at %08x\n",
|
||||||
|
buf, x, me->base);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
me = me->next;
|
||||||
|
}
|
||||||
|
FAILIF(!me, "Nonexistent alias %s -> %s\n", buf, x);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
unsigned n = strtoul(x, 0, 16);
|
||||||
|
/* Note that this is not the only bounds check. If a library's
|
||||||
|
size exceeds its slot as defined in the prelink map, the
|
||||||
|
prelinker will exit with an error. See
|
||||||
|
pm_report_library_size_in_memory().
|
||||||
*/
|
*/
|
||||||
FAILIF((n < PRELINK_MIN) || (n > PRELINK_MAX),
|
FAILIF((n < PRELINK_MIN) || (n > PRELINK_MAX),
|
||||||
"%s:%d base 0x%08x out of range.\n",
|
"%s:%d base 0x%08x out of range.\n",
|
||||||
file, line, n);
|
file, line, n);
|
||||||
|
|
||||||
me = malloc(sizeof(mapentry) + strlen(buf) + 1);
|
me = malloc(sizeof(mapentry));
|
||||||
FAILIF(me == NULL, "Out of memory parsing %s\n", file);
|
FAILIF(me == NULL, "Out of memory parsing %s\n", file);
|
||||||
|
|
||||||
FAILIF(last <= n, "The prelink map is not in descending order "
|
FAILIF(last <= n, "The prelink map is not in descending order "
|
||||||
@@ -82,11 +102,19 @@ void pm_init(const char *file)
|
|||||||
last = n;
|
last = n;
|
||||||
|
|
||||||
me->base = n;
|
me->base = n;
|
||||||
strcpy(me->name, buf);
|
|
||||||
me->next = maplist;
|
me->next = maplist;
|
||||||
|
me->num_names = 0;
|
||||||
maplist = me;
|
maplist = me;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FAILIF(me->num_names >= MAX_ALIASES,
|
||||||
|
"Too many aliases for library %s, maximum is %d.\n",
|
||||||
|
me->names[0],
|
||||||
|
MAX_ALIASES);
|
||||||
|
me->names[me->num_names] = strdup(buf);
|
||||||
|
me->num_names++;
|
||||||
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,41 +127,44 @@ void pm_report_library_size_in_memory(const char *name,
|
|||||||
{
|
{
|
||||||
char *x;
|
char *x;
|
||||||
mapentry *me;
|
mapentry *me;
|
||||||
|
int n;
|
||||||
|
|
||||||
x = strrchr(name,'/');
|
x = strrchr(name,'/');
|
||||||
if(x) name = x+1;
|
if(x) name = x+1;
|
||||||
|
|
||||||
for(me = maplist; me; me = me->next){
|
for(me = maplist; me; me = me->next){
|
||||||
if(!strcmp(name, me->name)) {
|
for (n = 0; n < me->num_names; n++) {
|
||||||
|
if(!strcmp(name, me->names[n])) {
|
||||||
off_t slot = me->next ? me->next->base : PRELINK_MAX;
|
off_t slot = me->next ? me->next->base : PRELINK_MAX;
|
||||||
slot -= me->base;
|
slot -= me->base;
|
||||||
FAILIF(fsize > slot,
|
FAILIF(fsize > slot,
|
||||||
"prelink map error: library %s@0x%08x is too big "
|
"prelink map error: library %s@0x%08x is too big "
|
||||||
"at %lld bytes, it runs %lld bytes into "
|
"at %lld bytes, it runs %lld bytes into "
|
||||||
"library %s@0x%08x!\n",
|
"library %s@0x%08x!\n",
|
||||||
me->name, me->base, fsize, fsize - slot,
|
me->names[0], me->base, fsize, fsize - slot,
|
||||||
me->next->name, me->next->base);
|
me->next->names[0], me->next->base);
|
||||||
break;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FAILIF(!me,"library '%s' not in prelink map\n", name);
|
FAILIF(1, "library '%s' not in prelink map\n", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned pm_get_next_link_address(const char *lookup_name)
|
unsigned pm_get_next_link_address(const char *lookup_name)
|
||||||
{
|
{
|
||||||
char *x;
|
char *x;
|
||||||
mapentry *me;
|
mapentry *me;
|
||||||
|
int n;
|
||||||
|
|
||||||
x = strrchr(lookup_name,'/');
|
x = strrchr(lookup_name,'/');
|
||||||
if(x) lookup_name = x+1;
|
if(x) lookup_name = x+1;
|
||||||
|
|
||||||
for(me = maplist; me; me = me->next){
|
for(me = maplist; me; me = me->next)
|
||||||
if(!strcmp(lookup_name, me->name)) {
|
for (n = 0; n < me->num_names; n++)
|
||||||
|
if(!strcmp(lookup_name, me->names[n]))
|
||||||
return me->base;
|
return me->base;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FAILIF(1==1,"library '%s' not in prelink map\n", lookup_name);
|
FAILIF(1, "library '%s' not in prelink map\n", lookup_name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
is_comment_line(const char* p)
|
is_comment_line(const char* p)
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
#include <host/CopyFile.h>
|
#include <host/CopyFile.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@@ -24,6 +24,7 @@ echo "ro.product.cpu.abi=$TARGET_CPU_ABI"
|
|||||||
echo "ro.product.manufacturer=$PRODUCT_MANUFACTURER"
|
echo "ro.product.manufacturer=$PRODUCT_MANUFACTURER"
|
||||||
echo "ro.product.locale.language=$PRODUCT_DEFAULT_LANGUAGE"
|
echo "ro.product.locale.language=$PRODUCT_DEFAULT_LANGUAGE"
|
||||||
echo "ro.product.locale.region=$PRODUCT_DEFAULT_REGION"
|
echo "ro.product.locale.region=$PRODUCT_DEFAULT_REGION"
|
||||||
|
echo "ro.wifi.channels=$PRODUCT_DEFAULT_WIFI_CHANNELS"
|
||||||
echo "ro.board.platform=$TARGET_BOARD_PLATFORM"
|
echo "ro.board.platform=$TARGET_BOARD_PLATFORM"
|
||||||
|
|
||||||
echo "# ro.build.product is obsolete; use ro.product.device"
|
echo "# ro.build.product is obsolete; use ro.product.device"
|
||||||
|
@@ -77,6 +77,13 @@ ifdef sign_dexpreopt
|
|||||||
$(shell echo "$(p) $(PACKAGES.$(p).CERTIFICATE) $(PACKAGES.$(p).PRIVATE_KEY)" >> $(dexpreopt_package_certs_file)))
|
$(shell echo "$(p) $(PACKAGES.$(p).CERTIFICATE) $(PACKAGES.$(p).PRIVATE_KEY)" >> $(dexpreopt_package_certs_file)))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# The kernel used for ARMv7 system images is different
|
||||||
|
ifeq ($(TARGET_ARCH_VARIANT),armv7-a)
|
||||||
|
BUILD_DEXPREOPT_KERNEL := prebuilt/android-arm/kernel/kernel-qemu-armv7
|
||||||
|
else
|
||||||
|
BUILD_DEXPREOPT_KERNEL := prebuilt/android-arm/kernel/kernel-qemu
|
||||||
|
endif
|
||||||
|
|
||||||
# Build an optimized image from the unoptimized image
|
# Build an optimized image from the unoptimized image
|
||||||
BUILT_DEXPREOPT_SYSTEMIMAGE := $(intermediates)/system.img
|
BUILT_DEXPREOPT_SYSTEMIMAGE := $(intermediates)/system.img
|
||||||
$(BUILT_DEXPREOPT_SYSTEMIMAGE): $(BUILT_SYSTEMIMAGE_UNOPT)
|
$(BUILT_DEXPREOPT_SYSTEMIMAGE): $(BUILT_SYSTEMIMAGE_UNOPT)
|
||||||
@@ -99,7 +106,7 @@ $(BUILT_DEXPREOPT_SYSTEMIMAGE):
|
|||||||
$(hide) \
|
$(hide) \
|
||||||
PATH=$(HOST_OUT_EXECUTABLES):$$PATH \
|
PATH=$(HOST_OUT_EXECUTABLES):$$PATH \
|
||||||
$(DEXPREOPT) \
|
$(DEXPREOPT) \
|
||||||
--kernel prebuilt/android-arm/kernel/kernel-qemu \
|
--kernel $(BUILD_DEXPREOPT_KERNEL) \
|
||||||
--ramdisk $(BUILT_DEXPREOPT_RAMDISK) \
|
--ramdisk $(BUILT_DEXPREOPT_RAMDISK) \
|
||||||
--image $(BUILT_SYSTEMIMAGE_UNOPT) \
|
--image $(BUILT_SYSTEMIMAGE_UNOPT) \
|
||||||
--system $(PRODUCT_OUT) \
|
--system $(PRODUCT_OUT) \
|
||||||
|
@@ -35,6 +35,7 @@ class AnnotationInstanceInfo
|
|||||||
return mElementValues;
|
return mElementValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
StringBuilder str = new StringBuilder();
|
StringBuilder str = new StringBuilder();
|
||||||
|
@@ -99,6 +99,7 @@ public class AttrTagInfo extends TagInfo
|
|||||||
return REF_COMMAND.equals(mCommand) ? mRefField : null;
|
return REF_COMMAND.equals(mCommand) ? mRefField : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String name() {
|
public String name() {
|
||||||
return NAME_COMMAND.equals(mCommand) ? mAttrName : null;
|
return NAME_COMMAND.equals(mCommand) ? mAttrName : null;
|
||||||
}
|
}
|
||||||
@@ -107,6 +108,7 @@ public class AttrTagInfo extends TagInfo
|
|||||||
return DESCRIPTION_COMMAND.equals(mCommand) ? mDescrComment : null;
|
return DESCRIPTION_COMMAND.equals(mCommand) ? mDescrComment : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void makeHDF(HDF data, String base)
|
public void makeHDF(HDF data, String base)
|
||||||
{
|
{
|
||||||
super.makeHDF(data, base);
|
super.makeHDF(data, base);
|
||||||
|
@@ -146,6 +146,7 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ContainerInfo parent()
|
public ContainerInfo parent()
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
@@ -378,7 +379,7 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco
|
|||||||
|
|
||||||
public TagInfo[] deprecatedTags()
|
public TagInfo[] deprecatedTags()
|
||||||
{
|
{
|
||||||
// should we also do the interfaces?
|
// Should we also do the interfaces?
|
||||||
return comment().deprecatedTags();
|
return comment().deprecatedTags();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1137,6 +1138,10 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco
|
|||||||
data.setValue(base + ".kind", kind);
|
data.setValue(base + ".kind", kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cl.mIsIncluded) {
|
||||||
|
data.setValue(base + ".included", "true");
|
||||||
|
}
|
||||||
|
|
||||||
// xml attributes
|
// xml attributes
|
||||||
i=0;
|
i=0;
|
||||||
for (AttributeInfo attr: cl.selfAttributes()) {
|
for (AttributeInfo attr: cl.selfAttributes()) {
|
||||||
@@ -1170,6 +1175,7 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isHidden()
|
public boolean isHidden()
|
||||||
{
|
{
|
||||||
int val = mHidden;
|
int val = mHidden;
|
||||||
@@ -1384,6 +1390,7 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco
|
|||||||
public MethodInfo[] getHiddenMethods(){
|
public MethodInfo[] getHiddenMethods(){
|
||||||
return mHiddenMethods;
|
return mHiddenMethods;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
return this.qualifiedName();
|
return this.qualifiedName();
|
||||||
}
|
}
|
||||||
|
@@ -157,7 +157,7 @@ public class Comment
|
|||||||
else if (name.equals("@literal")) {
|
else if (name.equals("@literal")) {
|
||||||
mInlineTagsList.add(new LiteralTagInfo(name, name, text, pos));
|
mInlineTagsList.add(new LiteralTagInfo(name, name, text, pos));
|
||||||
}
|
}
|
||||||
else if (name.equals("@hide") || name.equals("@doconly")) {
|
else if (name.equals("@hide") || name.equals("@pending") || name.equals("@doconly")) {
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
else if (name.equals("@attr")) {
|
else if (name.equals("@attr")) {
|
||||||
@@ -307,7 +307,7 @@ public class Comment
|
|||||||
mHidden = 0;
|
mHidden = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
boolean b = mText.indexOf("@hide") >= 0;
|
boolean b = mText.indexOf("@hide") >= 0 || mText.indexOf("@pending") >= 0;
|
||||||
mHidden = b ? 1 : 0;
|
mHidden = b ? 1 : 0;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
@@ -238,6 +238,7 @@ public class Converter
|
|||||||
}
|
}
|
||||||
private static Cache mClasses = new Cache()
|
private static Cache mClasses = new Cache()
|
||||||
{
|
{
|
||||||
|
@Override
|
||||||
protected Object make(Object o)
|
protected Object make(Object o)
|
||||||
{
|
{
|
||||||
ClassDoc c = (ClassDoc)o;
|
ClassDoc c = (ClassDoc)o;
|
||||||
@@ -268,6 +269,7 @@ public class Converter
|
|||||||
}
|
}
|
||||||
return cl;
|
return cl;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
protected void made(Object o, Object r)
|
protected void made(Object o, Object r)
|
||||||
{
|
{
|
||||||
if (mClassesNeedingInit == null) {
|
if (mClassesNeedingInit == null) {
|
||||||
@@ -275,6 +277,7 @@ public class Converter
|
|||||||
((ClassInfo)r).init2();
|
((ClassInfo)r).init2();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
ClassInfo[] all()
|
ClassInfo[] all()
|
||||||
{
|
{
|
||||||
return (ClassInfo[])mCache.values().toArray(new ClassInfo[mCache.size()]);
|
return (ClassInfo[])mCache.values().toArray(new ClassInfo[mCache.size()]);
|
||||||
@@ -367,6 +370,7 @@ public class Converter
|
|||||||
}
|
}
|
||||||
private static Cache mMethods = new Cache()
|
private static Cache mMethods = new Cache()
|
||||||
{
|
{
|
||||||
|
@Override
|
||||||
protected Object make(Object o)
|
protected Object make(Object o)
|
||||||
{
|
{
|
||||||
if (o instanceof AnnotationTypeElementDoc) {
|
if (o instanceof AnnotationTypeElementDoc) {
|
||||||
@@ -472,6 +476,7 @@ public class Converter
|
|||||||
}
|
}
|
||||||
private static Cache mFields = new Cache()
|
private static Cache mFields = new Cache()
|
||||||
{
|
{
|
||||||
|
@Override
|
||||||
protected Object make(Object o)
|
protected Object make(Object o)
|
||||||
{
|
{
|
||||||
FieldDoc f = (FieldDoc)o;
|
FieldDoc f = (FieldDoc)o;
|
||||||
@@ -496,6 +501,7 @@ public class Converter
|
|||||||
}
|
}
|
||||||
private static Cache mPackagees = new Cache()
|
private static Cache mPackagees = new Cache()
|
||||||
{
|
{
|
||||||
|
@Override
|
||||||
protected Object make(Object o)
|
protected Object make(Object o)
|
||||||
{
|
{
|
||||||
PackageDoc p = (PackageDoc)o;
|
PackageDoc p = (PackageDoc)o;
|
||||||
@@ -510,6 +516,7 @@ public class Converter
|
|||||||
}
|
}
|
||||||
private static Cache mTypes = new Cache()
|
private static Cache mTypes = new Cache()
|
||||||
{
|
{
|
||||||
|
@Override
|
||||||
protected Object make(Object o)
|
protected Object make(Object o)
|
||||||
{
|
{
|
||||||
Type t = (Type)o;
|
Type t = (Type)o;
|
||||||
@@ -524,6 +531,7 @@ public class Converter
|
|||||||
Converter.obtainClass(t.asClassDoc()));
|
Converter.obtainClass(t.asClassDoc()));
|
||||||
return ti;
|
return ti;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
protected void made(Object o, Object r)
|
protected void made(Object o, Object r)
|
||||||
{
|
{
|
||||||
Type t = (Type)o;
|
Type t = (Type)o;
|
||||||
@@ -545,6 +553,7 @@ public class Converter
|
|||||||
Converter.convertTypes(t.asWildcardType().extendsBounds()));
|
Converter.convertTypes(t.asWildcardType().extendsBounds()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
protected Object keyFor(Object o)
|
protected Object keyFor(Object o)
|
||||||
{
|
{
|
||||||
Type t = (Type)o;
|
Type t = (Type)o;
|
||||||
@@ -599,6 +608,7 @@ public class Converter
|
|||||||
}
|
}
|
||||||
private static Cache mMembers = new Cache()
|
private static Cache mMembers = new Cache()
|
||||||
{
|
{
|
||||||
|
@Override
|
||||||
protected Object make(Object o)
|
protected Object make(Object o)
|
||||||
{
|
{
|
||||||
if (o instanceof MethodDoc) {
|
if (o instanceof MethodDoc) {
|
||||||
@@ -633,6 +643,7 @@ public class Converter
|
|||||||
}
|
}
|
||||||
private static Cache mAnnotationInstances = new Cache()
|
private static Cache mAnnotationInstances = new Cache()
|
||||||
{
|
{
|
||||||
|
@Override
|
||||||
protected Object make(Object o)
|
protected Object make(Object o)
|
||||||
{
|
{
|
||||||
AnnotationDesc a = (AnnotationDesc)o;
|
AnnotationDesc a = (AnnotationDesc)o;
|
||||||
|
@@ -95,6 +95,7 @@ public class DroidDoc
|
|||||||
String stubsDir = null;
|
String stubsDir = null;
|
||||||
//Create the dependency graph for the stubs directory
|
//Create the dependency graph for the stubs directory
|
||||||
boolean apiXML = false;
|
boolean apiXML = false;
|
||||||
|
boolean noDocs = false;
|
||||||
String apiFile = null;
|
String apiFile = null;
|
||||||
String debugStubsFile = "";
|
String debugStubsFile = "";
|
||||||
HashSet<String> stubPackages = null;
|
HashSet<String> stubPackages = null;
|
||||||
@@ -187,6 +188,9 @@ public class DroidDoc
|
|||||||
apiXML = true;
|
apiXML = true;
|
||||||
apiFile = a[1];
|
apiFile = a[1];
|
||||||
}
|
}
|
||||||
|
else if (a[0].equals("-nodocs")) {
|
||||||
|
noDocs = true;
|
||||||
|
}
|
||||||
else if (a[0].equals("-since")) {
|
else if (a[0].equals("-since")) {
|
||||||
sinceTagger.addVersion(a[1], a[2]);
|
sinceTagger.addVersion(a[1], a[2]);
|
||||||
}
|
}
|
||||||
@@ -200,6 +204,12 @@ public class DroidDoc
|
|||||||
// Set up the data structures
|
// Set up the data structures
|
||||||
Converter.makeInfo(r);
|
Converter.makeInfo(r);
|
||||||
|
|
||||||
|
if (!noDocs) {
|
||||||
|
long startTime = System.nanoTime();
|
||||||
|
|
||||||
|
// Apply @since tags from the XML file
|
||||||
|
sinceTagger.tagAll(Converter.rootClasses());
|
||||||
|
|
||||||
// Files for proofreading
|
// Files for proofreading
|
||||||
if (proofreadFile != null) {
|
if (proofreadFile != null) {
|
||||||
Proofread.initProofread(proofreadFile);
|
Proofread.initProofread(proofreadFile);
|
||||||
@@ -208,9 +218,6 @@ public class DroidDoc
|
|||||||
TodoFile.writeTodoFile(todoFile);
|
TodoFile.writeTodoFile(todoFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply @since tags from the XML file
|
|
||||||
sinceTagger.tagAll(Converter.rootClasses());
|
|
||||||
|
|
||||||
// HTML Pages
|
// HTML Pages
|
||||||
if (ClearPage.htmlDir != null) {
|
if (ClearPage.htmlDir != null) {
|
||||||
writeHTMLPages();
|
writeHTMLPages();
|
||||||
@@ -247,15 +254,20 @@ public class DroidDoc
|
|||||||
|
|
||||||
Proofread.finishProofread(proofreadFile);
|
Proofread.finishProofread(proofreadFile);
|
||||||
|
|
||||||
|
if (sdkValuePath != null) {
|
||||||
|
writeSdkValues(sdkValuePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
long time = System.nanoTime() - startTime;
|
||||||
|
System.out.println("DroidDoc took " + (time / 1000000000) + " sec. to write docs to "
|
||||||
|
+ ClearPage.outputDir);
|
||||||
|
}
|
||||||
|
|
||||||
// Stubs
|
// Stubs
|
||||||
if (stubsDir != null) {
|
if (stubsDir != null) {
|
||||||
Stubs.writeStubs(stubsDir, apiXML, apiFile, stubPackages);
|
Stubs.writeStubs(stubsDir, apiXML, apiFile, stubPackages);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sdkValuePath != null) {
|
|
||||||
writeSdkValues(sdkValuePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
Errors.printErrors();
|
Errors.printErrors();
|
||||||
return !Errors.hadError;
|
return !Errors.hadError;
|
||||||
}
|
}
|
||||||
@@ -401,6 +413,9 @@ public class DroidDoc
|
|||||||
if (option.equals("-apixml")) {
|
if (option.equals("-apixml")) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
if (option.equals("-nodocs")) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (option.equals("-since")) {
|
if (option.equals("-since")) {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
@@ -964,10 +979,11 @@ public class DroidDoc
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the given element has an @hide annotation.
|
* Returns true if the given element has an @hide or @pending annotation.
|
||||||
*/
|
*/
|
||||||
private static boolean hasHideAnnotation(Doc doc) {
|
private static boolean hasHideAnnotation(Doc doc) {
|
||||||
return doc.getRawCommentText().indexOf("@hide") != -1;
|
String comment = doc.getRawCommentText();
|
||||||
|
return comment.indexOf("@hide") != -1 || comment.indexOf("@pending") != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -41,6 +41,7 @@ public class Errors
|
|||||||
return this.msg.compareTo(that.msg);
|
return this.msg.compareTo(that.msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String whereText = this.pos == null ? "unknown: " : this.pos.toString() + ':';
|
String whereText = this.pos == null ? "unknown: " : this.pos.toString() + ':';
|
||||||
return whereText + this.msg;
|
return whereText + this.msg;
|
||||||
|
@@ -291,6 +291,7 @@ public class FieldInfo extends MemberInfo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isExecutable()
|
public boolean isExecutable()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@@ -115,6 +115,7 @@ public abstract class MemberInfo extends DocInfo implements Comparable, Scoped
|
|||||||
return mIsSynthetic;
|
return mIsSynthetic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ContainerInfo parent()
|
public ContainerInfo parent()
|
||||||
{
|
{
|
||||||
return mContainingClass;
|
return mContainingClass;
|
||||||
|
@@ -589,6 +589,7 @@ public class MethodInfo extends MemberInfo
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isExecutable()
|
public boolean isExecutable()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -624,6 +625,8 @@ public class MethodInfo extends MemberInfo
|
|||||||
public boolean isVarArgs(){
|
public boolean isVarArgs(){
|
||||||
return mIsVarargs;
|
return mIsVarargs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
return this.name();
|
return this.name();
|
||||||
}
|
}
|
||||||
|
@@ -57,11 +57,13 @@ public class PackageInfo extends DocInfo implements ContainerInfo
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ContainerInfo parent()
|
public ContainerInfo parent()
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isHidden()
|
public boolean isHidden()
|
||||||
{
|
{
|
||||||
return comment().isHidden();
|
return comment().isHidden();
|
||||||
|
@@ -76,6 +76,7 @@ public class ParamTagInfo extends ParsedTagInfo
|
|||||||
return mParameterName;
|
return mParameterName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void makeHDF(HDF data, String base)
|
public void makeHDF(HDF data, String base)
|
||||||
{
|
{
|
||||||
data.setValue(base + ".name", parameterName());
|
data.setValue(base + ".name", parameterName());
|
||||||
|
@@ -274,6 +274,7 @@ public class SampleTagInfo extends TagInfo
|
|||||||
return result.substring(0);
|
return result.substring(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void makeHDF(HDF data, String base)
|
public void makeHDF(HDF data, String base)
|
||||||
{
|
{
|
||||||
data.setValue(base + ".name", name());
|
data.setValue(base + ".name", name());
|
||||||
|
@@ -45,6 +45,7 @@ public class SeeTagInfo extends TagInfo
|
|||||||
return linkReference().label;
|
return linkReference().label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void makeHDF(HDF data, String base)
|
public void makeHDF(HDF data, String base)
|
||||||
{
|
{
|
||||||
LinkReference linkRef = linkReference();
|
LinkReference linkRef = linkReference();
|
||||||
|
@@ -76,6 +76,7 @@ public class SourcePositionInfo implements Comparable
|
|||||||
return new SourcePositionInfo(that.file, line, 0);
|
return new SourcePositionInfo(that.file, line, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return file + ':' + line;
|
return file + ':' + line;
|
||||||
|
@@ -249,6 +249,7 @@ public class TypeInfo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
String returnString = "";
|
String returnString = "";
|
||||||
returnString += "Primitive?: " + mIsPrimitive + " TypeVariable?: " +
|
returnString += "Primitive?: " + mIsPrimitive + " TypeVariable?: " +
|
||||||
|
@@ -73,9 +73,10 @@ def:custom_masthead() ?>
|
|||||||
call:default_search_box() ?><?cs
|
call:default_search_box() ?><?cs
|
||||||
if:reference ?>
|
if:reference ?>
|
||||||
<div id="api-level-toggle">
|
<div id="api-level-toggle">
|
||||||
<label for="apiLevelControl"><a href="<?cs var:toroot ?>guide/appendix/api-levels.html">Filter by API Level</a>: </label>
|
<input type="checkbox" id="apiLevelCheckbox" onclick="toggleApiLevelSelector(this)" />
|
||||||
<select id="apiLevelControl">
|
<label for="apiLevelCheckbox" class="disabled">Filter by API Level: </label>
|
||||||
<!-- option elements added by buildApiLevelToggle() -->
|
<select id="apiLevelSelector">
|
||||||
|
<!-- option elements added by buildApiLevelSelector() -->
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
@@ -85,7 +86,7 @@ def:custom_masthead() ?>
|
|||||||
if:!last(since) ?>, <?cs /if ?><?cs
|
if:!last(since) ?>, <?cs /if ?><?cs
|
||||||
/each
|
/each
|
||||||
?> ];
|
?> ];
|
||||||
buildApiLevelToggle();
|
buildApiLevelSelector();
|
||||||
</script><?cs
|
</script><?cs
|
||||||
/if ?>
|
/if ?>
|
||||||
</div><!-- headerRight -->
|
</div><!-- headerRight -->
|
||||||
|
@@ -1,66 +0,0 @@
|
|||||||
<ul>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>index.html">Home</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>what-is-android.html">What is Android?</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>intro/index.html">Getting Started</a></div>
|
|
||||||
<ul>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>intro/installing.html">Installing the SDK</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>intro/upgrading.html">Upgrading the SDK</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>intro/develop-and-debug.html">Developing/Debugging</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>intro/hello-android.html">Hello Android</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>intro/anatomy.html">Anatomy of an App</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>intro/tutorial.html">Notepad Tutorial</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>intro/tools.html">Development Tools</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>intro/appmodel.html">Application Model</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>intro/lifecycle.html">Application Life Cycle</a></div></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><div><div><a href="<?cs var:toroot ?>devel/index.html">Developing Applications</a></div>
|
|
||||||
<ul>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>devel/implementing-ui.html">Implementing a UI</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>devel/building-blocks.html">Building Blocks</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>devel/data.html">Data Storage and Retrieval</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>devel/security.html">Security Model</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>devel/resources-i18n.html">Resources and i18n</a></div></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>toolbox/index.html">Developer Toolbox</a></div>
|
|
||||||
<ul>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>toolbox/philosophy.html">Design Philosophy</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>toolbox/custom-components.html">Building Custom Components</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>toolbox/optional-apis.html">Optional APIs</a></div></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>samples/index.html">Sample Code</a></div>
|
|
||||||
<ul>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>samples/ApiDemos/index.html">API Demos</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>samples/LunarLander/index.html">Lunar Lander</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>samples/NotePad/index.html">Note Pad</a></div></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li> <a href="<?cs var:toroot ?>reference/index.html"><strong>Reference Information</strong></a>
|
|
||||||
<ul>
|
|
||||||
<li><a href="<?cs var:toroot ?>reference/packages.html">Package Index</a></li>
|
|
||||||
<li><a href="<?cs var:toroot ?>reference/classes.html">Class Index</a></li>
|
|
||||||
<li><a href="<?cs var:toroot ?>reference/hierarchy.html">Class Hierarchy</a></li>
|
|
||||||
<li><a href="<?cs var:toroot ?>reference/view-gallery.html">List of Views</a></li>
|
|
||||||
<li><a href="<?cs var:toroot ?>reference/available-intents.html">List of Intents</a></li>
|
|
||||||
<li><a href="<?cs var:toroot ?>reference/android/Manifest.permission.html">List of Permissions</a></li>
|
|
||||||
<li><a href="<?cs var:toroot ?>reference/available-resources.html">List of Resource Types</a></li>
|
|
||||||
<li><a href="<?cs var:toroot ?>reference/aidl.html">Android IDL</a></li>
|
|
||||||
<li><a href="<?cs var:toroot ?>reference/glossary.html">Glossary</a></li>
|
|
||||||
<li><a href="<?cs var:toroot ?>reference/keywords.html">Index</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>kb/index.html">FAQs</a></div>
|
|
||||||
<ul>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>kb/general.html">General</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>kb/commontasks.html">Common Tasks</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>kb/troubleshooting.html">Troubleshooting</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>kb/licensingandoss.html">Open Source Licensing</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>kb/framework.html">Application Framework</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>kb/security.html">Security</a></div></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>roadmap.html">Roadmap</a></div></li>
|
|
||||||
<li><div><a href="<?cs var:toroot ?>goodies/index.html">Goodies</a></div></li>
|
|
||||||
</ul>
|
|
@@ -6,79 +6,81 @@
|
|||||||
elif:community ?>community<?cs
|
elif:community ?>community<?cs
|
||||||
elif:videos ?>videos<?cs /if ?>">
|
elif:videos ?>videos<?cs /if ?>">
|
||||||
|
|
||||||
<li id="home-link"><a href="<?cs var:toroot ?><?cs if:android.whichdoc != "online" ?>offline.html<?cs else ?>index.html<?cs /if ?>">
|
<li id="home-link"><a href="<?cs var:toroot ?><?cs
|
||||||
|
if:android.whichdoc != "online" ?>offline.html<?cs
|
||||||
|
else ?>index.html<?cs /if ?>">
|
||||||
<?cs if:!sdk.redirect ?>
|
<?cs if:!sdk.redirect ?>
|
||||||
<span class="en">Home</span>
|
<span class="en">Home</span>
|
||||||
<span class="de">Startseite</span>
|
<span style="display:none" class="de">Startseite</span>
|
||||||
<span class="es"></span>
|
<span style="display:none" class="es"></span>
|
||||||
<span class="fr"></span>
|
<span style="display:none" class="fr"></span>
|
||||||
<span class="it"></span>
|
<span style="display:none" class="it"></span>
|
||||||
<span class="ja">ホーム</span>
|
<span style="display:none" class="ja">ホーム</span>
|
||||||
<span class="zh-CN">主页</span>
|
<span style="display:none" class="zh-CN">主页</span>
|
||||||
<span class="zh-TW">首頁</span>
|
<span style="display:none" class="zh-TW">首頁</span>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
</a></li>
|
</a></li>
|
||||||
<li id="sdk-link"><a href="<?cs var:toroot ?>sdk/<?cs var:sdk.current ?>/index.html">
|
<li id="sdk-link"><a href="<?cs var:toroot ?>sdk/index.html">
|
||||||
<span class="en">SDK</span>
|
<span class="en">SDK</span>
|
||||||
</a></li>
|
</a></li>
|
||||||
<li id="guide-link"><a href="<?cs var:toroot ?>guide/index.html" onClick="return loadLast('guide')">
|
<li id="guide-link"><a href="<?cs var:toroot ?>guide/index.html" onClick="return loadLast('guide')">
|
||||||
<?cs if:!sdk.redirect ?>
|
<?cs if:!sdk.redirect ?>
|
||||||
<span class="en">Dev Guide</span>
|
<span class="en">Dev Guide</span>
|
||||||
<span class="de">Handbuch</span>
|
<span style="display:none" class="de">Handbuch</span>
|
||||||
<span class="es">Guía</span>
|
<span style="display:none" class="es">Guía</span>
|
||||||
<span class="fr">Guide</span>
|
<span style="display:none" class="fr">Guide</span>
|
||||||
<span class="it">Guida</span>
|
<span style="display:none" class="it">Guida</span>
|
||||||
<span class="ja">開発ガイド</span>
|
<span style="display:none" class="ja">開発ガイド</span>
|
||||||
<span class="zh-CN">开发人员指南</span>
|
<span style="display:none" class="zh-CN">开发人员指南</span>
|
||||||
<span class="zh-TW">開發指南</span>
|
<span style="display:none" class="zh-TW">開發指南</span>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
</a></li>
|
</a></li>
|
||||||
<li id="reference-link"><a href="<?cs var:toroot ?>reference/packages.html" onClick="return loadLast('reference')">
|
<li id="reference-link"><a href="<?cs var:toroot ?>reference/packages.html" onClick="return loadLast('reference')">
|
||||||
<?cs if:!sdk.redirect ?>
|
<?cs if:!sdk.redirect ?>
|
||||||
<span class="en">Reference</span>
|
<span class="en">Reference</span>
|
||||||
<span class="de">Referenz</span>
|
<span style="display:none" class="de">Referenz</span>
|
||||||
<span class="es">Referencia</span>
|
<span style="display:none" class="es">Referencia</span>
|
||||||
<span class="fr">Référence</span>
|
<span style="display:none" class="fr">Référence</span>
|
||||||
<span class="it">Riferimento</span>
|
<span style="display:none" class="it">Riferimento</span>
|
||||||
<span class="ja">リファレンス</span>
|
<span style="display:none" class="ja">リファレンス</span>
|
||||||
<span class="zh-CN">参考</span>
|
<span style="display:none" class="zh-CN">参考</span>
|
||||||
<span class="zh-TW">參考資料</span>
|
<span style="display:none" class="zh-TW">參考資料</span>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
</a></li>
|
</a></li>
|
||||||
<li><a href="http://android-developers.blogspot.com" onClick="return requestAppendHL(this.href)">
|
<li><a href="http://android-developers.blogspot.com" onClick="return requestAppendHL(this.href)">
|
||||||
<?cs if:!sdk.redirect ?>
|
<?cs if:!sdk.redirect ?>
|
||||||
<span class="en">Blog</span>
|
<span class="en">Blog</span>
|
||||||
<span class="de"></span>
|
<span style="display:none" class="de"></span>
|
||||||
<span class="es"></span>
|
<span style="display:none" class="es"></span>
|
||||||
<span class="fr"></span>
|
<span style="display:none" class="fr"></span>
|
||||||
<span class="it"></span>
|
<span style="display:none" class="it"></span>
|
||||||
<span class="ja">ブログ</span>
|
<span style="display:none" class="ja">ブログ</span>
|
||||||
<span class="zh-CN">博客</span>
|
<span style="display:none" class="zh-CN">博客</span>
|
||||||
<span class="zh-TW">網誌</span>
|
<span style="display:none" class="zh-TW">網誌</span>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
</a></li>
|
</a></li>
|
||||||
<li id="videos-link"><a href="<?cs var:toroot ?>videos/index.html" onClick="return loadLast('videos')">
|
<li id="videos-link"><a href="<?cs var:toroot ?>videos/index.html" onClick="return loadLast('videos')">
|
||||||
<?cs if:!sdk.redirect ?>
|
<?cs if:!sdk.redirect ?>
|
||||||
<span class="en">Videos</span>
|
<span class="en">Videos</span>
|
||||||
<span class="de"></span>
|
<span style="display:none" class="de"></span>
|
||||||
<span class="es"></span>
|
<span style="display:none" class="es"></span>
|
||||||
<span class="fr"></span>
|
<span style="display:none" class="fr"></span>
|
||||||
<span class="it"></span>
|
<span style="display:none" class="it"></span>
|
||||||
<span class="ja">ビデオ</span>
|
<span style="display:none" class="ja">ビデオ</span>
|
||||||
<span class="zh-CN"></span>
|
<span style="display:none" class="zh-CN"></span>
|
||||||
<span class="zh-TW"></span>
|
<span style="display:none" class="zh-TW"></span>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
</a></li>
|
</a></li>
|
||||||
<li id="community-link"><a href="<?cs var:toroot ?>community/index.html">
|
<li id="community-link"><a href="<?cs var:toroot ?>community/index.html">
|
||||||
<?cs if:!sdk.redirect ?>
|
<?cs if:!sdk.redirect ?>
|
||||||
<span class="en">Community</span>
|
<span class="en">Community</span>
|
||||||
<span class="de"></span>
|
<span style="display:none" class="de"></span>
|
||||||
<span class="es">Comunidad</span>
|
<span style="display:none" class="es">Comunidad</span>
|
||||||
<span class="fr">Communauté</span>
|
<span style="display:none" class="fr">Communauté</span>
|
||||||
<span class="it"></span>
|
<span style="display:none" class="it"></span>
|
||||||
<span class="ja">コミュニティ</span>
|
<span style="display:none" class="ja">コミュニティ</span>
|
||||||
<span class="zh-CN">社区</span>
|
<span style="display:none" class="zh-CN">社区</span>
|
||||||
<span class="zh-TW">社群</span>
|
<span style="display:none" class="zh-TW">社群</span>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
</a></li>
|
</a></li>
|
||||||
|
|
||||||
|
@@ -33,28 +33,29 @@
|
|||||||
<div class="g-unit" id="doc-content" >
|
<div class="g-unit" id="doc-content" >
|
||||||
<div id="jd-header" class="guide-header" >
|
<div id="jd-header" class="guide-header" >
|
||||||
<span class="crumb"> </span>
|
<span class="crumb"> </span>
|
||||||
<h1><?cs if:android.whichdoc == "online" ?>Download <?cs /if ?><?cs var:page.title ?></h1>
|
<h1><?cs if:android.whichdoc == "online" ?>Download the <?cs /if ?><?cs var:page.title ?></h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="jd-content">
|
<div id="jd-content">
|
||||||
<p><em><?cs
|
<?cs
|
||||||
if:ndk ?><?cs
|
if:ndk ?><p><em><?cs
|
||||||
var:ndk.date ?><?cs
|
var:ndk.date ?></em></p><?cs
|
||||||
else ?><?cs
|
else ?><?cs
|
||||||
var:sdk.date ?><?cs
|
if:android.whichdoc == "online" ?><p><em><?cs
|
||||||
/if ?></em>
|
var:sdk.date ?></em></p><?cs
|
||||||
</p>
|
/if ?><?cs
|
||||||
|
/if ?>
|
||||||
|
|
||||||
<?cs if:sdk.not_latest_version ?>
|
<?cs if:sdk.not_latest_version ?>
|
||||||
<div class="special">
|
<div class="special">
|
||||||
<p><strong>This is NOT the current Android SDK release.</strong></p>
|
<p><strong>This is NOT the current Android SDK release.</strong></p>
|
||||||
<p><a href="/sdk/<?cs var:sdk.current ?>/index.html">Download the current Android SDK</a></p>
|
<p><a href="/sdk/index.html">Download the current Android SDK</a></p>
|
||||||
</div>
|
</div>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
|
|
||||||
<?cs if:android.whichdoc != "online" && !android.preview ?>
|
<?cs if:android.whichdoc != "online" && !android.preview ?>
|
||||||
|
|
||||||
<p>The sections below provide an overview of the SDK package. </p>
|
<!-- <p>The sections below provide an overview of how to install the SDK package. </p> -->
|
||||||
|
|
||||||
<?cs else ?>
|
<?cs else ?>
|
||||||
<?cs if:ndk ?>
|
<?cs if:ndk ?>
|
||||||
@@ -62,10 +63,10 @@
|
|||||||
<p>The Android NDK is a companion tool to the Android SDK that lets Android
|
<p>The Android NDK is a companion tool to the Android SDK that lets Android
|
||||||
application developers build performance-critical portions of their apps in
|
application developers build performance-critical portions of their apps in
|
||||||
native code. It is designed for use <em>only</em> in conjunction with the
|
native code. It is designed for use <em>only</em> in conjunction with the
|
||||||
Android SDK, so if you have not already installed the Android 1.5 SDK, please do
|
Android SDK, so if you have not already installed the latest Android SDK, please
|
||||||
so before downloading the NDK. Also, please read <a href="#overview">What is the
|
do so before downloading the NDK. Also, please read <a href="#overview">What is
|
||||||
Android NDK?</a> to get an understanding of what the NDK offers and whether it
|
the Android NDK?</a> to get an understanding of what the NDK offers and whether
|
||||||
will be useful to you.</p>
|
it will be useful to you.</p>
|
||||||
|
|
||||||
<p>Select the download package that is appropriate for your development
|
<p>Select the download package that is appropriate for your development
|
||||||
computer. </p>
|
computer. </p>
|
||||||
@@ -110,16 +111,49 @@ computer. </p>
|
|||||||
Android 1.6 and we are pleased to announce the availability of an early look
|
Android 1.6 and we are pleased to announce the availability of an early look
|
||||||
SDK to give you a head-start on developing applications for it. </p>
|
SDK to give you a head-start on developing applications for it. </p>
|
||||||
|
|
||||||
<p>The Android 1.6 platform includes a variety of improvements and new
|
<p>The Android <?cs var:sdk.preview.version ?> platform includes a variety of
|
||||||
features for users and developers. Additionally, the SDK itself introduces
|
improvements and new features for users and developers. Additionally, the SDK
|
||||||
several new capabilities that enable you to develop applications more
|
itself introduces several new capabilities that enable you to develop
|
||||||
efficiently. See the <a href="features.html">Android 1.6 Highlights</a>
|
applications more efficiently. See the <a href="features.html">Android <?cs
|
||||||
document for a list of highlights.</p>
|
var:sdk.preview.version ?> Platform Highlights</a> document for a list of
|
||||||
|
highlights.</p>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
|
<?cs # end if NDK ... the following is for the SDK ?>
|
||||||
|
|
||||||
|
<div class="toggle-content special">
|
||||||
|
<p>The Android SDK has changed! If you've worked with the Android SDK before,
|
||||||
|
you will notice several important differences:</p>
|
||||||
|
|
||||||
|
<div class="toggle-content-toggleme" style="display:none">
|
||||||
|
<ul style="padding-bottom:.0;">
|
||||||
|
<li style="margin-top:.5em">The SDK downloadable package includes <em>only</em>
|
||||||
|
the latest version of the Android SDK Tools.</li>
|
||||||
|
<li>Once you've installed the SDK, you now use the Android SDK and AVD Manager
|
||||||
|
to download all of the SDK components that you need, such as Android platforms,
|
||||||
|
SDK add-ons, tools, and documentation. </li>
|
||||||
|
<li>The new approach is modular — you can install only the components you
|
||||||
|
need and update any or all components without affecting other parts of your
|
||||||
|
development environment.</li>
|
||||||
|
<li>In short, once you've installed the new SDK, you will not need to download
|
||||||
|
an SDK package again. Instead, you will use the Android SDK and AVD Manager to
|
||||||
|
keep your development environment up-to-date. </li>
|
||||||
|
</ul>
|
||||||
|
<p style="margin-top:0">If you are currently using the Android 1.6 SDK, you
|
||||||
|
do not need to install the new SDK, because your existing SDK already
|
||||||
|
includes the Android SDK and AVD Manager tool. To develop against Android
|
||||||
|
2.0, for example, you can just download the Android 2.0 platform (and
|
||||||
|
updated SDK Tools) into your existing SDK. Refer to <a
|
||||||
|
href="adding-components.html">Adding SDK Components</a>.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a href='#' class='toggle-content-button show' onclick="toggleContent(this);return false;">
|
||||||
|
<span>show more</span><span style='display:none'>show less</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>If you are new to the Android SDK, please read the <a href="#quickstart">Quick Start</a>,
|
||||||
|
below, for an overview of how to install and set up the SDK.</p>
|
||||||
|
|
||||||
<p>Before downloading, please read the <a href="requirements.html">
|
|
||||||
System Requirements</a> document. As you start the download, you will also need to review and agree to
|
|
||||||
the Terms and Conditions that govern the use of the Android SDK. </p>
|
|
||||||
|
|
||||||
<table class="download">
|
<table class="download">
|
||||||
<tr>
|
<tr>
|
||||||
@@ -156,7 +190,7 @@ the Terms and Conditions that govern the use of the Android SDK. </p>
|
|||||||
<tr class="alt-color">
|
<tr class="alt-color">
|
||||||
<td>ADT Plugin for Eclipse <?cs var:adt.zip_version ?></td>
|
<td>ADT Plugin for Eclipse <?cs var:adt.zip_version ?></td>
|
||||||
<td>
|
<td>
|
||||||
<a href="<?cs var:toroot ?>sdk/download.html?v=<?cs var:adt.zip_download ?>"><?cs var:adt.zip_download ?></a>
|
<a href="http://dl.google.com/android/<?cs var:adt.zip_download ?>"><?cs var:adt.zip_download ?></a>
|
||||||
</td>
|
</td>
|
||||||
<td><?cs var:adt.zip_bytes ?> bytes</td>
|
<td><?cs var:adt.zip_bytes ?> bytes</td>
|
||||||
<td><?cs var:adt.zip_checksum ?></td>
|
<td><?cs var:adt.zip_checksum ?></td>
|
||||||
@@ -170,14 +204,17 @@ the Terms and Conditions that govern the use of the Android SDK. </p>
|
|||||||
|
|
||||||
<?cs if:android.whichdoc != "online" && sdk.preview ?>
|
<?cs if:android.whichdoc != "online" && sdk.preview ?>
|
||||||
<p>Welcome developers! The next release of the Android platform will be
|
<p>Welcome developers! The next release of the Android platform will be
|
||||||
Android 1.6 and we are pleased to announce the availability of an early look SDK
|
Android <?cs var:sdk.preview.version ?> and we are pleased to announce the
|
||||||
to give you a head-start on developing applications for it. </p>
|
availability of an early look SDK to give you a head-start on developing
|
||||||
|
applications for it. </p>
|
||||||
|
|
||||||
<p>The Android 1.6 platform includes a variety of improvements and new features
|
<p>The Android <?cs var:sdk.preview.version ?> platform includes a variety of
|
||||||
for users and developers. Additionally, the SDK itself introduces several new
|
improvements and new features for users and developers. Additionally, the SDK
|
||||||
capabilities that enable you to develop applications more efficiently.
|
itself introduces several new capabilities that enable you to develop
|
||||||
See the <a href="http://developer.android.com/sdk/preview/features.html">
|
applications more efficiently. See the <a
|
||||||
Android 1.6 Highlights</a> document for a list of highlights.</p>
|
href="http://developer.android.com/sdk/preview/features.html">Android
|
||||||
|
<?cs var:sdk.preview.version ?> Highlights</a> document for a list of
|
||||||
|
highlights.</p>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
|
|
||||||
<?cs call:tag_list(root.descr) ?>
|
<?cs call:tag_list(root.descr) ?>
|
||||||
|
@@ -48,11 +48,12 @@ a:visited code {
|
|||||||
}
|
}
|
||||||
|
|
||||||
input, select,
|
input, select,
|
||||||
textarea, option {
|
textarea, option, label {
|
||||||
font-family:inherit;
|
font-family:inherit;
|
||||||
font-size:inherit;
|
font-size:inherit;
|
||||||
padding:0;
|
padding:0;
|
||||||
margin:0;
|
margin:0;
|
||||||
|
vertical-align:middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
option {
|
option {
|
||||||
@@ -81,6 +82,7 @@ pre {
|
|||||||
padding:10px;
|
padding:10px;
|
||||||
margin:0 0 1em 1em;
|
margin:0 0 1em 1em;
|
||||||
overflow:auto;
|
overflow:auto;
|
||||||
|
line-height:inherit; /* fixes vertical scrolling in webkit */
|
||||||
}
|
}
|
||||||
|
|
||||||
h1,h2,h3,h4,h5 {
|
h1,h2,h3,h4,h5 {
|
||||||
@@ -194,7 +196,7 @@ hr.blue {
|
|||||||
height: 114px;
|
height: 114px;
|
||||||
position:relative;
|
position:relative;
|
||||||
z-index:100;
|
z-index:100;
|
||||||
min-width:576px;
|
min-width:675px; /* min width for the tabs, before they wrap */
|
||||||
padding:0 10px;
|
padding:0 10px;
|
||||||
border-bottom:3px solid #94b922;
|
border-bottom:3px solid #94b922;
|
||||||
}
|
}
|
||||||
|
@@ -339,9 +339,12 @@ links to summary tables) */
|
|||||||
}
|
}
|
||||||
|
|
||||||
#api-level-toggle {
|
#api-level-toggle {
|
||||||
float:right;
|
|
||||||
padding:0 10px;
|
padding:0 10px;
|
||||||
font-size:11px;
|
font-size:11px;
|
||||||
|
float:right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#api-level-toggle label.disabled {
|
||||||
color:#999;
|
color:#999;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -660,7 +663,27 @@ h5.jd-tagtitle {
|
|||||||
div.special {
|
div.special {
|
||||||
padding: .5em 1em 1em 1em;
|
padding: .5em 1em 1em 1em;
|
||||||
margin: 0 0 1em;
|
margin: 0 0 1em;
|
||||||
background-color: #ddf0f2;
|
background-color: #DAF3FC;
|
||||||
|
border:1px solid #d3ecf5;
|
||||||
|
border-radius:5px;
|
||||||
|
-moz-border-radius:5px;
|
||||||
|
-webkit-border-radius:5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-content-toggleme {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-content-button {
|
||||||
|
font-size:.9em;
|
||||||
|
line-height:.9em;
|
||||||
|
text-decoration:none;
|
||||||
|
position:relative;
|
||||||
|
top:5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-content-button:hover {
|
||||||
|
text-decoration:underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.special p {
|
div.special p {
|
||||||
@@ -751,6 +774,8 @@ ul.no-style {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: red;
|
color: red;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
vertical-align:top;
|
||||||
|
line-height:.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre.classic {
|
pre.classic {
|
||||||
|
@@ -10,6 +10,7 @@ var NAV_PREF_PANELS = "panels";
|
|||||||
var nav_pref;
|
var nav_pref;
|
||||||
var toRoot;
|
var toRoot;
|
||||||
var isMobile = false; // true if mobile, so we can adjust some layout
|
var isMobile = false; // true if mobile, so we can adjust some layout
|
||||||
|
var isIE6 = false; // true if IE6
|
||||||
|
|
||||||
function addLoadEvent(newfun) {
|
function addLoadEvent(newfun) {
|
||||||
var current = window.onload;
|
var current = window.onload;
|
||||||
@@ -24,16 +25,23 @@ function addLoadEvent(newfun) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var agent = navigator['userAgent'];
|
var agent = navigator['userAgent'];
|
||||||
|
// If a mobile phone, set flag and do mobile setup
|
||||||
if ((agent.indexOf("Mobile") != -1) ||
|
if ((agent.indexOf("Mobile") != -1) ||
|
||||||
(agent.indexOf("BlackBerry") != -1) ||
|
(agent.indexOf("BlackBerry") != -1) ||
|
||||||
(agent.indexOf("Mini") != -1)) {
|
(agent.indexOf("Mini") != -1)) {
|
||||||
isMobile = true;
|
isMobile = true;
|
||||||
addLoadEvent(mobileSetup);
|
addLoadEvent(mobileSetup);
|
||||||
}
|
// If not a mobile browser, set the onresize event for IE6, and others
|
||||||
|
} else if (agent.indexOf("MSIE 6.0") != -1) {
|
||||||
|
isIE6 = true;
|
||||||
addLoadEvent(function() {
|
addLoadEvent(function() {
|
||||||
window.onresize = resizeAll;
|
window.onresize = resizeAll;
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
addLoadEvent(function() {
|
||||||
|
window.onresize = resizeHeight;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function mobileSetup() {
|
function mobileSetup() {
|
||||||
$("body").css({'overflow':'auto'});
|
$("body").css({'overflow':'auto'});
|
||||||
@@ -50,7 +58,7 @@ addLoadEvent( function() {
|
|||||||
var lists = document.createElement("script");
|
var lists = document.createElement("script");
|
||||||
lists.setAttribute("type","text/javascript");
|
lists.setAttribute("type","text/javascript");
|
||||||
lists.setAttribute("src", toRoot+"reference/lists.js");
|
lists.setAttribute("src", toRoot+"reference/lists.js");
|
||||||
$("head").append($(lists));
|
document.getElementsByTagName("head")[0].appendChild(lists);
|
||||||
} );
|
} );
|
||||||
|
|
||||||
function setToRoot(root) {
|
function setToRoot(root) {
|
||||||
@@ -60,8 +68,12 @@ function setToRoot(root) {
|
|||||||
|
|
||||||
function restoreWidth(navWidth) {
|
function restoreWidth(navWidth) {
|
||||||
var windowWidth = $(window).width() + "px";
|
var windowWidth = $(window).width() + "px";
|
||||||
content.css({marginLeft:parseInt(navWidth) + 6 + "px", //account for 6px-wide handle-bar
|
content.css({marginLeft:parseInt(navWidth) + 6 + "px"}); //account for 6px-wide handle-bar
|
||||||
width:parseInt(windowWidth) - parseInt(navWidth) - 6 + "px"});
|
|
||||||
|
if (isIE6) {
|
||||||
|
content.css({width:parseInt(windowWidth) - parseInt(navWidth) - 6 + "px"}); // necessary in order for scrollbars to be visible
|
||||||
|
}
|
||||||
|
|
||||||
sidenav.css({width:navWidth});
|
sidenav.css({width:navWidth});
|
||||||
resizePackagesNav.css({width:navWidth});
|
resizePackagesNav.css({width:navWidth});
|
||||||
classesNav.css({width:navWidth});
|
classesNav.css({width:navWidth});
|
||||||
@@ -99,7 +111,7 @@ function readCookie(cookie) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function writeCookie(cookie, val, section, expiration) {
|
function writeCookie(cookie, val, section, expiration) {
|
||||||
if (!val) return;
|
if (val==undefined) return;
|
||||||
section = section == null ? "_" : "_"+section+"_";
|
section = section == null ? "_" : "_"+section+"_";
|
||||||
if (expiration == null) {
|
if (expiration == null) {
|
||||||
var date = new Date();
|
var date = new Date();
|
||||||
@@ -124,7 +136,7 @@ function init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isMobile) {
|
if (!isMobile) {
|
||||||
$("#resize-packages-nav").resizable({handles: "s", resize: function(e, ui) { resizeHeight(); } });
|
$("#resize-packages-nav").resizable({handles: "s", resize: function(e, ui) { resizePackagesHeight(); } });
|
||||||
$(".side-nav-resizable").resizable({handles: "e", resize: function(e, ui) { resizeWidth(); } });
|
$(".side-nav-resizable").resizable({handles: "e", resize: function(e, ui) { resizeWidth(); } });
|
||||||
var cookieWidth = readCookie(cookiePath+'width');
|
var cookieWidth = readCookie(cookiePath+'width');
|
||||||
var cookieHeight = readCookie(cookiePath+'height');
|
var cookieHeight = readCookie(cookiePath+'height');
|
||||||
@@ -156,8 +168,8 @@ function highlightNav(fullPageName) {
|
|||||||
var htmlPos = fullPageName.lastIndexOf(".html", fullPageName.length);
|
var htmlPos = fullPageName.lastIndexOf(".html", fullPageName.length);
|
||||||
var pathPageName = fullPageName.slice(firstSlashPos, htmlPos + 5);
|
var pathPageName = fullPageName.slice(firstSlashPos, htmlPos + 5);
|
||||||
var link = $("#devdoc-nav a[href$='"+ pathPageName+"']");
|
var link = $("#devdoc-nav a[href$='"+ pathPageName+"']");
|
||||||
if ((link.length == 0) && ((fullPageName.indexOf("/guide/") != -1) || (fullPageName.indexOf("/sdk/") != -1))) {
|
if ((link.length == 0) && (fullPageName.indexOf("/guide/") != -1)) {
|
||||||
// if there's no match, then let's backstep through the directory until we find an index.html page that matches our ancestor directories (only for dev guide and sdk)
|
// if there's no match, then let's backstep through the directory until we find an index.html page that matches our ancestor directories (only for dev guide)
|
||||||
lastBackstep = pathPageName.lastIndexOf("/");
|
lastBackstep = pathPageName.lastIndexOf("/");
|
||||||
while (link.length == 0) {
|
while (link.length == 0) {
|
||||||
backstepDirectory = pathPageName.lastIndexOf("/", lastBackstep);
|
backstepDirectory = pathPageName.lastIndexOf("/", lastBackstep);
|
||||||
@@ -174,23 +186,46 @@ function highlightNav(fullPageName) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function resizeHeight() {
|
/* Resize the height of the nav panels in the reference,
|
||||||
|
* and save the new size to a cookie */
|
||||||
|
function resizePackagesHeight() {
|
||||||
var windowHeight = ($(window).height() - HEADER_HEIGHT);
|
var windowHeight = ($(window).height() - HEADER_HEIGHT);
|
||||||
var swapperHeight = windowHeight - 13;
|
var swapperHeight = windowHeight - 13; // move 13px for swapper link at the bottom
|
||||||
$("#swapper").css({height:swapperHeight + "px"});
|
|
||||||
sidenav.css({height:windowHeight + "px"});
|
|
||||||
content.css({height:windowHeight + "px"});
|
|
||||||
resizePackagesNav.css({maxHeight:swapperHeight + "px"});
|
resizePackagesNav.css({maxHeight:swapperHeight + "px"});
|
||||||
classesNav.css({height:swapperHeight - parseInt(resizePackagesNav.css("height")) + "px"});
|
classesNav.css({height:swapperHeight - parseInt(resizePackagesNav.css("height")) + "px"});
|
||||||
|
|
||||||
|
$("#swapper").css({height:swapperHeight + "px"});
|
||||||
$("#packages-nav").css({height:parseInt(resizePackagesNav.css("height")) - 6 + "px"}); //move 6px for handle
|
$("#packages-nav").css({height:parseInt(resizePackagesNav.css("height")) - 6 + "px"}); //move 6px for handle
|
||||||
devdocNav.css({height:sidenav.css("height")});
|
|
||||||
$("#nav-tree").css({height:swapperHeight + "px"});
|
|
||||||
|
|
||||||
var basePath = getBaseUri(location.pathname);
|
var basePath = getBaseUri(location.pathname);
|
||||||
var section = basePath.substring(1,basePath.indexOf("/",1));
|
var section = basePath.substring(1,basePath.indexOf("/",1));
|
||||||
writeCookie("height", resizePackagesNav.css("height"), section, null);
|
writeCookie("height", resizePackagesNav.css("height"), section, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Resize the height of the side-nav and doc-content divs,
|
||||||
|
* which creates the frame effect */
|
||||||
|
function resizeHeight() {
|
||||||
|
// Get the window height and always resize the doc-content and side-nav divs
|
||||||
|
var windowHeight = ($(window).height() - HEADER_HEIGHT);
|
||||||
|
content.css({height:windowHeight + "px"});
|
||||||
|
sidenav.css({height:windowHeight + "px"});
|
||||||
|
|
||||||
|
var href = location.href;
|
||||||
|
// If in the reference docs, also resize the "swapper", "classes-nav", and "nav-tree" divs
|
||||||
|
if (href.indexOf("/reference/") != -1) {
|
||||||
|
var swapperHeight = windowHeight - 13;
|
||||||
|
$("#swapper").css({height:swapperHeight + "px"});
|
||||||
|
$("#classes-nav").css({height:swapperHeight - parseInt(resizePackagesNav.css("height")) + "px"});
|
||||||
|
$("#nav-tree").css({height:swapperHeight + "px"});
|
||||||
|
|
||||||
|
// If in the dev guide docs, also resize the "devdoc-nav" div
|
||||||
|
} else if (href.indexOf("/guide/") != -1) {
|
||||||
|
$("#devdoc-nav").css({height:sidenav.css("height")});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resize the width of the "side-nav" and the left margin of the "doc-content" div,
|
||||||
|
* which creates the resizable side bar */
|
||||||
function resizeWidth() {
|
function resizeWidth() {
|
||||||
var windowWidth = $(window).width() + "px";
|
var windowWidth = $(window).width() + "px";
|
||||||
if (sidenav.length) {
|
if (sidenav.length) {
|
||||||
@@ -198,8 +233,12 @@ function resizeWidth() {
|
|||||||
} else {
|
} else {
|
||||||
var sidenavWidth = 0;
|
var sidenavWidth = 0;
|
||||||
}
|
}
|
||||||
content.css({marginLeft:parseInt(sidenavWidth) + 6 + "px", //account for 6px-wide handle-bar
|
content.css({marginLeft:parseInt(sidenavWidth) + 6 + "px"}); //account for 6px-wide handle-bar
|
||||||
width:parseInt(windowWidth) - parseInt(sidenavWidth) - 6 + "px"});
|
|
||||||
|
if (isIE6) {
|
||||||
|
content.css({width:parseInt(windowWidth) - parseInt(sidenavWidth) - 6 + "px"}); // necessary in order to for scrollbars to be visible
|
||||||
|
}
|
||||||
|
|
||||||
resizePackagesNav.css({width:sidenavWidth});
|
resizePackagesNav.css({width:sidenavWidth});
|
||||||
classesNav.css({width:sidenavWidth});
|
classesNav.css({width:sidenavWidth});
|
||||||
$("#packages-nav").css({width:sidenavWidth});
|
$("#packages-nav").css({width:sidenavWidth});
|
||||||
@@ -209,14 +248,13 @@ function resizeWidth() {
|
|||||||
writeCookie("width", sidenavWidth, section, null);
|
writeCookie("width", sidenavWidth, section, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For IE6 only,
|
||||||
|
* because it can't properly perform auto width for "doc-content" div,
|
||||||
|
* avoiding this for all browsers provides better performance */
|
||||||
function resizeAll() {
|
function resizeAll() {
|
||||||
if (!isMobile) {
|
|
||||||
resizeHeight();
|
resizeHeight();
|
||||||
if ($(".side-nav-resizable").length) {
|
|
||||||
resizeWidth();
|
resizeWidth();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBaseUri(uri) {
|
function getBaseUri(uri) {
|
||||||
var intlUrl = (uri.substring(0,6) == "/intl/");
|
var intlUrl = (uri.substring(0,6) == "/intl/");
|
||||||
@@ -448,3 +486,18 @@ function getLangPref() {
|
|||||||
}
|
}
|
||||||
return (lang != 0) ? lang : 'en';
|
return (lang != 0) ? lang : 'en';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function toggleContent(obj) {
|
||||||
|
var button = $(obj);
|
||||||
|
var div = $(obj.parentNode);
|
||||||
|
var toggleMe = $(".toggle-content-toggleme",div);
|
||||||
|
if (button.hasClass("show")) {
|
||||||
|
toggleMe.slideDown();
|
||||||
|
button.removeClass("show").addClass("hide");
|
||||||
|
} else {
|
||||||
|
toggleMe.slideUp();
|
||||||
|
button.removeClass("hide").addClass("show");
|
||||||
|
}
|
||||||
|
$("span", button).toggle();
|
||||||
|
}
|
||||||
|
@@ -1,21 +1,42 @@
|
|||||||
|
|
||||||
/* API LEVEL TOGGLE */
|
/* API LEVEL TOGGLE */
|
||||||
addLoadEvent(changeApiLevel);
|
addLoadEvent(changeApiLevel);
|
||||||
|
|
||||||
|
var API_LEVEL_ENABLED_COOKIE = "api_level_enabled";
|
||||||
var API_LEVEL_COOKIE = "api_level";
|
var API_LEVEL_COOKIE = "api_level";
|
||||||
var minLevel = 1;
|
var minLevel = 1;
|
||||||
|
|
||||||
function buildApiLevelToggle() {
|
function toggleApiLevelSelector(checkbox) {
|
||||||
var maxLevel = SINCE_DATA.length;
|
var date = new Date();
|
||||||
var userApiLevel = readCookie(API_LEVEL_COOKIE);
|
date.setTime(date.getTime()+(10*365*24*60*60*1000)); // keep this for 10 years
|
||||||
|
var expiration = date.toGMTString();
|
||||||
if (userApiLevel != 0) {
|
if (checkbox.checked) {
|
||||||
selectedLevel = userApiLevel;
|
$("#apiLevelSelector").removeAttr("disabled");
|
||||||
|
$("#api-level-toggle label").removeClass("disabled");
|
||||||
|
writeCookie(API_LEVEL_ENABLED_COOKIE, 1, null, expiration);
|
||||||
} else {
|
} else {
|
||||||
selectedLevel = maxLevel;
|
$("#apiLevelSelector").attr("disabled","disabled");
|
||||||
|
$("#api-level-toggle label").addClass("disabled");
|
||||||
|
writeCookie(API_LEVEL_ENABLED_COOKIE, 0, null, expiration);
|
||||||
|
}
|
||||||
|
changeApiLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildApiLevelSelector() {
|
||||||
|
var maxLevel = SINCE_DATA.length;
|
||||||
|
var userApiLevelEnabled = readCookie(API_LEVEL_ENABLED_COOKIE);
|
||||||
|
var userApiLevel = readCookie(API_LEVEL_COOKIE);
|
||||||
|
userApiLevel = userApiLevel == 0 ? maxLevel : userApiLevel; // If there's no cookie (zero), use the max by default
|
||||||
|
|
||||||
|
if (userApiLevelEnabled == 0) {
|
||||||
|
$("#apiLevelSelector").attr("disabled","disabled");
|
||||||
|
} else {
|
||||||
|
$("#apiLevelCheckbox").attr("checked","checked");
|
||||||
|
$("#api-level-toggle label").removeClass("disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
minLevel = $("body").attr("class");
|
minLevel = $("body").attr("class");
|
||||||
var select = $("#apiLevelControl").html("").change(changeApiLevel);
|
var select = $("#apiLevelSelector").html("").change(changeApiLevel);
|
||||||
for (var i = maxLevel-1; i >= 0; i--) {
|
for (var i = maxLevel-1; i >= 0; i--) {
|
||||||
var option = $("<option />").attr("value",""+SINCE_DATA[i]).append(""+SINCE_DATA[i]);
|
var option = $("<option />").attr("value",""+SINCE_DATA[i]).append(""+SINCE_DATA[i]);
|
||||||
// if (SINCE_DATA[i] < minLevel) option.addClass("absent"); // always false for strings (codenames)
|
// if (SINCE_DATA[i] < minLevel) option.addClass("absent"); // always false for strings (codenames)
|
||||||
@@ -23,17 +44,26 @@ function buildApiLevelToggle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get the DOM element and use setAttribute cuz IE6 fails when using jquery .attr('selected',true)
|
// get the DOM element and use setAttribute cuz IE6 fails when using jquery .attr('selected',true)
|
||||||
var selectedLevelItem = $("#apiLevelControl option[value='"+selectedLevel+"']").get(0);
|
var selectedLevelItem = $("#apiLevelSelector option[value='"+userApiLevel+"']").get(0);
|
||||||
selectedLevelItem.setAttribute('selected',true);
|
selectedLevelItem.setAttribute('selected',true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeApiLevel() {
|
function changeApiLevel() {
|
||||||
var selectedLevel = $("#apiLevelControl option:selected").val();
|
var maxLevel = SINCE_DATA.length;
|
||||||
|
var userApiLevelEnabled = readCookie(API_LEVEL_ENABLED_COOKIE);
|
||||||
|
var selectedLevel = maxLevel;
|
||||||
|
|
||||||
|
if (userApiLevelEnabled == 0) {
|
||||||
|
toggleVisisbleApis(selectedLevel, "body");
|
||||||
|
} else {
|
||||||
|
selectedLevel = $("#apiLevelSelector option:selected").val();
|
||||||
toggleVisisbleApis(selectedLevel, "body");
|
toggleVisisbleApis(selectedLevel, "body");
|
||||||
|
|
||||||
var date = new Date();
|
var date = new Date();
|
||||||
date.setTime(date.getTime()+(50*365*24*60*60*1000)); // keep this for 50 years
|
date.setTime(date.getTime()+(10*365*24*60*60*1000)); // keep this for 10 years
|
||||||
writeCookie(API_LEVEL_COOKIE, selectedLevel, null, date);
|
var expiration = date.toGMTString();
|
||||||
|
writeCookie(API_LEVEL_COOKIE, selectedLevel, null, expiration);
|
||||||
|
}
|
||||||
|
|
||||||
if (selectedLevel < minLevel) {
|
if (selectedLevel < minLevel) {
|
||||||
var thing = ($("#jd-header").html().indexOf("package") != -1) ? "package" : "class";
|
var thing = ($("#jd-header").html().indexOf("package") != -1) ? "package" : "class";
|
||||||
@@ -156,7 +186,7 @@ function expand_node(me, node)
|
|||||||
node.expanded = true;
|
node.expanded = true;
|
||||||
|
|
||||||
// perform api level toggling because new nodes are new to the DOM
|
// perform api level toggling because new nodes are new to the DOM
|
||||||
var selectedLevel = $("#apiLevelControl option:selected").val();
|
var selectedLevel = $("#apiLevelSelector option:selected").val();
|
||||||
toggleVisisbleApis(selectedLevel, "#side-nav");
|
toggleVisisbleApis(selectedLevel, "#side-nav");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,7 +258,7 @@ function init_default_navtree(toroot) {
|
|||||||
init_navtree("nav-tree", toroot, NAVTREE_DATA);
|
init_navtree("nav-tree", toroot, NAVTREE_DATA);
|
||||||
|
|
||||||
// perform api level toggling because because the whole tree is new to the DOM
|
// perform api level toggling because because the whole tree is new to the DOM
|
||||||
var selectedLevel = $("#apiLevelControl option:selected").val();
|
var selectedLevel = $("#apiLevelSelector option:selected").val();
|
||||||
toggleVisisbleApis(selectedLevel, "#side-nav");
|
toggleVisisbleApis(selectedLevel, "#side-nav");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
tools/droiddoc/templates/assets/images/home/donut-android.png
Normal file → Executable file
BIN
tools/droiddoc/templates/assets/images/home/donut-android.png
Normal file → Executable file
Binary file not shown.
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 9.2 KiB |
BIN
tools/droiddoc/templates/assets/images/home/eclair-android.png
Normal file
BIN
tools/droiddoc/templates/assets/images/home/eclair-android.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
@@ -168,6 +168,6 @@ function search_focus_changed(obj, focused)
|
|||||||
|
|
||||||
function submit_search() {
|
function submit_search() {
|
||||||
var query = document.getElementById('search_autocomplete').value;
|
var query = document.getElementById('search_autocomplete').value;
|
||||||
document.location = toRoot + 'search.html#q=' + query; // toRoot is initialized in android-developer-docs.js
|
document.location = toRoot + 'search.html#q=' + query + '&t=0';
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -188,7 +188,7 @@ Summary:
|
|||||||
|
|
||||||
<?cs # summary macros ?>
|
<?cs # summary macros ?>
|
||||||
|
|
||||||
<?cs def:write_method_summary(methods) ?>
|
<?cs def:write_method_summary(methods, included) ?>
|
||||||
<?cs set:count = #1 ?>
|
<?cs set:count = #1 ?>
|
||||||
<?cs each:method = methods ?>
|
<?cs each:method = methods ?>
|
||||||
<?cs # The apilevel-N class MUST BE LAST in the sequence of class names ?>
|
<?cs # The apilevel-N class MUST BE LAST in the sequence of class names ?>
|
||||||
@@ -202,8 +202,7 @@ Summary:
|
|||||||
<?cs call:type_link(method.returnType) ?></nobr>
|
<?cs call:type_link(method.returnType) ?></nobr>
|
||||||
</td>
|
</td>
|
||||||
<td class="jd-linkcol" width="100%"><nobr>
|
<td class="jd-linkcol" width="100%"><nobr>
|
||||||
<span class="sympad"><a href="<?cs var:toroot ?><?cs var:method.href ?>">
|
<span class="sympad"><?cs call:cond_link(method.name, toroot, method.href, included) ?></span>(<?cs call:parameter_list(method.params) ?>)</nobr>
|
||||||
<?cs var:method.name ?></a></span>(<?cs call:parameter_list(method.params) ?>)</nobr>
|
|
||||||
<?cs if:subcount(method.shortDescr) || subcount(method.deprecated) ?>
|
<?cs if:subcount(method.shortDescr) || subcount(method.deprecated) ?>
|
||||||
<div class="jd-descrdiv"><?cs call:short_descr(method) ?></div>
|
<div class="jd-descrdiv"><?cs call:short_descr(method) ?></div>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
@@ -212,7 +211,7 @@ Summary:
|
|||||||
<?cs /each ?>
|
<?cs /each ?>
|
||||||
<?cs /def ?>
|
<?cs /def ?>
|
||||||
|
|
||||||
<?cs def:write_field_summary(fields) ?>
|
<?cs def:write_field_summary(fields, included) ?>
|
||||||
<?cs set:count = #1 ?>
|
<?cs set:count = #1 ?>
|
||||||
<?cs each:field=fields ?>
|
<?cs each:field=fields ?>
|
||||||
<tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:field.since ?>" >
|
<tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:field.since ?>" >
|
||||||
@@ -221,26 +220,26 @@ Summary:
|
|||||||
<?cs var:field.static ?>
|
<?cs var:field.static ?>
|
||||||
<?cs var:field.final ?>
|
<?cs var:field.final ?>
|
||||||
<?cs call:type_link(field.type) ?></nobr></td>
|
<?cs call:type_link(field.type) ?></nobr></td>
|
||||||
<td class="jd-linkcol"><a href="<?cs var:toroot ?><?cs var:field.href ?>"><?cs var:field.name ?></a></td>
|
<td class="jd-linkcol"><?cs call:cond_link(field.name, toroot, field.href, included) ?></td>
|
||||||
<td class="jd-descrcol" width="100%"><?cs call:short_descr(field) ?></td>
|
<td class="jd-descrcol" width="100%"><?cs call:short_descr(field) ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?cs set:count = count + #1 ?>
|
<?cs set:count = count + #1 ?>
|
||||||
<?cs /each ?>
|
<?cs /each ?>
|
||||||
<?cs /def ?>
|
<?cs /def ?>
|
||||||
|
|
||||||
<?cs def:write_constant_summary(fields) ?>
|
<?cs def:write_constant_summary(fields, included) ?>
|
||||||
<?cs set:count = #1 ?>
|
<?cs set:count = #1 ?>
|
||||||
<?cs each:field=fields ?>
|
<?cs each:field=fields ?>
|
||||||
<tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:field.since ?>" >
|
<tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:field.since ?>" >
|
||||||
<td class="jd-typecol"><?cs call:type_link(field.type) ?></td>
|
<td class="jd-typecol"><?cs call:type_link(field.type) ?></td>
|
||||||
<td class="jd-linkcol"><a href="<?cs var:toroot ?><?cs var:field.href ?>"><?cs var:field.name ?></a></td>
|
<td class="jd-linkcol"><?cs call:cond_link(field.name, toroot, field.href, included) ?></td>
|
||||||
<td class="jd-descrcol" width="100%"><?cs call:short_descr(field) ?></td>
|
<td class="jd-descrcol" width="100%"><?cs call:short_descr(field) ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?cs set:count = count + #1 ?>
|
<?cs set:count = count + #1 ?>
|
||||||
<?cs /each ?>
|
<?cs /each ?>
|
||||||
<?cs /def ?>
|
<?cs /def ?>
|
||||||
|
|
||||||
<?cs def:write_attr_summary(attrs) ?>
|
<?cs def:write_attr_summary(attrs, included) ?>
|
||||||
<?cs set:count = #1 ?>
|
<?cs set:count = #1 ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td><nobr><em>Attribute Name</em></nobr></td>
|
<td><nobr><em>Attribute Name</em></nobr></td>
|
||||||
@@ -249,9 +248,9 @@ Summary:
|
|||||||
</tr>
|
</tr>
|
||||||
<?cs each:attr=attrs ?>
|
<?cs each:attr=attrs ?>
|
||||||
<tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:attr.since ?>" >
|
<tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:attr.since ?>" >
|
||||||
<td class="jd-linkcol"><a href="<?cs var:toroot ?><?cs var:attr.href ?>"><?cs var:attr.name ?></a></td>
|
<td class="jd-linkcol"><?cs if:included ?><a href="<?cs var:toroot ?><?cs var:attr.href ?>"><?cs /if ?><?cs var:attr.name ?><?cs if:included ?></a><?cs /if ?></td>
|
||||||
<td class="jd-linkcol"><?cs each:m=attr.methods ?>
|
<td class="jd-linkcol"><?cs each:m=attr.methods ?>
|
||||||
<a href="<?cs var:toroot ?><?cs var:m.href ?>"><?cs var:m.name ?></a>
|
<?cs call:cond_link(m.name, toroot, m.href, included) ?>
|
||||||
<?cs /each ?>
|
<?cs /each ?>
|
||||||
</td>
|
</td>
|
||||||
<td class="jd-descrcol" width="100%"><?cs call:short_descr(attr) ?> </td>
|
<td class="jd-descrcol" width="100%"><?cs call:short_descr(attr) ?> </td>
|
||||||
@@ -293,7 +292,7 @@ Summary:
|
|||||||
<?cs if:subcount(class.attrs) ?>
|
<?cs if:subcount(class.attrs) ?>
|
||||||
<!-- =========== FIELD SUMMARY =========== -->
|
<!-- =========== FIELD SUMMARY =========== -->
|
||||||
<table id="lattrs" class="jd-sumtable"><tr><th colspan="12">XML Attributes</th></tr>
|
<table id="lattrs" class="jd-sumtable"><tr><th colspan="12">XML Attributes</th></tr>
|
||||||
<?cs call:write_attr_summary(class.attrs) ?>
|
<?cs call:write_attr_summary(class.attrs, 1) ?>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
|
|
||||||
<?cs # if there are inherited attrs, write the table ?>
|
<?cs # if there are inherited attrs, write the table ?>
|
||||||
@@ -308,14 +307,14 @@ Summary:
|
|||||||
<tr class="api apilevel-<?cs var:cl.since ?>" >
|
<tr class="api apilevel-<?cs var:cl.since ?>" >
|
||||||
<td colspan="12">
|
<td colspan="12">
|
||||||
<?cs call:expando_trigger("inherited-attrs-"+cl.qualified, "closed") ?>From <?cs var:cl.kind ?>
|
<?cs call:expando_trigger("inherited-attrs-"+cl.qualified, "closed") ?>From <?cs var:cl.kind ?>
|
||||||
<a href="<?cs var:toroot ?><?cs var:cl.link ?>"><?cs var:cl.qualified ?></a>
|
<?cs call:cond_link(cl.qualified, toroot, cl.link, cl.included) ?>
|
||||||
<div id="inherited-attrs-<?cs var:cl.qualified ?>">
|
<div id="inherited-attrs-<?cs var:cl.qualified ?>">
|
||||||
<div id="inherited-attrs-<?cs var:cl.qualified ?>-list"
|
<div id="inherited-attrs-<?cs var:cl.qualified ?>-list"
|
||||||
class="jd-inheritedlinks">
|
class="jd-inheritedlinks">
|
||||||
</div>
|
</div>
|
||||||
<div id="inherited-attrs-<?cs var:cl.qualified ?>-summary" style="display: none;">
|
<div id="inherited-attrs-<?cs var:cl.qualified ?>-summary" style="display: none;">
|
||||||
<table class="jd-sumtable-expando">
|
<table class="jd-sumtable-expando">
|
||||||
<?cs call:write_attr_summary(cl.attrs) ?></table>
|
<?cs call:write_attr_summary(cl.attrs, cl.included) ?></table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
@@ -332,7 +331,7 @@ Summary:
|
|||||||
<?cs each:field=class.enumConstants ?>
|
<?cs each:field=class.enumConstants ?>
|
||||||
<tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:field.since ?>" >
|
<tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:field.since ?>" >
|
||||||
<td class="jd-descrcol"><?cs call:type_link(field.type) ?> </td>
|
<td class="jd-descrcol"><?cs call:type_link(field.type) ?> </td>
|
||||||
<td class="jd-linkcol"><a href="<?cs var:toroot ?><?cs var:field.href ?>"><?cs var:field.name ?></a> </td>
|
<td class="jd-linkcol"><?cs call:cond_link(field.name, toroot, field.href, cl.included) ?> </td>
|
||||||
<td class="jd-descrcol" width="100%"><?cs call:short_descr(field) ?> </td>
|
<td class="jd-descrcol" width="100%"><?cs call:short_descr(field) ?> </td>
|
||||||
</tr>
|
</tr>
|
||||||
<?cs set:count = count + #1 ?>
|
<?cs set:count = count + #1 ?>
|
||||||
@@ -343,7 +342,7 @@ Summary:
|
|||||||
<?cs # this next line must be exactly like this to be parsed by eclipse ?>
|
<?cs # this next line must be exactly like this to be parsed by eclipse ?>
|
||||||
<!-- =========== ENUM CONSTANT SUMMARY =========== -->
|
<!-- =========== ENUM CONSTANT SUMMARY =========== -->
|
||||||
<table id="constants" class="jd-sumtable"><tr><th colspan="12">Constants</th></tr>
|
<table id="constants" class="jd-sumtable"><tr><th colspan="12">Constants</th></tr>
|
||||||
<?cs call:write_constant_summary(class.constants) ?>
|
<?cs call:write_constant_summary(class.constants, 1) ?>
|
||||||
</table>
|
</table>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
|
|
||||||
@@ -359,14 +358,14 @@ Summary:
|
|||||||
<tr class="api apilevel-<?cs var:cl.since ?>" >
|
<tr class="api apilevel-<?cs var:cl.since ?>" >
|
||||||
<td colspan="12">
|
<td colspan="12">
|
||||||
<?cs call:expando_trigger("inherited-constants-"+cl.qualified, "closed") ?>From <?cs var:cl.kind ?>
|
<?cs call:expando_trigger("inherited-constants-"+cl.qualified, "closed") ?>From <?cs var:cl.kind ?>
|
||||||
<a href="<?cs var:toroot ?><?cs var:cl.link ?>"><?cs var:cl.qualified ?></a>
|
<?cs call:cond_link(cl.qualified, toroot, cl.link, cl.included) ?>
|
||||||
<div id="inherited-constants-<?cs var:cl.qualified ?>">
|
<div id="inherited-constants-<?cs var:cl.qualified ?>">
|
||||||
<div id="inherited-constants-<?cs var:cl.qualified ?>-list"
|
<div id="inherited-constants-<?cs var:cl.qualified ?>-list"
|
||||||
class="jd-inheritedlinks">
|
class="jd-inheritedlinks">
|
||||||
</div>
|
</div>
|
||||||
<div id="inherited-constants-<?cs var:cl.qualified ?>-summary" style="display: none;">
|
<div id="inherited-constants-<?cs var:cl.qualified ?>-summary" style="display: none;">
|
||||||
<table class="jd-sumtable-expando">
|
<table class="jd-sumtable-expando">
|
||||||
<?cs call:write_constant_summary(cl.constants) ?></table>
|
<?cs call:write_constant_summary(cl.constants, cl.included) ?></table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
@@ -379,7 +378,7 @@ Summary:
|
|||||||
<?cs # this next line must be exactly like this to be parsed by eclipse ?>
|
<?cs # this next line must be exactly like this to be parsed by eclipse ?>
|
||||||
<!-- =========== FIELD SUMMARY =========== -->
|
<!-- =========== FIELD SUMMARY =========== -->
|
||||||
<table id="lfields" class="jd-sumtable"><tr><th colspan="12">Fields</th></tr>
|
<table id="lfields" class="jd-sumtable"><tr><th colspan="12">Fields</th></tr>
|
||||||
<?cs call:write_field_summary(class.fields) ?>
|
<?cs call:write_field_summary(class.fields, 1) ?>
|
||||||
</table>
|
</table>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
|
|
||||||
@@ -395,14 +394,14 @@ Summary:
|
|||||||
<tr class="api apilevel-<?cs var:cl.since ?>" >
|
<tr class="api apilevel-<?cs var:cl.since ?>" >
|
||||||
<td colspan="12">
|
<td colspan="12">
|
||||||
<?cs call:expando_trigger("inherited-fields-"+cl.qualified, "closed") ?>From <?cs var:cl.kind ?>
|
<?cs call:expando_trigger("inherited-fields-"+cl.qualified, "closed") ?>From <?cs var:cl.kind ?>
|
||||||
<a href="<?cs var:toroot ?><?cs var:cl.link ?>"><?cs var:cl.qualified ?></a>
|
<?cs call:cond_link(cl.qualified, toroot, cl.link, cl.included) ?>
|
||||||
<div id="inherited-fields-<?cs var:cl.qualified ?>">
|
<div id="inherited-fields-<?cs var:cl.qualified ?>">
|
||||||
<div id="inherited-fields-<?cs var:cl.qualified ?>-list"
|
<div id="inherited-fields-<?cs var:cl.qualified ?>-list"
|
||||||
class="jd-inheritedlinks">
|
class="jd-inheritedlinks">
|
||||||
</div>
|
</div>
|
||||||
<div id="inherited-fields-<?cs var:cl.qualified ?>-summary" style="display: none;">
|
<div id="inherited-fields-<?cs var:cl.qualified ?>-summary" style="display: none;">
|
||||||
<table class="jd-sumtable-expando">
|
<table class="jd-sumtable-expando">
|
||||||
<?cs call:write_field_summary(cl.fields) ?></table>
|
<?cs call:write_field_summary(cl.fields, cl.included) ?></table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
@@ -415,7 +414,7 @@ Summary:
|
|||||||
<?cs # this next line must be exactly like this to be parsed by eclipse ?>
|
<?cs # this next line must be exactly like this to be parsed by eclipse ?>
|
||||||
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
|
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
|
||||||
<table id="pubctors" class="jd-sumtable"><tr><th colspan="12">Public Constructors</th></tr>
|
<table id="pubctors" class="jd-sumtable"><tr><th colspan="12">Public Constructors</th></tr>
|
||||||
<?cs call:write_method_summary(class.ctors.public) ?>
|
<?cs call:write_method_summary(class.ctors.public, 1) ?>
|
||||||
</table>
|
</table>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
|
|
||||||
@@ -423,7 +422,7 @@ Summary:
|
|||||||
<?cs # this next line must be exactly like this to be parsed by eclipse ?>
|
<?cs # this next line must be exactly like this to be parsed by eclipse ?>
|
||||||
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
|
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
|
||||||
<table id="proctors" class="jd-sumtable"><tr><th colspan="12">Protected Constructors</th></tr>
|
<table id="proctors" class="jd-sumtable"><tr><th colspan="12">Protected Constructors</th></tr>
|
||||||
<?cs call:write_method_summary(class.ctors.protected) ?>
|
<?cs call:write_method_summary(class.ctors.protected, 1) ?>
|
||||||
</table>
|
</table>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
|
|
||||||
@@ -431,7 +430,7 @@ Summary:
|
|||||||
<?cs # this next line must be exactly like this to be parsed by eclipse ?>
|
<?cs # this next line must be exactly like this to be parsed by eclipse ?>
|
||||||
<!-- ========== METHOD SUMMARY =========== -->
|
<!-- ========== METHOD SUMMARY =========== -->
|
||||||
<table id="pubmethods" class="jd-sumtable"><tr><th colspan="12">Public Methods</th></tr>
|
<table id="pubmethods" class="jd-sumtable"><tr><th colspan="12">Public Methods</th></tr>
|
||||||
<?cs call:write_method_summary(class.methods.public) ?>
|
<?cs call:write_method_summary(class.methods.public, 1) ?>
|
||||||
</table>
|
</table>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
|
|
||||||
@@ -439,7 +438,7 @@ Summary:
|
|||||||
<?cs # this next line must be exactly like this to be parsed by eclipse ?>
|
<?cs # this next line must be exactly like this to be parsed by eclipse ?>
|
||||||
<!-- ========== METHOD SUMMARY =========== -->
|
<!-- ========== METHOD SUMMARY =========== -->
|
||||||
<table id="promethods" class="jd-sumtable"><tr><th colspan="12">Protected Methods</th></tr>
|
<table id="promethods" class="jd-sumtable"><tr><th colspan="12">Protected Methods</th></tr>
|
||||||
<?cs call:write_method_summary(class.methods.protected) ?>
|
<?cs call:write_method_summary(class.methods.protected, 1) ?>
|
||||||
</table>
|
</table>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
|
|
||||||
@@ -454,14 +453,14 @@ Summary:
|
|||||||
<?cs if:subcount(cl.methods) ?>
|
<?cs if:subcount(cl.methods) ?>
|
||||||
<tr class="api apilevel-<?cs var:cl.since ?>" >
|
<tr class="api apilevel-<?cs var:cl.since ?>" >
|
||||||
<td colspan="12"><?cs call:expando_trigger("inherited-methods-"+cl.qualified, "closed") ?>
|
<td colspan="12"><?cs call:expando_trigger("inherited-methods-"+cl.qualified, "closed") ?>
|
||||||
From <?cs var:cl.kind ?> <a href="<?cs var:toroot ?><?cs var:cl.link ?>"><?cs var:cl.qualified ?></a>
|
From <?cs var:cl.kind ?> <?cs call:cond_link(cl.qualified, toroot, cl.link, cl.included) ?>
|
||||||
<div id="inherited-methods-<?cs var:cl.qualified ?>">
|
<div id="inherited-methods-<?cs var:cl.qualified ?>">
|
||||||
<div id="inherited-methods-<?cs var:cl.qualified ?>-list"
|
<div id="inherited-methods-<?cs var:cl.qualified ?>-list"
|
||||||
class="jd-inheritedlinks">
|
class="jd-inheritedlinks">
|
||||||
</div>
|
</div>
|
||||||
<div id="inherited-methods-<?cs var:cl.qualified ?>-summary" style="display: none;">
|
<div id="inherited-methods-<?cs var:cl.qualified ?>-summary" style="display: none;">
|
||||||
<table class="jd-sumtable-expando">
|
<table class="jd-sumtable-expando">
|
||||||
<?cs call:write_method_summary(cl.methods) ?></table>
|
<?cs call:write_method_summary(cl.methods, cl.included) ?></table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
|
@@ -39,6 +39,15 @@ def:type_link_impl(type, link) ?><?cs
|
|||||||
<?cs def:class_name(type) ?><?cs call:type_link_impl(type, "false") ?><?cs /def ?>
|
<?cs def:class_name(type) ?><?cs call:type_link_impl(type, "false") ?><?cs /def ?>
|
||||||
<?cs def:type_link(type) ?><?cs call:type_link_impl(type, "true") ?><?cs /def ?>
|
<?cs def:type_link(type) ?><?cs call:type_link_impl(type, "true") ?><?cs /def ?>
|
||||||
|
|
||||||
|
<?cs # a conditional link.
|
||||||
|
if the "condition" parameter evals to true then the link is displayed
|
||||||
|
otherwise only the text is displayed
|
||||||
|
?><?cs
|
||||||
|
def:cond_link(text, root, path, condition) ?><?cs
|
||||||
|
if:condition ?><a href="<?cs var:root ?><?cs var:path ?>"><?cs /if ?><?cs var:text ?><?cs if:condition ?></a><?cs /if ?><?cs
|
||||||
|
/def ?>
|
||||||
|
|
||||||
|
|
||||||
<?cs # A comma separated parameter list ?><?cs
|
<?cs # A comma separated parameter list ?><?cs
|
||||||
def:parameter_list(params) ?><?cs
|
def:parameter_list(params) ?><?cs
|
||||||
each:param = params ?><?cs
|
each:param = params ?><?cs
|
||||||
@@ -64,6 +73,15 @@ def:tag_list(tags) ?><?cs
|
|||||||
elif:tag.kind == "@sdkCurrent" ?><?cs var:sdk.current ?><?cs
|
elif:tag.kind == "@sdkCurrent" ?><?cs var:sdk.current ?><?cs
|
||||||
elif:tag.kind == "@sdkCurrentVersion" ?><?cs var:sdk.version ?><?cs
|
elif:tag.kind == "@sdkCurrentVersion" ?><?cs var:sdk.version ?><?cs
|
||||||
elif:tag.kind == "@sdkCurrentRelId" ?><?cs var:sdk.rel.id ?><?cs
|
elif:tag.kind == "@sdkCurrentRelId" ?><?cs var:sdk.rel.id ?><?cs
|
||||||
|
elif:tag.kind == "@sdkPlatformVersion" ?><?cs var:sdk.platform.version ?><?cs
|
||||||
|
elif:tag.kind == "@sdkPlatformApiLevel" ?><?cs var:sdk.platform.apiLevel ?><?cs
|
||||||
|
elif:tag.kind == "@sdkPlatformMajorMinor" ?><?cs var:sdk.platform.majorMinor ?><?cs
|
||||||
|
elif:tag.kind == "@sdkPlatformReleaseDate" ?><?cs var:sdk.platform.releaseDate ?><?cs
|
||||||
|
elif:tag.kind == "@sdkPlatformDeployableDate" ?><?cs var:sdk.platform.deployableDate ?><?cs
|
||||||
|
elif:tag.kind == "@adtZipVersion" ?><?cs var:adt.zip.version ?><?cs
|
||||||
|
elif:tag.kind == "@adtZipDownload" ?><?cs var:adt.zip.download ?><?cs
|
||||||
|
elif:tag.kind == "@adtZipBytes" ?><?cs var:adt.zip.bytes ?><?cs
|
||||||
|
elif:tag.kind == "@adtZipChecksum" ?><?cs var:adt.zip.checksum ?><?cs
|
||||||
elif:tag.kind == "@inheritDoc" ?><?cs # This is the case when @inheritDoc is in something
|
elif:tag.kind == "@inheritDoc" ?><?cs # This is the case when @inheritDoc is in something
|
||||||
that doesn't inherit from anything?><?cs
|
that doesn't inherit from anything?><?cs
|
||||||
elif:tag.kind == "@attr" ?><?cs
|
elif:tag.kind == "@attr" ?><?cs
|
||||||
@@ -89,8 +107,8 @@ def:short_descr(obj) ?><?cs
|
|||||||
<?cs # Show the red box with the deprecated warning ?><?cs
|
<?cs # Show the red box with the deprecated warning ?><?cs
|
||||||
def:deprecated_warning(obj) ?><?cs
|
def:deprecated_warning(obj) ?><?cs
|
||||||
if:subcount(obj.deprecated) ?><p>
|
if:subcount(obj.deprecated) ?><p>
|
||||||
<p class="warning jd-deprecated-warning">
|
<p class="caution">
|
||||||
<strong><?cs call:deprecated_text(obj.kind) ?></strong><?cs
|
<strong><?cs call:deprecated_text(obj.kind) ?></strong><br/> <?cs
|
||||||
call:tag_list(obj.deprecated) ?>
|
call:tag_list(obj.deprecated) ?>
|
||||||
</p><?cs
|
</p><?cs
|
||||||
/if ?><?cs
|
/if ?><?cs
|
||||||
|
@@ -102,7 +102,7 @@ do
|
|||||||
$1 != "Length" ||
|
$1 != "Length" ||
|
||||||
$2 != "Method" ||
|
$2 != "Method" ||
|
||||||
$3 != "Size" ||
|
$3 != "Size" ||
|
||||||
$4 != "Ratio" ||
|
($4 != "Ratio" && $4 != "Cmpr") ||
|
||||||
$5 != "Date" ||
|
$5 != "Date" ||
|
||||||
$6 != "Time" ||
|
$6 != "Time" ||
|
||||||
$7 != "CRC-32" ||
|
$7 != "CRC-32" ||
|
||||||
|
98
tools/findleaves.py
Executable file
98
tools/findleaves.py
Executable file
@@ -0,0 +1,98 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Copyright (C) 2009 The Android Open Source Project
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Finds files with the specified name under a particular directory, stopping
|
||||||
|
# the search in a given subdirectory when the file is found.
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def perform_find(mindepth, prune, dirlist, filename):
|
||||||
|
result = []
|
||||||
|
pruneleaves = set(map(lambda x: os.path.split(x)[1], prune))
|
||||||
|
for rootdir in dirlist:
|
||||||
|
rootdepth = rootdir.count("/")
|
||||||
|
for root, dirs, files in os.walk(rootdir):
|
||||||
|
# prune
|
||||||
|
check_prune = False
|
||||||
|
for d in dirs:
|
||||||
|
if d in pruneleaves:
|
||||||
|
check_prune = True
|
||||||
|
break
|
||||||
|
if check_prune:
|
||||||
|
i = 0
|
||||||
|
while i < len(dirs):
|
||||||
|
if dirs[i] in prune:
|
||||||
|
del dirs[i]
|
||||||
|
else:
|
||||||
|
i += 1
|
||||||
|
# mindepth
|
||||||
|
if mindepth > 0:
|
||||||
|
depth = 1 + root.count("/") - rootdepth
|
||||||
|
if depth < mindepth:
|
||||||
|
continue
|
||||||
|
# match
|
||||||
|
if filename in files:
|
||||||
|
result.append(os.path.join(root, filename))
|
||||||
|
del dirs[:]
|
||||||
|
return result
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
sys.stderr.write("""Usage: %(progName)s [<options>] <dirlist> <filename>
|
||||||
|
Options:
|
||||||
|
--mindepth=<mindepth>
|
||||||
|
Both behave in the same way as their find(1) equivalents.
|
||||||
|
--prune=<dirname>
|
||||||
|
Avoids returning results from inside any directory called <dirname>
|
||||||
|
(e.g., "*/out/*"). May be used multiple times.
|
||||||
|
""" % {
|
||||||
|
"progName": os.path.split(sys.argv[0])[1],
|
||||||
|
})
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def main(argv):
|
||||||
|
mindepth = -1
|
||||||
|
prune = []
|
||||||
|
i=1
|
||||||
|
while i<len(argv) and len(argv[i])>2 and argv[i][0:2] == "--":
|
||||||
|
arg = argv[i]
|
||||||
|
if arg.startswith("--mindepth="):
|
||||||
|
try:
|
||||||
|
mindepth = int(arg[len("--mindepth="):])
|
||||||
|
except ValueError:
|
||||||
|
usage()
|
||||||
|
elif arg.startswith("--prune="):
|
||||||
|
p = arg[len("--prune="):]
|
||||||
|
if len(p) == 0:
|
||||||
|
usage()
|
||||||
|
prune.append(p)
|
||||||
|
else:
|
||||||
|
usage()
|
||||||
|
i += 1
|
||||||
|
if len(argv)-i < 2: # need both <dirlist> and <filename>
|
||||||
|
usage()
|
||||||
|
dirlist = argv[i:-1]
|
||||||
|
filename = argv[-1]
|
||||||
|
results = perform_find(mindepth, prune, dirlist, filename)
|
||||||
|
results.sort()
|
||||||
|
for r in set(results):
|
||||||
|
print r
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main(sys.argv)
|
@@ -1,109 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
#
|
|
||||||
# Copyright (C) 2008 The Android Open Source Project
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Finds files with the specified name under a particular directory, stopping
|
|
||||||
# the search in a given subdirectory when the file is found.
|
|
||||||
#
|
|
||||||
|
|
||||||
set -o nounset # fail when dereferencing unset variables
|
|
||||||
set -o errexit # fail if any subcommand fails
|
|
||||||
|
|
||||||
progName=`basename $0`
|
|
||||||
|
|
||||||
function warn() {
|
|
||||||
echo "$progName: $@" >&2
|
|
||||||
}
|
|
||||||
|
|
||||||
function trace() {
|
|
||||||
echo "$progName: $@"
|
|
||||||
}
|
|
||||||
|
|
||||||
function usage() {
|
|
||||||
if [[ $# > 0 ]]
|
|
||||||
then
|
|
||||||
warn $@
|
|
||||||
fi
|
|
||||||
cat <<-EOF
|
|
||||||
Usage: $progName [<options>] <dirlist> <filename>
|
|
||||||
Options:
|
|
||||||
--mindepth=<mindepth>
|
|
||||||
--maxdepth=<maxdepth>
|
|
||||||
Both behave in the same way as their find(1) equivalents.
|
|
||||||
--prune=<glob>
|
|
||||||
Avoids returning results from any path matching the given glob-style
|
|
||||||
pattern (e.g., "*/out/*"). May be used multiple times.
|
|
||||||
EOF
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
function fail() {
|
|
||||||
warn $@
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ $# -lt 2 ]
|
|
||||||
then
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
|
|
||||||
findargs=""
|
|
||||||
while [[ "${1:0:2}" == "--" ]]
|
|
||||||
do
|
|
||||||
arg=${1:2}
|
|
||||||
name=${arg%%=*}
|
|
||||||
value=${arg##*=}
|
|
||||||
if [[ "$name" == "mindepth" || "$name" == "maxdepth" ]]
|
|
||||||
then
|
|
||||||
# Add to beginning of findargs; these must come before the expression.
|
|
||||||
findargs="-$name $value $findargs"
|
|
||||||
elif [[ "$name" == "prune" ]]
|
|
||||||
then
|
|
||||||
# Add to end of findargs; these are part of the expression.
|
|
||||||
findargs="$findargs -path $value -prune -or"
|
|
||||||
fi
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
|
|
||||||
nargs=$#
|
|
||||||
# The filename is the last argument
|
|
||||||
filename="${!nargs}"
|
|
||||||
|
|
||||||
# Print out all files that match, as long as the path isn't explicitly
|
|
||||||
# pruned. This will print out extraneous results from directories whose
|
|
||||||
# parents have a match. These are filtered out by the awk script below.
|
|
||||||
find "${@:1:$nargs-1}" $findargs -type f -name "$filename" -print |
|
|
||||||
|
|
||||||
# Only pass along the directory of each match.
|
|
||||||
sed -e 's/\/[^\/]*$/\//' |
|
|
||||||
|
|
||||||
# Sort the output, so directories appear immediately before their contents.
|
|
||||||
# If there are any duplicates, the awk script will implicitly ignore them.
|
|
||||||
# The LC_ALL=C forces sort(1) to use bytewise ordering instead of listening
|
|
||||||
# to the locale, which may do case-insensitive and/or alphanumeric-only
|
|
||||||
# sorting.
|
|
||||||
LC_ALL=C sort |
|
|
||||||
|
|
||||||
# Always print the first line, which can't possibly be covered by a
|
|
||||||
# parent directory match. After that, only print lines where the last
|
|
||||||
# line printed isn't a prefix.
|
|
||||||
awk -v "filename=$filename" '
|
|
||||||
(NR == 1) || (index($0, last) != 1) {
|
|
||||||
last = $0;
|
|
||||||
printf("%s%s\n", $0, filename);
|
|
||||||
}
|
|
||||||
'
|
|
@@ -87,6 +87,10 @@ class AmendGenerator(object):
|
|||||||
'dur' seconds."""
|
'dur' seconds."""
|
||||||
self.script.append("show_progress %f %d" % (frac, int(dur)))
|
self.script.append("show_progress %f %d" % (frac, int(dur)))
|
||||||
|
|
||||||
|
def SetProgress(self, frac):
|
||||||
|
"""Not implemented in amend."""
|
||||||
|
pass
|
||||||
|
|
||||||
def PatchCheck(self, filename, *sha1):
|
def PatchCheck(self, filename, *sha1):
|
||||||
"""Check that the given file (or MTD reference) has one of the
|
"""Check that the given file (or MTD reference) has one of the
|
||||||
given *sha1 hashes."""
|
given *sha1 hashes."""
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
import errno
|
import errno
|
||||||
import getopt
|
import getopt
|
||||||
import getpass
|
import getpass
|
||||||
|
import imp
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
@@ -33,7 +34,7 @@ OPTIONS.search_path = "out/host/linux-x86"
|
|||||||
OPTIONS.max_image_size = {}
|
OPTIONS.max_image_size = {}
|
||||||
OPTIONS.verbose = False
|
OPTIONS.verbose = False
|
||||||
OPTIONS.tempfiles = []
|
OPTIONS.tempfiles = []
|
||||||
|
OPTIONS.device_specific = None
|
||||||
|
|
||||||
class ExternalError(RuntimeError): pass
|
class ExternalError(RuntimeError): pass
|
||||||
|
|
||||||
@@ -184,14 +185,20 @@ def GetKeyPasswords(keylist):
|
|||||||
return key_passwords
|
return key_passwords
|
||||||
|
|
||||||
|
|
||||||
def SignFile(input_name, output_name, key, password, align=None):
|
def SignFile(input_name, output_name, key, password, align=None,
|
||||||
|
whole_file=False):
|
||||||
"""Sign the input_name zip/jar/apk, producing output_name. Use the
|
"""Sign the input_name zip/jar/apk, producing output_name. Use the
|
||||||
given key and password (the latter may be None if the key does not
|
given key and password (the latter may be None if the key does not
|
||||||
have a password.
|
have a password.
|
||||||
|
|
||||||
If align is an integer > 1, zipalign is run to align stored files in
|
If align is an integer > 1, zipalign is run to align stored files in
|
||||||
the output zip on 'align'-byte boundaries.
|
the output zip on 'align'-byte boundaries.
|
||||||
|
|
||||||
|
If whole_file is true, use the "-w" option to SignApk to embed a
|
||||||
|
signature that covers the whole file in the archive comment of the
|
||||||
|
zip file.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if align == 0 or align == 1:
|
if align == 0 or align == 1:
|
||||||
align = None
|
align = None
|
||||||
|
|
||||||
@@ -201,13 +208,14 @@ def SignFile(input_name, output_name, key, password, align=None):
|
|||||||
else:
|
else:
|
||||||
sign_name = output_name
|
sign_name = output_name
|
||||||
|
|
||||||
p = Run(["java", "-jar",
|
cmd = ["java", "-Xmx512m", "-jar",
|
||||||
os.path.join(OPTIONS.search_path, "framework", "signapk.jar"),
|
os.path.join(OPTIONS.search_path, "framework", "signapk.jar")]
|
||||||
key + ".x509.pem",
|
if whole_file:
|
||||||
key + ".pk8",
|
cmd.append("-w")
|
||||||
input_name, sign_name],
|
cmd.extend([key + ".x509.pem", key + ".pk8",
|
||||||
stdin=subprocess.PIPE,
|
input_name, sign_name])
|
||||||
stdout=subprocess.PIPE)
|
|
||||||
|
p = Run(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||||
if password is not None:
|
if password is not None:
|
||||||
password += "\n"
|
password += "\n"
|
||||||
p.communicate(password)
|
p.communicate(password)
|
||||||
@@ -247,6 +255,10 @@ COMMON_DOCSTRING = """
|
|||||||
Prepend <dir>/bin to the list of places to search for binaries
|
Prepend <dir>/bin to the list of places to search for binaries
|
||||||
run by this script, and expect to find jars in <dir>/framework.
|
run by this script, and expect to find jars in <dir>/framework.
|
||||||
|
|
||||||
|
-s (--device_specific) <file>
|
||||||
|
Path to the python module containing device-specific
|
||||||
|
releasetools code.
|
||||||
|
|
||||||
-v (--verbose)
|
-v (--verbose)
|
||||||
Show command lines being executed.
|
Show command lines being executed.
|
||||||
|
|
||||||
@@ -271,8 +283,9 @@ def ParseOptions(argv,
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(
|
opts, args = getopt.getopt(
|
||||||
argv, "hvp:" + extra_opts,
|
argv, "hvp:s:" + extra_opts,
|
||||||
["help", "verbose", "path="] + list(extra_long_opts))
|
["help", "verbose", "path=", "device_specific="] +
|
||||||
|
list(extra_long_opts))
|
||||||
except getopt.GetoptError, err:
|
except getopt.GetoptError, err:
|
||||||
Usage(docstring)
|
Usage(docstring)
|
||||||
print "**", str(err), "**"
|
print "**", str(err), "**"
|
||||||
@@ -288,6 +301,8 @@ def ParseOptions(argv,
|
|||||||
OPTIONS.verbose = True
|
OPTIONS.verbose = True
|
||||||
elif o in ("-p", "--path"):
|
elif o in ("-p", "--path"):
|
||||||
OPTIONS.search_path = a
|
OPTIONS.search_path = a
|
||||||
|
elif o in ("-s", "--device_specific"):
|
||||||
|
OPTIONS.device_specific = a
|
||||||
else:
|
else:
|
||||||
if extra_option_handler is None or not extra_option_handler(o, a):
|
if extra_option_handler is None or not extra_option_handler(o, a):
|
||||||
assert False, "unknown option \"%s\"" % (o,)
|
assert False, "unknown option \"%s\"" % (o,)
|
||||||
@@ -412,3 +427,68 @@ def ZipWriteStr(zip, filename, data, perms=0644):
|
|||||||
zinfo.compress_type = zip.compression
|
zinfo.compress_type = zip.compression
|
||||||
zinfo.external_attr = perms << 16
|
zinfo.external_attr = perms << 16
|
||||||
zip.writestr(zinfo, data)
|
zip.writestr(zinfo, data)
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceSpecificParams(object):
|
||||||
|
module = None
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
"""Keyword arguments to the constructor become attributes of this
|
||||||
|
object, which is passed to all functions in the device-specific
|
||||||
|
module."""
|
||||||
|
for k, v in kwargs.iteritems():
|
||||||
|
setattr(self, k, v)
|
||||||
|
|
||||||
|
if self.module is None:
|
||||||
|
path = OPTIONS.device_specific
|
||||||
|
if not path: return
|
||||||
|
try:
|
||||||
|
if os.path.isdir(path):
|
||||||
|
info = imp.find_module("releasetools", [path])
|
||||||
|
else:
|
||||||
|
d, f = os.path.split(path)
|
||||||
|
b, x = os.path.splitext(f)
|
||||||
|
if x == ".py":
|
||||||
|
f = b
|
||||||
|
info = imp.find_module(f, [d])
|
||||||
|
self.module = imp.load_module("device_specific", *info)
|
||||||
|
except ImportError:
|
||||||
|
print "unable to load device-specific module; assuming none"
|
||||||
|
|
||||||
|
def _DoCall(self, function_name, *args, **kwargs):
|
||||||
|
"""Call the named function in the device-specific module, passing
|
||||||
|
the given args and kwargs. The first argument to the call will be
|
||||||
|
the DeviceSpecific object itself. If there is no module, or the
|
||||||
|
module does not define the function, return the value of the
|
||||||
|
'default' kwarg (which itself defaults to None)."""
|
||||||
|
if self.module is None or not hasattr(self.module, function_name):
|
||||||
|
return kwargs.get("default", None)
|
||||||
|
return getattr(self.module, function_name)(*((self,) + args), **kwargs)
|
||||||
|
|
||||||
|
def FullOTA_Assertions(self):
|
||||||
|
"""Called after emitting the block of assertions at the top of a
|
||||||
|
full OTA package. Implementations can add whatever additional
|
||||||
|
assertions they like."""
|
||||||
|
return self._DoCall("FullOTA_Assertions")
|
||||||
|
|
||||||
|
def FullOTA_InstallEnd(self):
|
||||||
|
"""Called at the end of full OTA installation; typically this is
|
||||||
|
used to install the image for the device's baseband processor."""
|
||||||
|
return self._DoCall("FullOTA_InstallEnd")
|
||||||
|
|
||||||
|
def IncrementalOTA_Assertions(self):
|
||||||
|
"""Called after emitting the block of assertions at the top of an
|
||||||
|
incremental OTA package. Implementations can add whatever
|
||||||
|
additional assertions they like."""
|
||||||
|
return self._DoCall("IncrementalOTA_Assertions")
|
||||||
|
|
||||||
|
def IncrementalOTA_VerifyEnd(self):
|
||||||
|
"""Called at the end of the verification phase of incremental OTA
|
||||||
|
installation; additional checks can be placed here to abort the
|
||||||
|
script before any changes are made."""
|
||||||
|
return self._DoCall("IncrementalOTA_VerifyEnd")
|
||||||
|
|
||||||
|
def IncrementalOTA_InstallEnd(self):
|
||||||
|
"""Called at the end of incremental OTA installation; typically
|
||||||
|
this is used to install the image for the device's baseband
|
||||||
|
processor."""
|
||||||
|
return self._DoCall("IncrementalOTA_InstallEnd")
|
||||||
|
@@ -100,9 +100,16 @@ class EdifyGenerator(object):
|
|||||||
|
|
||||||
def ShowProgress(self, frac, dur):
|
def ShowProgress(self, frac, dur):
|
||||||
"""Update the progress bar, advancing it over 'frac' over the next
|
"""Update the progress bar, advancing it over 'frac' over the next
|
||||||
'dur' seconds."""
|
'dur' seconds. 'dur' may be zero to advance it via SetProgress
|
||||||
|
commands instead of by time."""
|
||||||
self.script.append("show_progress(%f, %d);" % (frac, int(dur)))
|
self.script.append("show_progress(%f, %d);" % (frac, int(dur)))
|
||||||
|
|
||||||
|
def SetProgress(self, frac):
|
||||||
|
"""Set the position of the progress bar within the chunk defined
|
||||||
|
by the most recent ShowProgress call. 'frac' should be in
|
||||||
|
[0,1]."""
|
||||||
|
self.script.append("set_progress(%f);" % (frac,))
|
||||||
|
|
||||||
def PatchCheck(self, filename, *sha1):
|
def PatchCheck(self, filename, *sha1):
|
||||||
"""Check that the given file (or MTD reference) has one of the
|
"""Check that the given file (or MTD reference) has one of the
|
||||||
given *sha1 hashes."""
|
given *sha1 hashes."""
|
||||||
|
@@ -31,6 +31,7 @@ if sys.hexversion < 0x02040000:
|
|||||||
print >> sys.stderr, "Python 2.4 or newer is required."
|
print >> sys.stderr, "Python 2.4 or newer is required."
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
import errno
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
@@ -82,8 +83,16 @@ def AddSystem(output_zip):
|
|||||||
# The name of the directory it is making an image out of matters to
|
# The name of the directory it is making an image out of matters to
|
||||||
# mkyaffs2image. It wants "system" but we have a directory named
|
# mkyaffs2image. It wants "system" but we have a directory named
|
||||||
# "SYSTEM", so create a symlink.
|
# "SYSTEM", so create a symlink.
|
||||||
|
try:
|
||||||
os.symlink(os.path.join(OPTIONS.input_tmp, "SYSTEM"),
|
os.symlink(os.path.join(OPTIONS.input_tmp, "SYSTEM"),
|
||||||
os.path.join(OPTIONS.input_tmp, "system"))
|
os.path.join(OPTIONS.input_tmp, "system"))
|
||||||
|
except OSError, e:
|
||||||
|
# bogus error on my mac version?
|
||||||
|
# File "./build/tools/releasetools/img_from_target_files", line 86, in AddSystem
|
||||||
|
# os.path.join(OPTIONS.input_tmp, "system"))
|
||||||
|
# OSError: [Errno 17] File exists
|
||||||
|
if (e.errno == errno.EEXIST):
|
||||||
|
pass
|
||||||
|
|
||||||
p = common.Run(["mkyaffs2image", "-f",
|
p = common.Run(["mkyaffs2image", "-f",
|
||||||
os.path.join(OPTIONS.input_tmp, "system"), img.name])
|
os.path.join(OPTIONS.input_tmp, "system"), img.name])
|
||||||
|
@@ -57,11 +57,13 @@ if sys.hexversion < 0x02040000:
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
import errno
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sha
|
import sha
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
@@ -80,6 +82,7 @@ OPTIONS.wipe_user_data = False
|
|||||||
OPTIONS.omit_prereq = False
|
OPTIONS.omit_prereq = False
|
||||||
OPTIONS.extra_script = None
|
OPTIONS.extra_script = None
|
||||||
OPTIONS.script_mode = 'auto'
|
OPTIONS.script_mode = 'auto'
|
||||||
|
OPTIONS.worker_threads = 3
|
||||||
|
|
||||||
def MostPopularKey(d, default):
|
def MostPopularKey(d, default):
|
||||||
"""Given a dict, return the key corresponding to the largest
|
"""Given a dict, return the key corresponding to the largest
|
||||||
@@ -273,19 +276,14 @@ def SignOutput(temp_zip_name, output_zip_name):
|
|||||||
key_passwords = common.GetKeyPasswords([OPTIONS.package_key])
|
key_passwords = common.GetKeyPasswords([OPTIONS.package_key])
|
||||||
pw = key_passwords[OPTIONS.package_key]
|
pw = key_passwords[OPTIONS.package_key]
|
||||||
|
|
||||||
common.SignFile(temp_zip_name, output_zip_name, OPTIONS.package_key, pw)
|
common.SignFile(temp_zip_name, output_zip_name, OPTIONS.package_key, pw,
|
||||||
|
whole_file=True)
|
||||||
|
|
||||||
|
|
||||||
def AppendAssertions(script, input_zip):
|
def AppendAssertions(script, input_zip):
|
||||||
device = GetBuildProp("ro.product.device", input_zip)
|
device = GetBuildProp("ro.product.device", input_zip)
|
||||||
script.AssertDevice(device)
|
script.AssertDevice(device)
|
||||||
|
|
||||||
info = input_zip.read("OTA/android-info.txt")
|
|
||||||
m = re.search(r"require\s+version-bootloader\s*=\s*(\S+)", info)
|
|
||||||
if m:
|
|
||||||
bootloaders = m.group(1).split("|")
|
|
||||||
script.AssertSomeBootloader(*bootloaders)
|
|
||||||
|
|
||||||
|
|
||||||
def MakeRecoveryPatch(output_zip, recovery_img, boot_img):
|
def MakeRecoveryPatch(output_zip, recovery_img, boot_img):
|
||||||
"""Generate a binary patch that creates the recovery image starting
|
"""Generate a binary patch that creates the recovery image starting
|
||||||
@@ -302,8 +300,9 @@ def MakeRecoveryPatch(output_zip, recovery_img, boot_img):
|
|||||||
executable.
|
executable.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
patch = Difference(recovery_img, boot_img, "imgdiff")
|
d = Difference(recovery_img, boot_img)
|
||||||
common.ZipWriteStr(output_zip, "system/recovery-from-boot.p", patch)
|
_, _, patch = d.ComputePatch()
|
||||||
|
common.ZipWriteStr(output_zip, "recovery/recovery-from-boot.p", patch)
|
||||||
Item.Get("system/recovery-from-boot.p", dir=False)
|
Item.Get("system/recovery-from-boot.p", dir=False)
|
||||||
|
|
||||||
# Images with different content will have a different first page, so
|
# Images with different content will have a different first page, so
|
||||||
@@ -324,7 +323,7 @@ fi
|
|||||||
'header_sha1': header_sha1,
|
'header_sha1': header_sha1,
|
||||||
'recovery_size': recovery_img.size,
|
'recovery_size': recovery_img.size,
|
||||||
'recovery_sha1': recovery_img.sha1 }
|
'recovery_sha1': recovery_img.sha1 }
|
||||||
common.ZipWriteStr(output_zip, "system/etc/install-recovery.sh", sh)
|
common.ZipWriteStr(output_zip, "recovery/etc/install-recovery.sh", sh)
|
||||||
return Item.Get("system/etc/install-recovery.sh", dir=False)
|
return Item.Get("system/etc/install-recovery.sh", dir=False)
|
||||||
|
|
||||||
|
|
||||||
@@ -339,19 +338,18 @@ def WriteFullOTAPackage(input_zip, output_zip):
|
|||||||
# change very often.
|
# change very often.
|
||||||
script = edify_generator.EdifyGenerator(2)
|
script = edify_generator.EdifyGenerator(2)
|
||||||
|
|
||||||
|
device_specific = common.DeviceSpecificParams(
|
||||||
|
input_zip=input_zip,
|
||||||
|
output_zip=output_zip,
|
||||||
|
script=script,
|
||||||
|
input_tmp=OPTIONS.input_tmp)
|
||||||
|
|
||||||
if not OPTIONS.omit_prereq:
|
if not OPTIONS.omit_prereq:
|
||||||
ts = GetBuildProp("ro.build.date.utc", input_zip)
|
ts = GetBuildProp("ro.build.date.utc", input_zip)
|
||||||
script.AssertOlderBuild(ts)
|
script.AssertOlderBuild(ts)
|
||||||
|
|
||||||
AppendAssertions(script, input_zip)
|
AppendAssertions(script, input_zip)
|
||||||
|
device_specific.FullOTA_Assertions()
|
||||||
script.ShowProgress(0.1, 0)
|
|
||||||
|
|
||||||
try:
|
|
||||||
common.ZipWriteStr(output_zip, "radio.img", input_zip.read("RADIO/image"))
|
|
||||||
script.WriteFirmwareImage("radio", "radio.img")
|
|
||||||
except KeyError:
|
|
||||||
print "warning: no radio image in input target_files; not flashing radio"
|
|
||||||
|
|
||||||
script.ShowProgress(0.5, 0)
|
script.ShowProgress(0.5, 0)
|
||||||
|
|
||||||
@@ -360,6 +358,7 @@ def WriteFullOTAPackage(input_zip, output_zip):
|
|||||||
|
|
||||||
script.FormatPartition("system")
|
script.FormatPartition("system")
|
||||||
script.Mount("MTD", "system", "/system")
|
script.Mount("MTD", "system", "/system")
|
||||||
|
script.UnpackPackageDir("recovery", "/system")
|
||||||
script.UnpackPackageDir("system", "/system")
|
script.UnpackPackageDir("system", "/system")
|
||||||
|
|
||||||
symlinks = CopySystemFiles(input_zip, output_zip)
|
symlinks = CopySystemFiles(input_zip, output_zip)
|
||||||
@@ -385,8 +384,11 @@ def WriteFullOTAPackage(input_zip, output_zip):
|
|||||||
common.ZipWriteStr(output_zip, "boot.img", boot_img.data)
|
common.ZipWriteStr(output_zip, "boot.img", boot_img.data)
|
||||||
script.ShowProgress(0.2, 0)
|
script.ShowProgress(0.2, 0)
|
||||||
|
|
||||||
script.WriteRawImage("boot", "boot.img")
|
|
||||||
script.ShowProgress(0.2, 10)
|
script.ShowProgress(0.2, 10)
|
||||||
|
script.WriteRawImage("boot", "boot.img")
|
||||||
|
|
||||||
|
script.ShowProgress(0.1, 0)
|
||||||
|
device_specific.FullOTA_InstallEnd()
|
||||||
|
|
||||||
if OPTIONS.extra_script is not None:
|
if OPTIONS.extra_script is not None:
|
||||||
script.AppendExtra(OPTIONS.extra_script)
|
script.AppendExtra(OPTIONS.extra_script)
|
||||||
@@ -423,11 +425,30 @@ def LoadSystemFiles(z):
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def Difference(tf, sf, diff_program):
|
DIFF_PROGRAM_BY_EXT = {
|
||||||
"""Return the patch (as a string of data) needed to turn sf into tf.
|
".gz" : "imgdiff",
|
||||||
diff_program is the name of an external program (or list, if
|
".zip" : ["imgdiff", "-z"],
|
||||||
additional arguments are desired) to run to generate the diff.
|
".jar" : ["imgdiff", "-z"],
|
||||||
"""
|
".apk" : ["imgdiff", "-z"],
|
||||||
|
".img" : "imgdiff",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Difference(object):
|
||||||
|
def __init__(self, tf, sf):
|
||||||
|
self.tf = tf
|
||||||
|
self.sf = sf
|
||||||
|
self.patch = None
|
||||||
|
|
||||||
|
def ComputePatch(self):
|
||||||
|
"""Compute the patch (as a string of data) needed to turn sf into
|
||||||
|
tf. Returns the same tuple as GetPatch()."""
|
||||||
|
|
||||||
|
tf = self.tf
|
||||||
|
sf = self.sf
|
||||||
|
|
||||||
|
ext = os.path.splitext(tf.name)[1]
|
||||||
|
diff_program = DIFF_PROGRAM_BY_EXT.get(ext, "bsdiff")
|
||||||
|
|
||||||
ttemp = tf.WriteToTemp()
|
ttemp = tf.WriteToTemp()
|
||||||
stemp = sf.WriteToTemp()
|
stemp = sf.WriteToTemp()
|
||||||
@@ -443,7 +464,7 @@ def Difference(tf, sf, diff_program):
|
|||||||
cmd.append(stemp.name)
|
cmd.append(stemp.name)
|
||||||
cmd.append(ttemp.name)
|
cmd.append(ttemp.name)
|
||||||
cmd.append(ptemp.name)
|
cmd.append(ptemp.name)
|
||||||
p = common.Run(cmd)
|
p = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
_, err = p.communicate()
|
_, err = p.communicate()
|
||||||
if err or p.returncode != 0:
|
if err or p.returncode != 0:
|
||||||
print "WARNING: failure running %s:\n%s\n" % (diff_program, err)
|
print "WARNING: failure running %s:\n%s\n" % (diff_program, err)
|
||||||
@@ -454,7 +475,61 @@ def Difference(tf, sf, diff_program):
|
|||||||
stemp.close()
|
stemp.close()
|
||||||
ttemp.close()
|
ttemp.close()
|
||||||
|
|
||||||
return diff
|
self.patch = diff
|
||||||
|
return self.tf, self.sf, self.patch
|
||||||
|
|
||||||
|
|
||||||
|
def GetPatch(self):
|
||||||
|
"""Return a tuple (target_file, source_file, patch_data).
|
||||||
|
patch_data may be None if ComputePatch hasn't been called, or if
|
||||||
|
computing the patch failed."""
|
||||||
|
return self.tf, self.sf, self.patch
|
||||||
|
|
||||||
|
|
||||||
|
def ComputeDifferences(diffs):
|
||||||
|
"""Call ComputePatch on all the Difference objects in 'diffs'."""
|
||||||
|
print len(diffs), "diffs to compute"
|
||||||
|
|
||||||
|
# Do the largest files first, to try and reduce the long-pole effect.
|
||||||
|
by_size = [(i.tf.size, i) for i in diffs]
|
||||||
|
by_size.sort(reverse=True)
|
||||||
|
by_size = [i[1] for i in by_size]
|
||||||
|
|
||||||
|
lock = threading.Lock()
|
||||||
|
diff_iter = iter(by_size) # accessed under lock
|
||||||
|
|
||||||
|
def worker():
|
||||||
|
try:
|
||||||
|
lock.acquire()
|
||||||
|
for d in diff_iter:
|
||||||
|
lock.release()
|
||||||
|
start = time.time()
|
||||||
|
d.ComputePatch()
|
||||||
|
dur = time.time() - start
|
||||||
|
lock.acquire()
|
||||||
|
|
||||||
|
tf, sf, patch = d.GetPatch()
|
||||||
|
if sf.name == tf.name:
|
||||||
|
name = tf.name
|
||||||
|
else:
|
||||||
|
name = "%s (%s)" % (tf.name, sf.name)
|
||||||
|
if patch is None:
|
||||||
|
print "patching failed! %s" % (name,)
|
||||||
|
else:
|
||||||
|
print "%8.2f sec %8d / %8d bytes (%6.2f%%) %s" % (
|
||||||
|
dur, len(patch), tf.size, 100.0 * len(patch) / tf.size, name)
|
||||||
|
lock.release()
|
||||||
|
except Exception, e:
|
||||||
|
print e
|
||||||
|
raise
|
||||||
|
|
||||||
|
# start worker threads; wait for them all to finish.
|
||||||
|
threads = [threading.Thread(target=worker)
|
||||||
|
for i in range(OPTIONS.worker_threads)]
|
||||||
|
for th in threads:
|
||||||
|
th.start()
|
||||||
|
while threads:
|
||||||
|
threads.pop().join()
|
||||||
|
|
||||||
|
|
||||||
def GetBuildProp(property, z):
|
def GetBuildProp(property, z):
|
||||||
@@ -484,6 +559,7 @@ def GetRecoveryAPIVersion(zip):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
|
def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
|
||||||
source_version = GetRecoveryAPIVersion(source_zip)
|
source_version = GetRecoveryAPIVersion(source_zip)
|
||||||
|
|
||||||
@@ -502,6 +578,12 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
|
|||||||
else:
|
else:
|
||||||
raise ValueError('unknown script mode "%s"' % (OPTIONS.script_mode,))
|
raise ValueError('unknown script mode "%s"' % (OPTIONS.script_mode,))
|
||||||
|
|
||||||
|
device_specific = common.DeviceSpecificParams(
|
||||||
|
source_zip=source_zip,
|
||||||
|
target_zip=target_zip,
|
||||||
|
output_zip=output_zip,
|
||||||
|
script=script)
|
||||||
|
|
||||||
print "Loading target..."
|
print "Loading target..."
|
||||||
target_data = LoadSystemFiles(target_zip)
|
target_data = LoadSystemFiles(target_zip)
|
||||||
print "Loading source..."
|
print "Loading source..."
|
||||||
@@ -509,9 +591,11 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
|
|||||||
|
|
||||||
verbatim_targets = []
|
verbatim_targets = []
|
||||||
patch_list = []
|
patch_list = []
|
||||||
|
diffs = []
|
||||||
largest_source_size = 0
|
largest_source_size = 0
|
||||||
for fn in sorted(target_data.keys()):
|
for fn in sorted(target_data.keys()):
|
||||||
tf = target_data[fn]
|
tf = target_data[fn]
|
||||||
|
assert fn == tf.name
|
||||||
sf = source_data.get(fn, None)
|
sf = source_data.get(fn, None)
|
||||||
|
|
||||||
if sf is None or fn in OPTIONS.require_verbatim:
|
if sf is None or fn in OPTIONS.require_verbatim:
|
||||||
@@ -523,26 +607,23 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
|
|||||||
verbatim_targets.append((fn, tf.size))
|
verbatim_targets.append((fn, tf.size))
|
||||||
elif tf.sha1 != sf.sha1:
|
elif tf.sha1 != sf.sha1:
|
||||||
# File is different; consider sending as a patch
|
# File is different; consider sending as a patch
|
||||||
diff_method = "bsdiff"
|
diffs.append(Difference(tf, sf))
|
||||||
if tf.name.endswith(".gz"):
|
|
||||||
diff_method = "imgdiff"
|
|
||||||
d = Difference(tf, sf, diff_method)
|
|
||||||
if d is not None:
|
|
||||||
print fn, tf.size, len(d), (float(len(d)) / tf.size)
|
|
||||||
if d is None or len(d) > tf.size * OPTIONS.patch_threshold:
|
|
||||||
# patch is almost as big as the file; don't bother patching
|
|
||||||
tf.AddToZip(output_zip)
|
|
||||||
verbatim_targets.append((fn, tf.size))
|
|
||||||
else:
|
|
||||||
common.ZipWriteStr(output_zip, "patch/" + fn + ".p", d)
|
|
||||||
patch_list.append((fn, tf, sf, tf.size))
|
|
||||||
largest_source_size = max(largest_source_size, sf.size)
|
|
||||||
else:
|
else:
|
||||||
# Target file identical to source.
|
# Target file identical to source.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
total_verbatim_size = sum([i[1] for i in verbatim_targets])
|
ComputeDifferences(diffs)
|
||||||
total_patched_size = sum([i[3] for i in patch_list])
|
|
||||||
|
for diff in diffs:
|
||||||
|
tf, sf, d = diff.GetPatch()
|
||||||
|
if d is None or len(d) > tf.size * OPTIONS.patch_threshold:
|
||||||
|
# patch is almost as big as the file; don't bother patching
|
||||||
|
tf.AddToZip(output_zip)
|
||||||
|
verbatim_targets.append((tf.name, tf.size))
|
||||||
|
else:
|
||||||
|
common.ZipWriteStr(output_zip, "patch/" + tf.name + ".p", d)
|
||||||
|
patch_list.append((tf.name, tf, sf, tf.size))
|
||||||
|
largest_source_size = max(largest_source_size, sf.size)
|
||||||
|
|
||||||
source_fp = GetBuildProp("ro.build.fingerprint", source_zip)
|
source_fp = GetBuildProp("ro.build.fingerprint", source_zip)
|
||||||
target_fp = GetBuildProp("ro.build.fingerprint", target_zip)
|
target_fp = GetBuildProp("ro.build.fingerprint", target_zip)
|
||||||
@@ -566,35 +647,31 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
|
|||||||
os.path.join(OPTIONS.target_tmp, "RECOVERY")))
|
os.path.join(OPTIONS.target_tmp, "RECOVERY")))
|
||||||
updating_recovery = (source_recovery.data != target_recovery.data)
|
updating_recovery = (source_recovery.data != target_recovery.data)
|
||||||
|
|
||||||
source_radio = source_zip.read("RADIO/image")
|
# Here's how we divide up the progress bar:
|
||||||
target_radio = target_zip.read("RADIO/image")
|
# 0.1 for verifying the start state (PatchCheck calls)
|
||||||
updating_radio = (source_radio != target_radio)
|
# 0.8 for applying patches (ApplyPatch calls)
|
||||||
|
# 0.1 for unpacking verbatim files, symlinking, and doing the
|
||||||
# The last 0.1 is reserved for creating symlinks, fixing
|
# device-specific commands.
|
||||||
# permissions, and writing the boot image (if necessary).
|
|
||||||
progress_bar_total = 1.0
|
|
||||||
if updating_boot:
|
|
||||||
progress_bar_total -= 0.1
|
|
||||||
if updating_radio:
|
|
||||||
progress_bar_total -= 0.3
|
|
||||||
|
|
||||||
AppendAssertions(script, target_zip)
|
AppendAssertions(script, target_zip)
|
||||||
|
device_specific.IncrementalOTA_Assertions()
|
||||||
|
|
||||||
script.Print("Verifying current system...")
|
script.Print("Verifying current system...")
|
||||||
|
|
||||||
pb_verify = progress_bar_total * 0.3 * \
|
script.ShowProgress(0.1, 0)
|
||||||
(total_patched_size /
|
total_verify_size = float(sum([i[2].size for i in patch_list]) + 1)
|
||||||
float(total_patched_size+total_verbatim_size+1))
|
if updating_boot:
|
||||||
|
total_verify_size += source_boot.size
|
||||||
for i, (fn, tf, sf, size) in enumerate(patch_list):
|
so_far = 0
|
||||||
if i % 5 == 0:
|
|
||||||
next_sizes = sum([i[3] for i in patch_list[i:i+5]])
|
|
||||||
script.ShowProgress(next_sizes * pb_verify / (total_patched_size+1), 1)
|
|
||||||
|
|
||||||
|
for fn, tf, sf, size in patch_list:
|
||||||
script.PatchCheck("/"+fn, tf.sha1, sf.sha1)
|
script.PatchCheck("/"+fn, tf.sha1, sf.sha1)
|
||||||
|
so_far += sf.size
|
||||||
|
script.SetProgress(so_far / total_verify_size)
|
||||||
|
|
||||||
if updating_boot:
|
if updating_boot:
|
||||||
d = Difference(target_boot, source_boot, "imgdiff")
|
d = Difference(target_boot, source_boot)
|
||||||
|
_, _, d = d.ComputePatch()
|
||||||
print "boot target: %d source: %d diff: %d" % (
|
print "boot target: %d source: %d diff: %d" % (
|
||||||
target_boot.size, source_boot.size, len(d))
|
target_boot.size, source_boot.size, len(d))
|
||||||
|
|
||||||
@@ -603,12 +680,16 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
|
|||||||
script.PatchCheck("MTD:boot:%d:%s:%d:%s" %
|
script.PatchCheck("MTD:boot:%d:%s:%d:%s" %
|
||||||
(source_boot.size, source_boot.sha1,
|
(source_boot.size, source_boot.sha1,
|
||||||
target_boot.size, target_boot.sha1))
|
target_boot.size, target_boot.sha1))
|
||||||
|
so_far += source_boot.size
|
||||||
|
script.SetProgress(so_far / total_verify_size)
|
||||||
|
|
||||||
if patch_list or updating_recovery or updating_boot:
|
if patch_list or updating_recovery or updating_boot:
|
||||||
script.CacheFreeSpaceCheck(largest_source_size)
|
script.CacheFreeSpaceCheck(largest_source_size)
|
||||||
script.Print("Unpacking patches...")
|
script.Print("Unpacking patches...")
|
||||||
script.UnpackPackageDir("patch", "/tmp/patchtmp")
|
script.UnpackPackageDir("patch", "/tmp/patchtmp")
|
||||||
|
|
||||||
|
device_specific.IncrementalOTA_VerifyEnd()
|
||||||
|
|
||||||
script.Comment("---- start making changes here ----")
|
script.Comment("---- start making changes here ----")
|
||||||
|
|
||||||
if OPTIONS.wipe_user_data:
|
if OPTIONS.wipe_user_data:
|
||||||
@@ -621,6 +702,19 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
|
|||||||
if i not in target_data] +
|
if i not in target_data] +
|
||||||
["/system/recovery.img"])
|
["/system/recovery.img"])
|
||||||
|
|
||||||
|
script.ShowProgress(0.8, 0)
|
||||||
|
total_patch_size = float(sum([i[1].size for i in patch_list]) + 1)
|
||||||
|
if updating_boot:
|
||||||
|
total_patch_size += target_boot.size
|
||||||
|
so_far = 0
|
||||||
|
|
||||||
|
script.Print("Patching system files...")
|
||||||
|
for fn, tf, sf, size in patch_list:
|
||||||
|
script.ApplyPatch("/"+fn, "-", tf.size, tf.sha1,
|
||||||
|
sf.sha1, "/tmp/patchtmp/"+fn+".p")
|
||||||
|
so_far += tf.size
|
||||||
|
script.SetProgress(so_far / total_patch_size)
|
||||||
|
|
||||||
if updating_boot:
|
if updating_boot:
|
||||||
# Produce the boot image by applying a patch to the current
|
# Produce the boot image by applying a patch to the current
|
||||||
# contents of the boot partition, and write it back to the
|
# contents of the boot partition, and write it back to the
|
||||||
@@ -632,6 +726,8 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
|
|||||||
"-",
|
"-",
|
||||||
target_boot.size, target_boot.sha1,
|
target_boot.size, target_boot.sha1,
|
||||||
source_boot.sha1, "/tmp/patchtmp/boot.img.p")
|
source_boot.sha1, "/tmp/patchtmp/boot.img.p")
|
||||||
|
so_far += target_boot.size
|
||||||
|
script.SetProgress(so_far / total_patch_size)
|
||||||
print "boot image changed; including."
|
print "boot image changed; including."
|
||||||
else:
|
else:
|
||||||
print "boot image unchanged; skipping."
|
print "boot image unchanged; skipping."
|
||||||
@@ -650,29 +746,12 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
|
|||||||
# as fodder for constructing the recovery image.
|
# as fodder for constructing the recovery image.
|
||||||
recovery_sh_item = MakeRecoveryPatch(output_zip,
|
recovery_sh_item = MakeRecoveryPatch(output_zip,
|
||||||
target_recovery, target_boot)
|
target_recovery, target_boot)
|
||||||
|
script.UnpackPackageDir("recovery", "/system")
|
||||||
print "recovery image changed; including as patch from boot."
|
print "recovery image changed; including as patch from boot."
|
||||||
else:
|
else:
|
||||||
print "recovery image unchanged; skipping."
|
print "recovery image unchanged; skipping."
|
||||||
|
|
||||||
if updating_radio:
|
script.ShowProgress(0.1, 10)
|
||||||
script.ShowProgress(0.3, 10)
|
|
||||||
script.Print("Writing radio image...")
|
|
||||||
script.WriteFirmwareImage("radio", "radio.img")
|
|
||||||
common.ZipWriteStr(output_zip, "radio.img", target_radio)
|
|
||||||
print "radio image changed; including."
|
|
||||||
else:
|
|
||||||
print "radio image unchanged; skipping."
|
|
||||||
|
|
||||||
script.Print("Patching system files...")
|
|
||||||
pb_apply = progress_bar_total * 0.7 * \
|
|
||||||
(total_patched_size /
|
|
||||||
float(total_patched_size+total_verbatim_size+1))
|
|
||||||
for i, (fn, tf, sf, size) in enumerate(patch_list):
|
|
||||||
if i % 5 == 0:
|
|
||||||
next_sizes = sum([i[3] for i in patch_list[i:i+5]])
|
|
||||||
script.ShowProgress(next_sizes * pb_apply / (total_patched_size+1), 1)
|
|
||||||
script.ApplyPatch("/"+fn, "-", tf.size, tf.sha1,
|
|
||||||
sf.sha1, "/tmp/patchtmp/"+fn+".p")
|
|
||||||
|
|
||||||
target_symlinks = CopySystemFiles(target_zip, None)
|
target_symlinks = CopySystemFiles(target_zip, None)
|
||||||
|
|
||||||
@@ -700,14 +779,10 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
|
|||||||
script.DeleteFiles(to_delete)
|
script.DeleteFiles(to_delete)
|
||||||
|
|
||||||
if verbatim_targets:
|
if verbatim_targets:
|
||||||
pb_verbatim = progress_bar_total * \
|
|
||||||
(total_verbatim_size /
|
|
||||||
float(total_patched_size+total_verbatim_size+1))
|
|
||||||
script.ShowProgress(pb_verbatim, 5)
|
|
||||||
script.Print("Unpacking new files...")
|
script.Print("Unpacking new files...")
|
||||||
script.UnpackPackageDir("system", "/system")
|
script.UnpackPackageDir("system", "/system")
|
||||||
|
|
||||||
script.Print("Finishing up...")
|
script.Print("Symlinks and permissions...")
|
||||||
|
|
||||||
# Create all the symlinks that don't already exist, or point to
|
# Create all the symlinks that don't already exist, or point to
|
||||||
# somewhere different than what we want. Delete each symlink before
|
# somewhere different than what we want. Delete each symlink before
|
||||||
@@ -726,6 +801,9 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
|
|||||||
# permissions.
|
# permissions.
|
||||||
script.AppendScript(temp_script)
|
script.AppendScript(temp_script)
|
||||||
|
|
||||||
|
# Do device-specific installation (eg, write radio image).
|
||||||
|
device_specific.IncrementalOTA_InstallEnd()
|
||||||
|
|
||||||
if OPTIONS.extra_script is not None:
|
if OPTIONS.extra_script is not None:
|
||||||
scirpt.AppendExtra(OPTIONS.extra_script)
|
scirpt.AppendExtra(OPTIONS.extra_script)
|
||||||
|
|
||||||
@@ -749,6 +827,8 @@ def main(argv):
|
|||||||
OPTIONS.extra_script = a
|
OPTIONS.extra_script = a
|
||||||
elif o in ("-m", "--script_mode"):
|
elif o in ("-m", "--script_mode"):
|
||||||
OPTIONS.script_mode = a
|
OPTIONS.script_mode = a
|
||||||
|
elif o in ("--worker_threads"):
|
||||||
|
OPTIONS.worker_threads = int(a)
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
@@ -761,7 +841,8 @@ def main(argv):
|
|||||||
"wipe_user_data",
|
"wipe_user_data",
|
||||||
"no_prereq",
|
"no_prereq",
|
||||||
"extra_script=",
|
"extra_script=",
|
||||||
"script_mode="],
|
"script_mode=",
|
||||||
|
"worker_threads="],
|
||||||
extra_option_handler=option_handler)
|
extra_option_handler=option_handler)
|
||||||
|
|
||||||
if len(args) != 2:
|
if len(args) != 2:
|
||||||
@@ -777,6 +858,23 @@ def main(argv):
|
|||||||
print "unzipping target target-files..."
|
print "unzipping target target-files..."
|
||||||
OPTIONS.input_tmp = common.UnzipTemp(args[0])
|
OPTIONS.input_tmp = common.UnzipTemp(args[0])
|
||||||
|
|
||||||
|
if OPTIONS.device_specific is None:
|
||||||
|
# look for the device-specific tools extension location in the input
|
||||||
|
try:
|
||||||
|
f = open(os.path.join(OPTIONS.input_tmp, "META", "tool-extensions.txt"))
|
||||||
|
ds = f.read().strip()
|
||||||
|
f.close()
|
||||||
|
if ds:
|
||||||
|
ds = os.path.normpath(ds)
|
||||||
|
print "using device-specific extensions in", ds
|
||||||
|
OPTIONS.device_specific = ds
|
||||||
|
except IOError, e:
|
||||||
|
if e.errno == errno.ENOENT:
|
||||||
|
# nothing specified in the file
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
common.LoadMaxSizes()
|
common.LoadMaxSizes()
|
||||||
if not OPTIONS.max_image_size:
|
if not OPTIONS.max_image_size:
|
||||||
print
|
print
|
||||||
|
@@ -20,10 +20,6 @@ target-files zip.
|
|||||||
|
|
||||||
Usage: sign_target_files_apks [flags] input_target_files output_target_files
|
Usage: sign_target_files_apks [flags] input_target_files output_target_files
|
||||||
|
|
||||||
-s (--signapk_jar) <path>
|
|
||||||
Path of the signapks.jar file used to sign an individual APK
|
|
||||||
file.
|
|
||||||
|
|
||||||
-e (--extra_apks) <name,name,...=key>
|
-e (--extra_apks) <name,name,...=key>
|
||||||
Add extra APK name/key pairs as though they appeared in
|
Add extra APK name/key pairs as though they appeared in
|
||||||
apkcerts.txt (so mappings specified by -k and -d are applied).
|
apkcerts.txt (so mappings specified by -k and -d are applied).
|
||||||
@@ -307,9 +303,7 @@ def ReplaceOtaKeys(input_tf_zip, output_tf_zip):
|
|||||||
def main(argv):
|
def main(argv):
|
||||||
|
|
||||||
def option_handler(o, a):
|
def option_handler(o, a):
|
||||||
if o in ("-s", "--signapk_jar"):
|
if o in ("-e", "--extra_apks"):
|
||||||
OPTIONS.signapk_jar = a
|
|
||||||
elif o in ("-e", "--extra_apks"):
|
|
||||||
names, key = a.split("=")
|
names, key = a.split("=")
|
||||||
names = names.split(",")
|
names = names.split(",")
|
||||||
for n in names:
|
for n in names:
|
||||||
@@ -339,9 +333,8 @@ def main(argv):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
args = common.ParseOptions(argv, __doc__,
|
args = common.ParseOptions(argv, __doc__,
|
||||||
extra_opts="s:e:d:k:ot:",
|
extra_opts="e:d:k:ot:",
|
||||||
extra_long_opts=["signapk_jar=",
|
extra_long_opts=["extra_apks=",
|
||||||
"extra_apks=",
|
|
||||||
"default_key_mappings=",
|
"default_key_mappings=",
|
||||||
"key_mapping=",
|
"key_mapping=",
|
||||||
"replace_ota_keys",
|
"replace_ota_keys",
|
||||||
|
@@ -247,7 +247,7 @@ class SignApk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write a .SF file with a digest the specified manifest. */
|
/** Write a .SF file with a digest of the specified manifest. */
|
||||||
private static void writeSignatureFile(Manifest manifest, OutputStream out)
|
private static void writeSignatureFile(Manifest manifest, OutputStream out)
|
||||||
throws IOException, GeneralSecurityException {
|
throws IOException, GeneralSecurityException {
|
||||||
Manifest sf = new Manifest();
|
Manifest sf = new Manifest();
|
||||||
@@ -304,6 +304,75 @@ class SignApk {
|
|||||||
pkcs7.encodeSignedData(out);
|
pkcs7.encodeSignedData(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void signWholeOutputFile(byte[] zipData,
|
||||||
|
OutputStream outputStream,
|
||||||
|
X509Certificate publicKey,
|
||||||
|
PrivateKey privateKey)
|
||||||
|
throws IOException, GeneralSecurityException {
|
||||||
|
|
||||||
|
// For a zip with no archive comment, the
|
||||||
|
// end-of-central-directory record will be 22 bytes long, so
|
||||||
|
// we expect to find the EOCD marker 22 bytes from the end.
|
||||||
|
if (zipData[zipData.length-22] != 0x50 ||
|
||||||
|
zipData[zipData.length-21] != 0x4b ||
|
||||||
|
zipData[zipData.length-20] != 0x05 ||
|
||||||
|
zipData[zipData.length-19] != 0x06) {
|
||||||
|
throw new IllegalArgumentException("zip data already has an archive comment");
|
||||||
|
}
|
||||||
|
|
||||||
|
Signature signature = Signature.getInstance("SHA1withRSA");
|
||||||
|
signature.initSign(privateKey);
|
||||||
|
signature.update(zipData, 0, zipData.length-2);
|
||||||
|
|
||||||
|
ByteArrayOutputStream temp = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
// put a readable message and a null char at the start of the
|
||||||
|
// archive comment, so that tools that display the comment
|
||||||
|
// (hopefully) show something sensible.
|
||||||
|
// TODO: anything more useful we can put in this message?
|
||||||
|
byte[] message = "signed by SignApk".getBytes("UTF-8");
|
||||||
|
temp.write(message);
|
||||||
|
temp.write(0);
|
||||||
|
writeSignatureBlock(signature, publicKey, temp);
|
||||||
|
int total_size = temp.size() + 6;
|
||||||
|
if (total_size > 0xffff) {
|
||||||
|
throw new IllegalArgumentException("signature is too big for ZIP file comment");
|
||||||
|
}
|
||||||
|
// signature starts this many bytes from the end of the file
|
||||||
|
int signature_start = total_size - message.length - 1;
|
||||||
|
temp.write(signature_start & 0xff);
|
||||||
|
temp.write((signature_start >> 8) & 0xff);
|
||||||
|
// Why the 0xff bytes? In a zip file with no archive comment,
|
||||||
|
// bytes [-6:-2] of the file are the little-endian offset from
|
||||||
|
// the start of the file to the central directory. So for the
|
||||||
|
// two high bytes to be 0xff 0xff, the archive would have to
|
||||||
|
// be nearly 4GB in side. So it's unlikely that a real
|
||||||
|
// commentless archive would have 0xffs here, and lets us tell
|
||||||
|
// an old signed archive from a new one.
|
||||||
|
temp.write(0xff);
|
||||||
|
temp.write(0xff);
|
||||||
|
temp.write(total_size & 0xff);
|
||||||
|
temp.write((total_size >> 8) & 0xff);
|
||||||
|
temp.flush();
|
||||||
|
|
||||||
|
// Signature verification checks that the EOCD header is the
|
||||||
|
// last such sequence in the file (to avoid minzip finding a
|
||||||
|
// fake EOCD appended after the signature in its scan). The
|
||||||
|
// odds of producing this sequence by chance are very low, but
|
||||||
|
// let's catch it here if it does.
|
||||||
|
byte[] b = temp.toByteArray();
|
||||||
|
for (int i = 0; i < b.length-3; ++i) {
|
||||||
|
if (b[i] == 0x50 && b[i+1] == 0x4b && b[i+2] == 0x05 && b[i+3] == 0x06) {
|
||||||
|
throw new IllegalArgumentException("found spurious EOCD header at " + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outputStream.write(zipData, 0, zipData.length-2);
|
||||||
|
outputStream.write(total_size & 0xff);
|
||||||
|
outputStream.write((total_size >> 8) & 0xff);
|
||||||
|
temp.writeTo(outputStream);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy all the files in a manifest from input to output. We set
|
* Copy all the files in a manifest from input to output. We set
|
||||||
* the modification times in the output to a fixed time, so as to
|
* the modification times in the output to a fixed time, so as to
|
||||||
@@ -340,25 +409,40 @@ class SignApk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
if (args.length != 4) {
|
if (args.length != 4 && args.length != 5) {
|
||||||
System.err.println("Usage: signapk " +
|
System.err.println("Usage: signapk [-w] " +
|
||||||
"publickey.x509[.pem] privatekey.pk8 " +
|
"publickey.x509[.pem] privatekey.pk8 " +
|
||||||
"input.jar output.jar");
|
"input.jar output.jar");
|
||||||
System.exit(2);
|
System.exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean signWholeFile = false;
|
||||||
|
int argstart = 0;
|
||||||
|
if (args[0].equals("-w")) {
|
||||||
|
signWholeFile = true;
|
||||||
|
argstart = 1;
|
||||||
|
}
|
||||||
|
|
||||||
JarFile inputJar = null;
|
JarFile inputJar = null;
|
||||||
JarOutputStream outputJar = null;
|
JarOutputStream outputJar = null;
|
||||||
|
FileOutputStream outputFile = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
X509Certificate publicKey = readPublicKey(new File(args[0]));
|
X509Certificate publicKey = readPublicKey(new File(args[argstart+0]));
|
||||||
|
|
||||||
// Assume the certificate is valid for at least an hour.
|
// Assume the certificate is valid for at least an hour.
|
||||||
long timestamp = publicKey.getNotBefore().getTime() + 3600L * 1000;
|
long timestamp = publicKey.getNotBefore().getTime() + 3600L * 1000;
|
||||||
|
|
||||||
PrivateKey privateKey = readPrivateKey(new File(args[1]));
|
PrivateKey privateKey = readPrivateKey(new File(args[argstart+1]));
|
||||||
inputJar = new JarFile(new File(args[2]), false); // Don't verify.
|
inputJar = new JarFile(new File(args[argstart+2]), false); // Don't verify.
|
||||||
outputJar = new JarOutputStream(new FileOutputStream(args[3]));
|
|
||||||
|
OutputStream outputStream = null;
|
||||||
|
if (signWholeFile) {
|
||||||
|
outputStream = new ByteArrayOutputStream();
|
||||||
|
} else {
|
||||||
|
outputStream = outputFile = new FileOutputStream(args[argstart+3]);
|
||||||
|
}
|
||||||
|
outputJar = new JarOutputStream(outputStream);
|
||||||
outputJar.setLevel(9);
|
outputJar.setLevel(9);
|
||||||
|
|
||||||
JarEntry je;
|
JarEntry je;
|
||||||
@@ -387,13 +471,23 @@ class SignApk {
|
|||||||
|
|
||||||
// Everything else
|
// Everything else
|
||||||
copyFiles(manifest, inputJar, outputJar, timestamp);
|
copyFiles(manifest, inputJar, outputJar, timestamp);
|
||||||
|
|
||||||
|
outputJar.close();
|
||||||
|
outputJar = null;
|
||||||
|
outputStream.flush();
|
||||||
|
|
||||||
|
if (signWholeFile) {
|
||||||
|
outputFile = new FileOutputStream(args[argstart+3]);
|
||||||
|
signWholeOutputFile(((ByteArrayOutputStream)outputStream).toByteArray(),
|
||||||
|
outputFile, publicKey, privateKey);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
if (inputJar != null) inputJar.close();
|
if (inputJar != null) inputJar.close();
|
||||||
if (outputJar != null) outputJar.close();
|
if (outputFile != null) outputFile.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
|
523
tools/warn.py
Executable file
523
tools/warn.py
Executable file
@@ -0,0 +1,523 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
if len(sys.argv) == 1:
|
||||||
|
print 'usage: ' + sys.argv[0] + ' <build.log>'
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
# if you add another level, don't forget to give it a color below
|
||||||
|
class severity:
|
||||||
|
UNKNOWN=0
|
||||||
|
SKIP=100
|
||||||
|
FIXMENOW=1
|
||||||
|
HIGH=2
|
||||||
|
MEDIUM=3
|
||||||
|
LOW=4
|
||||||
|
HARMLESS=5
|
||||||
|
|
||||||
|
def colorforseverity(sev):
|
||||||
|
if sev == severity.FIXMENOW:
|
||||||
|
return 'fuchsia'
|
||||||
|
if sev == severity.HIGH:
|
||||||
|
return 'red'
|
||||||
|
if sev == severity.MEDIUM:
|
||||||
|
return 'orange'
|
||||||
|
if sev == severity.LOW:
|
||||||
|
return 'yellow'
|
||||||
|
if sev == severity.HARMLESS:
|
||||||
|
return 'limegreen'
|
||||||
|
if sev == severity.UNKNOWN:
|
||||||
|
return 'blue'
|
||||||
|
return 'grey'
|
||||||
|
|
||||||
|
warnpatterns = [
|
||||||
|
{ 'category':'make', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'make: overriding commands/ignoring old commands',
|
||||||
|
'patterns':[r".*: warning: overriding commands for target .+",
|
||||||
|
r".*: warning: ignoring old commands for target .+"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wimplicit-function-declaration',
|
||||||
|
'description':'Implicit function declaration',
|
||||||
|
'patterns':[r".*: warning: implicit declaration of function .+"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'',
|
||||||
|
'description':'',
|
||||||
|
'patterns':[r".*: warning: conflicting types for '.+'"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wtype-limits',
|
||||||
|
'description':'Expression always evaluates to true or false',
|
||||||
|
'patterns':[r".*: warning: comparison is always false due to limited range of data type",
|
||||||
|
r".*: warning: comparison of unsigned expression >= 0 is always true",
|
||||||
|
r".*: warning: comparison of unsigned expression < 0 is always false"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Incompatible pointer types',
|
||||||
|
'patterns':[r".*: warning: assignment from incompatible pointer type",
|
||||||
|
r".*: warning: passing argument [0-9]+ of '.*' from incompatible pointer type",
|
||||||
|
r".*: warning: initialization from incompatible pointer type"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-fno-builtin',
|
||||||
|
'description':'Incompatible declaration of built in function',
|
||||||
|
'patterns':[r".*: warning: incompatible implicit declaration of built-in function .+"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunused-parameter',
|
||||||
|
'description':'Unused parameter',
|
||||||
|
'patterns':[r".*: warning: unused parameter '.*'"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunused',
|
||||||
|
'description':'Unused function, variable or label',
|
||||||
|
'patterns':[r".*: warning: '.+' defined but not used"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunused-value',
|
||||||
|
'description':'Statement with no effect',
|
||||||
|
'patterns':[r".*: warning: statement with no effect"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmissing-field-initializers',
|
||||||
|
'description':'Missing initializer',
|
||||||
|
'patterns':[r".*: warning: missing initializer"] },
|
||||||
|
{ 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
|
||||||
|
'description':'',
|
||||||
|
'patterns':[r".*: warning: \(near initialization for '.+'\)"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wformat',
|
||||||
|
'description':'Format string does not match arguments',
|
||||||
|
'patterns':[r".*: warning: format '.+' expects type '.+', but argument [0-9]+ has type '.+'"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wformat-extra-args',
|
||||||
|
'description':'Too many arguments for format string',
|
||||||
|
'patterns':[r".*: warning: too many arguments for format"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wsign-compare',
|
||||||
|
'description':'Comparison between signed and unsigned',
|
||||||
|
'patterns':[r".*: warning: comparison between signed and unsigned",
|
||||||
|
r".*: warning: comparison of promoted \~unsigned with unsigned",
|
||||||
|
r".*: warning: signed and unsigned type in conditional expression"] },
|
||||||
|
{ 'category':'libpng', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'libpng: zero area',
|
||||||
|
'patterns':[r".*libpng warning: Ignoring attempt to set cHRM RGB triangle with zero area"] },
|
||||||
|
{ 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'aapt: no comment for public symbol',
|
||||||
|
'patterns':[r".*: warning: No comment for public symbol .+"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmissing-braces',
|
||||||
|
'description':'Missing braces around initializer',
|
||||||
|
'patterns':[r".*: warning: missing braces around initializer.*"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.HARMLESS, 'members':[], 'option':'',
|
||||||
|
'description':'No newline at end of file',
|
||||||
|
'patterns':[r".*: warning: no newline at end of file"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wcast-qual',
|
||||||
|
'description':'Qualifier discarded',
|
||||||
|
'patterns':[r".*: warning: passing argument [0-9]+ of '.+' discards qualifiers from pointer target type",
|
||||||
|
r".*: warning: assignment discards qualifiers from pointer target type",
|
||||||
|
r".*: warning: return discards qualifiers from pointer target type"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wattributes',
|
||||||
|
'description':'Attribute ignored',
|
||||||
|
'patterns':[r".*: warning: '_*packed_*' attribute ignored"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wattributes',
|
||||||
|
'description':'Visibility mismatch',
|
||||||
|
'patterns':[r".*: warning: '.+' declared with greater visibility than the type of its field '.+'"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Shift count greater than width of type',
|
||||||
|
'patterns':[r".*: warning: (left|right) shift count >= width of type"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'extern <foo> is initialized',
|
||||||
|
'patterns':[r".*: warning: '.+' initialized and declared 'extern'"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wold-style-declaration',
|
||||||
|
'description':'Old style declaration',
|
||||||
|
'patterns':[r".*: warning: 'static' is not at beginning of declaration"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wuninitialized',
|
||||||
|
'description':'Variable may be used uninitialized',
|
||||||
|
'patterns':[r".*: warning: '.+' may be used uninitialized in this function"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wuninitialized',
|
||||||
|
'description':'Variable is used uninitialized',
|
||||||
|
'patterns':[r".*: warning: '.+' is used uninitialized in this function"] },
|
||||||
|
{ 'category':'ld', 'severity':severity.MEDIUM, 'members':[], 'option':'-fshort-enums',
|
||||||
|
'description':'ld: possible enum size mismatch',
|
||||||
|
'patterns':[r".*: warning: .* uses variable-size enums yet the output is to use 32-bit enums; use of enum values across objects may fail"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wpointer-sign',
|
||||||
|
'description':'Pointer targets differ in signedness',
|
||||||
|
'patterns':[r".*: warning: pointer targets in initialization differ in signedness",
|
||||||
|
r".*: warning: pointer targets in assignment differ in signedness",
|
||||||
|
r".*: warning: pointer targets in return differ in signedness",
|
||||||
|
r".*: warning: pointer targets in passing argument [0-9]+ of '.+' differ in signedness"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wstrict-overflow',
|
||||||
|
'description':'Assuming overflow does not occur',
|
||||||
|
'patterns':[r".*: warning: assuming signed overflow does not occur when assuming that .* is always (true|false)"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wempty-body',
|
||||||
|
'description':'Suggest adding braces around empty body',
|
||||||
|
'patterns':[r".*: warning: suggest braces around empty body in an 'if' statement",
|
||||||
|
r".*: warning: empty body in an if-statement",
|
||||||
|
r".*: warning: suggest braces around empty body in an 'else' statement",
|
||||||
|
r".*: warning: empty body in an else-statement"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wparentheses',
|
||||||
|
'description':'Suggest adding parentheses',
|
||||||
|
'patterns':[r".*: warning: suggest explicit braces to avoid ambiguous 'else'",
|
||||||
|
r".*: warning: suggest parentheses around arithmetic in operand of '.+'",
|
||||||
|
r".*: warning: suggest parentheses around comparison in operand of '.+'",
|
||||||
|
r".*: warning: suggest parentheses around '.+?' .+ '.+?'",
|
||||||
|
r".*: warning: suggest parentheses around assignment used as truth value"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Static variable used in non-static inline function',
|
||||||
|
'patterns':[r".*: warning: '.+' is static but used in inline function '.+' which is not static"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wimplicit int',
|
||||||
|
'description':'No type or storage class (will default to int)',
|
||||||
|
'patterns':[r".*: warning: data definition has no type or storage class"] },
|
||||||
|
{ 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
|
||||||
|
'description':'',
|
||||||
|
'patterns':[r".*: warning: type defaults to 'int' in declaration of '.+'"] },
|
||||||
|
{ 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
|
||||||
|
'description':'',
|
||||||
|
'patterns':[r".*: warning: parameter names \(without types\) in function declaration"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wstrict-aliasing',
|
||||||
|
'description':'Dereferencing <foo> breaks strict aliasing rules',
|
||||||
|
'patterns':[r".*: warning: dereferencing .* break strict-aliasing rules"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wpointer-to-int-cast',
|
||||||
|
'description':'Cast from pointer to integer of different size',
|
||||||
|
'patterns':[r".*: warning: cast from pointer to integer of different size"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wint-to-pointer-cast',
|
||||||
|
'description':'Cast to pointer from integer of different size',
|
||||||
|
'patterns':[r".*: warning: cast to pointer from integer of different size"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Symbol redefined',
|
||||||
|
'patterns':[r".*: warning: "".+"" redefined"] },
|
||||||
|
{ 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
|
||||||
|
'description':'',
|
||||||
|
'patterns':[r".*: warning: this is the location of the previous definition"] },
|
||||||
|
{ 'category':'ld', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'ld: type and size of dynamic symbol are not defined',
|
||||||
|
'patterns':[r".*: warning: type and size of dynamic symbol `.+' are not defined"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Pointer from integer without cast',
|
||||||
|
'patterns':[r".*: warning: assignment makes pointer from integer without a cast"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Pointer from integer without cast',
|
||||||
|
'patterns':[r".*: warning: passing argument [0-9]+ of '.+' makes pointer from integer without a cast"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Integer from pointer without cast',
|
||||||
|
'patterns':[r".*: warning: assignment makes integer from pointer without a cast"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Integer from pointer without cast',
|
||||||
|
'patterns':[r".*: warning: passing argument [0-9]+ of '.+' makes integer from pointer without a cast"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Integer from pointer without cast',
|
||||||
|
'patterns':[r".*: warning: return makes integer from pointer without a cast"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunknown-pragmas',
|
||||||
|
'description':'Ignoring pragma',
|
||||||
|
'patterns':[r".*: warning: ignoring #pragma .+"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wclobbered',
|
||||||
|
'description':'Variable might be clobbered by longjmp or vfork',
|
||||||
|
'patterns':[r".*: warning: variable '.+' might be clobbered by 'longjmp' or 'vfork'"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wclobbered',
|
||||||
|
'description':'Argument might be clobbered by longjmp or vfork',
|
||||||
|
'patterns':[r".*: warning: argument '.+' might be clobbered by 'longjmp' or 'vfork'"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wredundant-decls',
|
||||||
|
'description':'Redundant declaration',
|
||||||
|
'patterns':[r".*: warning: redundant redeclaration of '.+'"] },
|
||||||
|
{ 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
|
||||||
|
'description':'',
|
||||||
|
'patterns':[r".*: warning: previous declaration of '.+' was here"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wswitch-enum',
|
||||||
|
'description':'Enum value not handled in switch',
|
||||||
|
'patterns':[r".*: warning: enumeration value '.+' not handled in switch"] },
|
||||||
|
{ 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'-encoding',
|
||||||
|
'description':'Java: Non-ascii characters used, but ascii encoding specified',
|
||||||
|
'patterns':[r".*: warning: unmappable character for encoding ascii"] },
|
||||||
|
{ 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Java: Non-varargs call of varargs method with inexact argument type for last parameter',
|
||||||
|
'patterns':[r".*: warning: non-varargs call of varargs method with inexact argument type for last parameter"] },
|
||||||
|
{ 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'aapt: String marked untranslatable, but translation exists',
|
||||||
|
'patterns':[r".*: warning: string '.+' in .* marked untranslatable but exists in locale '??_??'"] },
|
||||||
|
{ 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'aapt: empty span in string',
|
||||||
|
'patterns':[r".*: warning: empty '.+' span found in text '.+"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Taking address of temporary',
|
||||||
|
'patterns':[r".*: warning: taking address of temporary"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Possible broken line continuation',
|
||||||
|
'patterns':[r".*: warning: backslash and newline separated by space"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Warray-bounds',
|
||||||
|
'description':'Array subscript out of bounds',
|
||||||
|
'patterns':[r".*: warning: array subscript is above array bounds"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Decimal constant is unsigned only in ISO C90',
|
||||||
|
'patterns':[r".*: warning: this decimal constant is unsigned only in ISO C90"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmain',
|
||||||
|
'description':'main is usually a function',
|
||||||
|
'patterns':[r".*: warning: 'main' is usually a function"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Typedef ignored',
|
||||||
|
'patterns':[r".*: warning: 'typedef' was ignored in this declaration"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Waddress',
|
||||||
|
'description':'Address always evaluates to true',
|
||||||
|
'patterns':[r".*: warning: the address of '.+' will always evaluate as 'true'"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.FIXMENOW, 'members':[], 'option':'',
|
||||||
|
'description':'Freeing a non-heap object',
|
||||||
|
'patterns':[r".*: warning: attempt to free a non-heap object '.+'"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wchar-subscripts',
|
||||||
|
'description':'Array subscript has type char',
|
||||||
|
'patterns':[r".*: warning: array subscript has type 'char'"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Constant too large for type',
|
||||||
|
'patterns':[r".*: warning: integer constant is too large for '.+' type"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Woverflow',
|
||||||
|
'description':'Constant too large for type, truncated',
|
||||||
|
'patterns':[r".*: warning: large integer implicitly truncated to unsigned type"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Woverflow',
|
||||||
|
'description':'Overflow in implicit constant conversion',
|
||||||
|
'patterns':[r".*: warning: overflow in implicit constant conversion"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Declaration does not declare anything',
|
||||||
|
'patterns':[r".*: warning: declaration 'class .+' does not declare anything"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wreorder',
|
||||||
|
'description':'Initialization order will be different',
|
||||||
|
'patterns':[r".*: warning: '.+' will be initialized after"] },
|
||||||
|
{ 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
|
||||||
|
'description':'',
|
||||||
|
'patterns':[r".*: warning: '.+'"] },
|
||||||
|
{ 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
|
||||||
|
'description':'',
|
||||||
|
'patterns':[r".*: warning: when initialized here"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmissing-parameter-type',
|
||||||
|
'description':'Parameter type not specified',
|
||||||
|
'patterns':[r".*: warning: type of '.+' defaults to 'int'"] },
|
||||||
|
{ 'category':'gcc', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Invalid option for C file',
|
||||||
|
'patterns':[r".*: warning: command line option "".+"" is valid for C\+\+\/ObjC\+\+ but not for C"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'User warning',
|
||||||
|
'patterns':[r".*: warning: #warning "".+"""] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wextra',
|
||||||
|
'description':'Dereferencing void*',
|
||||||
|
'patterns':[r".*: warning: dereferencing 'void \*' pointer"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wextra',
|
||||||
|
'description':'Comparison of pointer to zero',
|
||||||
|
'patterns':[r".*: warning: ordered comparison of pointer with integer zero"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wwrite-strings',
|
||||||
|
'description':'Conversion of string constant to non-const char*',
|
||||||
|
'patterns':[r".*: warning: deprecated conversion from string constant to '.+'"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wstrict-prototypes',
|
||||||
|
'description':'Function declaration isn''t a prototype',
|
||||||
|
'patterns':[r".*: warning: function declaration isn't a prototype"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wignored-qualifiers',
|
||||||
|
'description':'Type qualifiers ignored on function return value',
|
||||||
|
'patterns':[r".*: warning: type qualifiers ignored on function return type"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'<foo> declared inside parameter list, scope limited to this definition',
|
||||||
|
'patterns':[r".*: warning: '.+' declared inside parameter list"] },
|
||||||
|
{ 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
|
||||||
|
'description':'',
|
||||||
|
'patterns':[r".*: warning: its scope is only this definition or declaration, which is probably not what you want"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'-Wcomment',
|
||||||
|
'description':'Line continuation inside comment',
|
||||||
|
'patterns':[r".*: warning: multi-line comment"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.HARMLESS, 'members':[], 'option':'',
|
||||||
|
'description':'Extra tokens after #endif',
|
||||||
|
'patterns':[r".*: warning: extra tokens at end of #endif directive"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wenum-compare',
|
||||||
|
'description':'Comparison between different enums',
|
||||||
|
'patterns':[r".*: warning: comparison between 'enum .+' and 'enum .+'"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wconversion',
|
||||||
|
'description':'Implicit conversion of negative number to unsigned type',
|
||||||
|
'patterns':[r".*: warning: converting negative value '.+' to '.+'"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Passing NULL as non-pointer argument',
|
||||||
|
'patterns':[r".*: warning: passing NULL to non-pointer argument [0-9]+ of '.+'"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wctor-dtor-privacy',
|
||||||
|
'description':'Class seems unusable because of private ctor/dtor' ,
|
||||||
|
'patterns':[r".*: warning: all member functions in class '.+' are private"] },
|
||||||
|
# skip this next one, because it only points out some RefBase-based classes where having a private destructor is perfectly fine
|
||||||
|
{ 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'-Wctor-dtor-privacy',
|
||||||
|
'description':'Class seems unusable because of private ctor/dtor' ,
|
||||||
|
'patterns':[r".*: warning: 'class .+' only defines a private destructor and has no friends"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wctor-dtor-privacy',
|
||||||
|
'description':'Class seems unusable because of private ctor/dtor' ,
|
||||||
|
'patterns':[r".*: warning: 'class .+' only defines private constructors and has no friends"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wpointer-arith',
|
||||||
|
'description':'void* used in arithmetic' ,
|
||||||
|
'patterns':[r".*: warning: pointer of type 'void \*' used in (arithmetic|subtraction)",
|
||||||
|
r".*: warning: wrong type argument to increment"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wsign-promo',
|
||||||
|
'description':'Overload resolution chose to promote from unsigned or enum to signed type' ,
|
||||||
|
'patterns':[r".*: warning: passing '.+' chooses 'int' over '.* int'"] },
|
||||||
|
{ 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
|
||||||
|
'description':'',
|
||||||
|
'patterns':[r".*: warning: in call to '.+'"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wextra',
|
||||||
|
'description':'Base should be explicitly initialized in copy constructor',
|
||||||
|
'patterns':[r".*: warning: base class '.+' should be explicitly initialized in the copy constructor"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
'description':'Converting from <type> to <other type>',
|
||||||
|
'patterns':[r".*: warning: converting to '.+' from '.+'"] },
|
||||||
|
|
||||||
|
# these next ones are to deal with formatting problems resulting from the log being mixed up by 'make -j'
|
||||||
|
{ 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'',
|
||||||
|
'description':'',
|
||||||
|
'patterns':[r".*: warning: ,$"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'',
|
||||||
|
'description':'',
|
||||||
|
'patterns':[r".*: warning: $"] },
|
||||||
|
{ 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'',
|
||||||
|
'description':'',
|
||||||
|
'patterns':[r".*: warning: In file included from .+,"] },
|
||||||
|
|
||||||
|
# catch-all for warnings this script doesn't know about yet
|
||||||
|
{ 'category':'C/C++', 'severity':severity.UNKNOWN, 'members':[], 'option':'',
|
||||||
|
'description':'Unclassified/unrecognized warnings',
|
||||||
|
'patterns':[r".*: warning: .+"] },
|
||||||
|
]
|
||||||
|
|
||||||
|
anchor = 0
|
||||||
|
cur_row_color = 0
|
||||||
|
row_colors = [ 'e0e0e0', 'd0d0d0' ]
|
||||||
|
|
||||||
|
def output(text):
|
||||||
|
print text,
|
||||||
|
|
||||||
|
def htmlbig(param):
|
||||||
|
return '<font size="+2">' + param + '</font>'
|
||||||
|
|
||||||
|
def dumphtmlprologue(title):
|
||||||
|
output('<html>\n<head>\n<title>' + title + '</title>\n<body>\n')
|
||||||
|
output(htmlbig(title))
|
||||||
|
output('<p>\n')
|
||||||
|
|
||||||
|
def tablerow(text):
|
||||||
|
global cur_row_color
|
||||||
|
output('<tr bgcolor="' + row_colors[cur_row_color] + '"><td colspan="2">',)
|
||||||
|
cur_row_color = 1 - cur_row_color
|
||||||
|
output(text,)
|
||||||
|
output('</td></tr>')
|
||||||
|
|
||||||
|
def begintable(text, backgroundcolor):
|
||||||
|
global anchor
|
||||||
|
output('<table border="1" rules="cols" frame="box" width="100%" bgcolor="black"><tr bgcolor="' +
|
||||||
|
backgroundcolor + '"><a name="anchor' + str(anchor) + '"><td>')
|
||||||
|
output(htmlbig(text[0]) + '<br>')
|
||||||
|
for i in text[1:]:
|
||||||
|
output(i + '<br>')
|
||||||
|
output('</td>')
|
||||||
|
output('<td width="100" bgcolor="grey"><a align="right" href="#anchor' + str(anchor-1) +
|
||||||
|
'">previous</a><br><a align="right" href="#anchor' + str(anchor+1) + '">next</a>')
|
||||||
|
output('</td></a></tr>')
|
||||||
|
anchor += 1
|
||||||
|
|
||||||
|
def endtable():
|
||||||
|
output('</table><p>')
|
||||||
|
|
||||||
|
|
||||||
|
# dump some stats about total number of warnings and such
|
||||||
|
def dumpstats():
|
||||||
|
known = 0
|
||||||
|
unknown = 0
|
||||||
|
for i in warnpatterns:
|
||||||
|
if i['severity'] == severity.UNKNOWN:
|
||||||
|
unknown += len(i['members'])
|
||||||
|
elif i['severity'] != severity.SKIP:
|
||||||
|
known += len(i['members'])
|
||||||
|
output('Number of classified warnings: <b>' + str(known) + '</b><br>' )
|
||||||
|
output('Number of unclassified warnings: <b>' + str(unknown) + '</b><br>')
|
||||||
|
total = unknown + known
|
||||||
|
output('Total number of warnings: <b>' + str(total) + '</b>')
|
||||||
|
if total < 1000:
|
||||||
|
output('(low count may indicate incremental build)')
|
||||||
|
output('<p>')
|
||||||
|
|
||||||
|
def allpatterns(cat):
|
||||||
|
pats = ''
|
||||||
|
for i in cat['patterns']:
|
||||||
|
pats += i
|
||||||
|
pats += ' / '
|
||||||
|
return pats
|
||||||
|
|
||||||
|
def descriptionfor(cat):
|
||||||
|
if cat['description'] != '':
|
||||||
|
return cat['description']
|
||||||
|
return allpatterns(cat)
|
||||||
|
|
||||||
|
|
||||||
|
# show which warnings no longer occur
|
||||||
|
def dumpfixed():
|
||||||
|
tablestarted = False
|
||||||
|
for i in warnpatterns:
|
||||||
|
if len(i['members']) == 0 and i['severity'] != severity.SKIP:
|
||||||
|
if tablestarted == False:
|
||||||
|
tablestarted = True
|
||||||
|
begintable(['Fixed warnings', 'No more occurences. Please consider turning these in to errors if possible, before they are reintroduced in to the build'], 'blue')
|
||||||
|
tablerow(i['description'] + ' (' + allpatterns(i) + ') ' + i['option'])
|
||||||
|
if tablestarted:
|
||||||
|
endtable()
|
||||||
|
|
||||||
|
|
||||||
|
# dump a category, provided it is not marked as 'SKIP' and has more than 0 occurrences
|
||||||
|
def dumpcategory(cat):
|
||||||
|
if cat['severity'] != severity.SKIP and len(cat['members']) != 0:
|
||||||
|
header = [descriptionfor(cat),str(len(cat['members'])) + ' occurences:']
|
||||||
|
if cat['option'] != '':
|
||||||
|
header[1:1] = [' (related option: ' + cat['option'] +')']
|
||||||
|
begintable(header, colorforseverity(cat['severity']))
|
||||||
|
for i in cat['members']:
|
||||||
|
tablerow(i)
|
||||||
|
endtable()
|
||||||
|
|
||||||
|
|
||||||
|
# dump everything for a given severity
|
||||||
|
def dumpseverity(sev):
|
||||||
|
for i in warnpatterns:
|
||||||
|
if i['severity'] == sev:
|
||||||
|
dumpcategory(i)
|
||||||
|
|
||||||
|
|
||||||
|
def classifywarning(line):
|
||||||
|
for i in warnpatterns:
|
||||||
|
for cpat in i['compiledpatterns']:
|
||||||
|
if cpat.match(line):
|
||||||
|
i['members'].append(line)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
# If we end up here, there was a problem parsing the log
|
||||||
|
# probably caused by 'make -j' mixing the output from
|
||||||
|
# 2 or more concurrent compiles
|
||||||
|
pass
|
||||||
|
|
||||||
|
# precompiling every pattern speeds up parsing by about 30x
|
||||||
|
def compilepatterns():
|
||||||
|
for i in warnpatterns:
|
||||||
|
i['compiledpatterns'] = []
|
||||||
|
for pat in i['patterns']:
|
||||||
|
i['compiledpatterns'].append(re.compile(pat))
|
||||||
|
|
||||||
|
infile = open(sys.argv[1], 'r')
|
||||||
|
warnings = []
|
||||||
|
|
||||||
|
platformversion = 'unknown'
|
||||||
|
targetproduct = 'unknown'
|
||||||
|
targetvariant = 'unknown'
|
||||||
|
linecounter = 0
|
||||||
|
|
||||||
|
warningpattern = re.compile('.* warning:.*')
|
||||||
|
compilepatterns()
|
||||||
|
|
||||||
|
# read the log file and classify all the warnings
|
||||||
|
lastmatchedline = ''
|
||||||
|
for line in infile:
|
||||||
|
if warningpattern.match(line):
|
||||||
|
if line != lastmatchedline:
|
||||||
|
classifywarning(line)
|
||||||
|
lastmatchedline = line
|
||||||
|
else:
|
||||||
|
# save a little bit of time by only doing this for the first few lines
|
||||||
|
if linecounter < 50:
|
||||||
|
linecounter +=1
|
||||||
|
m = re.search('(?<=^PLATFORM_VERSION=).*', line)
|
||||||
|
if m != None:
|
||||||
|
platformversion = m.group(0)
|
||||||
|
m = re.search('(?<=^TARGET_PRODUCT=).*', line)
|
||||||
|
if m != None:
|
||||||
|
targetproduct = m.group(0)
|
||||||
|
m = re.search('(?<=^TARGET_BUILD_VARIANT=).*', line)
|
||||||
|
if m != None:
|
||||||
|
targetvariant = m.group(0)
|
||||||
|
|
||||||
|
|
||||||
|
# dump the html output to stdout
|
||||||
|
dumphtmlprologue('Warnings for ' + platformversion + ' - ' + targetproduct + ' - ' + targetvariant)
|
||||||
|
dumpstats()
|
||||||
|
dumpseverity(severity.FIXMENOW)
|
||||||
|
dumpseverity(severity.HIGH)
|
||||||
|
dumpseverity(severity.MEDIUM)
|
||||||
|
dumpseverity(severity.LOW)
|
||||||
|
dumpseverity(severity.HARMLESS)
|
||||||
|
dumpseverity(severity.UNKNOWN)
|
||||||
|
dumpfixed()
|
||||||
|
|
@@ -8,7 +8,9 @@ LOCAL_PATH:= $(call my-dir)
|
|||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
LOCAL_SRC_FILES := \
|
LOCAL_SRC_FILES := \
|
||||||
ZipAlign.cpp
|
ZipAlign.cpp \
|
||||||
|
ZipEntry.cpp \
|
||||||
|
ZipFile.cpp
|
||||||
|
|
||||||
LOCAL_C_INCLUDES += external/zlib
|
LOCAL_C_INCLUDES += external/zlib
|
||||||
|
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
zipalign -- zip archive alignment tool
|
zipalign -- zip archive alignment tool
|
||||||
|
|
||||||
usage: zipalign [-f] [-v] <align> infile.zip outfile.zip
|
usage: zipalign [-f] [-v] <align> infile.zip outfile.zip
|
||||||
|
zipalign -c [-v] <align> infile.zip
|
||||||
|
|
||||||
|
-c : check alignment only (does not modify file)
|
||||||
-f : overwrite existing outfile.zip
|
-f : overwrite existing outfile.zip
|
||||||
-v : verbose output
|
-v : verbose output
|
||||||
<align> is in bytes, e.g. "4" provides 32-bit alignment
|
<align> is in bytes, e.g. "4" provides 32-bit alignment
|
||||||
@@ -29,3 +31,5 @@ entries. Files added to an "aligned" archive will not be aligned.
|
|||||||
By default, zipalign will not overwrite an existing output file. With the
|
By default, zipalign will not overwrite an existing output file. With the
|
||||||
"-f" flag, an existing file will be overwritten.
|
"-f" flag, an existing file will be overwritten.
|
||||||
|
|
||||||
|
You can use the "-c" flag to test whether a zip archive is properly aligned.
|
||||||
|
|
||||||
|
@@ -13,10 +13,11 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Zip alignment tool
|
* Zip alignment tool
|
||||||
*/
|
*/
|
||||||
#include "utils/ZipFile.h"
|
#include "ZipFile.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -29,9 +30,15 @@ using namespace android;
|
|||||||
void usage(void)
|
void usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Zip alignment utility\n");
|
fprintf(stderr, "Zip alignment utility\n");
|
||||||
|
fprintf(stderr, "Copyright (C) 2009 The Android Open Source Project\n\n");
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Usage: zipalign [-f] [-v] <align> infile.zip outfile.zip\n"
|
"Usage: zipalign [-f] [-v] <align> infile.zip outfile.zip\n"
|
||||||
" zipalign -c [-v] <align> infile.zip\n" );
|
" zipalign -c [-v] <align> infile.zip\n\n" );
|
||||||
|
fprintf(stderr,
|
||||||
|
" <align>: alignment in bytes, e.g. '4' provides 32-bit alignment\n");
|
||||||
|
fprintf(stderr, " -c: check alignment only (does not modify file)\n");
|
||||||
|
fprintf(stderr, " -f: overwrite existing outfile.zip\n");
|
||||||
|
fprintf(stderr, " -v: verbose output\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
696
tools/zipalign/ZipEntry.cpp
Normal file
696
tools/zipalign/ZipEntry.cpp
Normal file
@@ -0,0 +1,696 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2006 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Access to entries in a Zip archive.
|
||||||
|
//
|
||||||
|
|
||||||
|
#define LOG_TAG "zip"
|
||||||
|
|
||||||
|
#include "ZipEntry.h"
|
||||||
|
#include <utils/Log.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
using namespace android;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize a new ZipEntry structure from a FILE* positioned at a
|
||||||
|
* CentralDirectoryEntry.
|
||||||
|
*
|
||||||
|
* On exit, the file pointer will be at the start of the next CDE or
|
||||||
|
* at the EOCD.
|
||||||
|
*/
|
||||||
|
status_t ZipEntry::initFromCDE(FILE* fp)
|
||||||
|
{
|
||||||
|
status_t result;
|
||||||
|
long posn;
|
||||||
|
bool hasDD;
|
||||||
|
|
||||||
|
//LOGV("initFromCDE ---\n");
|
||||||
|
|
||||||
|
/* read the CDE */
|
||||||
|
result = mCDE.read(fp);
|
||||||
|
if (result != NO_ERROR) {
|
||||||
|
LOGD("mCDE.read failed\n");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//mCDE.dump();
|
||||||
|
|
||||||
|
/* using the info in the CDE, go load up the LFH */
|
||||||
|
posn = ftell(fp);
|
||||||
|
if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {
|
||||||
|
LOGD("local header seek failed (%ld)\n",
|
||||||
|
mCDE.mLocalHeaderRelOffset);
|
||||||
|
return UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = mLFH.read(fp);
|
||||||
|
if (result != NO_ERROR) {
|
||||||
|
LOGD("mLFH.read failed\n");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fseek(fp, posn, SEEK_SET) != 0)
|
||||||
|
return UNKNOWN_ERROR;
|
||||||
|
|
||||||
|
//mLFH.dump();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We *might* need to read the Data Descriptor at this point and
|
||||||
|
* integrate it into the LFH. If this bit is set, the CRC-32,
|
||||||
|
* compressed size, and uncompressed size will be zero. In practice
|
||||||
|
* these seem to be rare.
|
||||||
|
*/
|
||||||
|
hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0;
|
||||||
|
if (hasDD) {
|
||||||
|
// do something clever
|
||||||
|
//LOGD("+++ has data descriptor\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sanity-check the LFH. Note that this will fail if the "kUsesDataDescr"
|
||||||
|
* flag is set, because the LFH is incomplete. (Not a problem, since we
|
||||||
|
* prefer the CDE values.)
|
||||||
|
*/
|
||||||
|
if (!hasDD && !compareHeaders()) {
|
||||||
|
LOGW("WARNING: header mismatch\n");
|
||||||
|
// keep going?
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the mVersionToExtract is greater than 20, we may have an
|
||||||
|
* issue unpacking the record -- could be encrypted, compressed
|
||||||
|
* with something we don't support, or use Zip64 extensions. We
|
||||||
|
* can defer worrying about that to when we're extracting data.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize a new entry. Pass in the file name and an optional comment.
|
||||||
|
*
|
||||||
|
* Initializes the CDE and the LFH.
|
||||||
|
*/
|
||||||
|
void ZipEntry::initNew(const char* fileName, const char* comment)
|
||||||
|
{
|
||||||
|
assert(fileName != NULL && *fileName != '\0'); // name required
|
||||||
|
|
||||||
|
/* most fields are properly initialized by constructor */
|
||||||
|
mCDE.mVersionMadeBy = kDefaultMadeBy;
|
||||||
|
mCDE.mVersionToExtract = kDefaultVersion;
|
||||||
|
mCDE.mCompressionMethod = kCompressStored;
|
||||||
|
mCDE.mFileNameLength = strlen(fileName);
|
||||||
|
if (comment != NULL)
|
||||||
|
mCDE.mFileCommentLength = strlen(comment);
|
||||||
|
mCDE.mExternalAttrs = 0x81b60020; // matches what WinZip does
|
||||||
|
|
||||||
|
if (mCDE.mFileNameLength > 0) {
|
||||||
|
mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];
|
||||||
|
strcpy((char*) mCDE.mFileName, fileName);
|
||||||
|
}
|
||||||
|
if (mCDE.mFileCommentLength > 0) {
|
||||||
|
/* TODO: stop assuming null-terminated ASCII here? */
|
||||||
|
mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];
|
||||||
|
strcpy((char*) mCDE.mFileComment, comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
copyCDEtoLFH();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize a new entry, starting with the ZipEntry from a different
|
||||||
|
* archive.
|
||||||
|
*
|
||||||
|
* Initializes the CDE and the LFH.
|
||||||
|
*/
|
||||||
|
status_t ZipEntry::initFromExternal(const ZipFile* pZipFile,
|
||||||
|
const ZipEntry* pEntry)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Copy everything in the CDE over, then fix up the hairy bits.
|
||||||
|
*/
|
||||||
|
memcpy(&mCDE, &pEntry->mCDE, sizeof(mCDE));
|
||||||
|
|
||||||
|
if (mCDE.mFileNameLength > 0) {
|
||||||
|
mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];
|
||||||
|
if (mCDE.mFileName == NULL)
|
||||||
|
return NO_MEMORY;
|
||||||
|
strcpy((char*) mCDE.mFileName, (char*)pEntry->mCDE.mFileName);
|
||||||
|
}
|
||||||
|
if (mCDE.mFileCommentLength > 0) {
|
||||||
|
mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];
|
||||||
|
if (mCDE.mFileComment == NULL)
|
||||||
|
return NO_MEMORY;
|
||||||
|
strcpy((char*) mCDE.mFileComment, (char*)pEntry->mCDE.mFileComment);
|
||||||
|
}
|
||||||
|
if (mCDE.mExtraFieldLength > 0) {
|
||||||
|
/* we null-terminate this, though it may not be a string */
|
||||||
|
mCDE.mExtraField = new unsigned char[mCDE.mExtraFieldLength+1];
|
||||||
|
if (mCDE.mExtraField == NULL)
|
||||||
|
return NO_MEMORY;
|
||||||
|
memcpy(mCDE.mExtraField, pEntry->mCDE.mExtraField,
|
||||||
|
mCDE.mExtraFieldLength+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* construct the LFH from the CDE */
|
||||||
|
copyCDEtoLFH();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The LFH "extra" field is independent of the CDE "extra", so we
|
||||||
|
* handle it here.
|
||||||
|
*/
|
||||||
|
assert(mLFH.mExtraField == NULL);
|
||||||
|
mLFH.mExtraFieldLength = pEntry->mLFH.mExtraFieldLength;
|
||||||
|
if (mLFH.mExtraFieldLength > 0) {
|
||||||
|
mLFH.mExtraField = new unsigned char[mLFH.mExtraFieldLength+1];
|
||||||
|
if (mLFH.mExtraField == NULL)
|
||||||
|
return NO_MEMORY;
|
||||||
|
memcpy(mLFH.mExtraField, pEntry->mLFH.mExtraField,
|
||||||
|
mLFH.mExtraFieldLength+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Insert pad bytes in the LFH by tweaking the "extra" field. This will
|
||||||
|
* potentially confuse something that put "extra" data in here earlier,
|
||||||
|
* but I can't find an actual problem.
|
||||||
|
*/
|
||||||
|
status_t ZipEntry::addPadding(int padding)
|
||||||
|
{
|
||||||
|
if (padding <= 0)
|
||||||
|
return INVALID_OPERATION;
|
||||||
|
|
||||||
|
//LOGI("HEY: adding %d pad bytes to existing %d in %s\n",
|
||||||
|
// padding, mLFH.mExtraFieldLength, mCDE.mFileName);
|
||||||
|
|
||||||
|
if (mLFH.mExtraFieldLength > 0) {
|
||||||
|
/* extend existing field */
|
||||||
|
unsigned char* newExtra;
|
||||||
|
|
||||||
|
newExtra = new unsigned char[mLFH.mExtraFieldLength + padding];
|
||||||
|
if (newExtra == NULL)
|
||||||
|
return NO_MEMORY;
|
||||||
|
memset(newExtra + mLFH.mExtraFieldLength, 0, padding);
|
||||||
|
memcpy(newExtra, mLFH.mExtraField, mLFH.mExtraFieldLength);
|
||||||
|
|
||||||
|
delete[] mLFH.mExtraField;
|
||||||
|
mLFH.mExtraField = newExtra;
|
||||||
|
mLFH.mExtraFieldLength += padding;
|
||||||
|
} else {
|
||||||
|
/* create new field */
|
||||||
|
mLFH.mExtraField = new unsigned char[padding];
|
||||||
|
memset(mLFH.mExtraField, 0, padding);
|
||||||
|
mLFH.mExtraFieldLength = padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the fields in the LFH equal to the corresponding fields in the CDE.
|
||||||
|
*
|
||||||
|
* This does not touch the LFH "extra" field.
|
||||||
|
*/
|
||||||
|
void ZipEntry::copyCDEtoLFH(void)
|
||||||
|
{
|
||||||
|
mLFH.mVersionToExtract = mCDE.mVersionToExtract;
|
||||||
|
mLFH.mGPBitFlag = mCDE.mGPBitFlag;
|
||||||
|
mLFH.mCompressionMethod = mCDE.mCompressionMethod;
|
||||||
|
mLFH.mLastModFileTime = mCDE.mLastModFileTime;
|
||||||
|
mLFH.mLastModFileDate = mCDE.mLastModFileDate;
|
||||||
|
mLFH.mCRC32 = mCDE.mCRC32;
|
||||||
|
mLFH.mCompressedSize = mCDE.mCompressedSize;
|
||||||
|
mLFH.mUncompressedSize = mCDE.mUncompressedSize;
|
||||||
|
mLFH.mFileNameLength = mCDE.mFileNameLength;
|
||||||
|
// the "extra field" is independent
|
||||||
|
|
||||||
|
delete[] mLFH.mFileName;
|
||||||
|
if (mLFH.mFileNameLength > 0) {
|
||||||
|
mLFH.mFileName = new unsigned char[mLFH.mFileNameLength+1];
|
||||||
|
strcpy((char*) mLFH.mFileName, (const char*) mCDE.mFileName);
|
||||||
|
} else {
|
||||||
|
mLFH.mFileName = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set some information about a file after we add it.
|
||||||
|
*/
|
||||||
|
void ZipEntry::setDataInfo(long uncompLen, long compLen, unsigned long crc32,
|
||||||
|
int compressionMethod)
|
||||||
|
{
|
||||||
|
mCDE.mCompressionMethod = compressionMethod;
|
||||||
|
mCDE.mCRC32 = crc32;
|
||||||
|
mCDE.mCompressedSize = compLen;
|
||||||
|
mCDE.mUncompressedSize = uncompLen;
|
||||||
|
mCDE.mCompressionMethod = compressionMethod;
|
||||||
|
if (compressionMethod == kCompressDeflated) {
|
||||||
|
mCDE.mGPBitFlag |= 0x0002; // indicates maximum compression used
|
||||||
|
}
|
||||||
|
copyCDEtoLFH();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See if the data in mCDE and mLFH match up. This is mostly useful for
|
||||||
|
* debugging these classes, but it can be used to identify damaged
|
||||||
|
* archives.
|
||||||
|
*
|
||||||
|
* Returns "false" if they differ.
|
||||||
|
*/
|
||||||
|
bool ZipEntry::compareHeaders(void) const
|
||||||
|
{
|
||||||
|
if (mCDE.mVersionToExtract != mLFH.mVersionToExtract) {
|
||||||
|
LOGV("cmp: VersionToExtract\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (mCDE.mGPBitFlag != mLFH.mGPBitFlag) {
|
||||||
|
LOGV("cmp: GPBitFlag\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (mCDE.mCompressionMethod != mLFH.mCompressionMethod) {
|
||||||
|
LOGV("cmp: CompressionMethod\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (mCDE.mLastModFileTime != mLFH.mLastModFileTime) {
|
||||||
|
LOGV("cmp: LastModFileTime\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (mCDE.mLastModFileDate != mLFH.mLastModFileDate) {
|
||||||
|
LOGV("cmp: LastModFileDate\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (mCDE.mCRC32 != mLFH.mCRC32) {
|
||||||
|
LOGV("cmp: CRC32\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (mCDE.mCompressedSize != mLFH.mCompressedSize) {
|
||||||
|
LOGV("cmp: CompressedSize\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (mCDE.mUncompressedSize != mLFH.mUncompressedSize) {
|
||||||
|
LOGV("cmp: UncompressedSize\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (mCDE.mFileNameLength != mLFH.mFileNameLength) {
|
||||||
|
LOGV("cmp: FileNameLength\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#if 0 // this seems to be used for padding, not real data
|
||||||
|
if (mCDE.mExtraFieldLength != mLFH.mExtraFieldLength) {
|
||||||
|
LOGV("cmp: ExtraFieldLength\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (mCDE.mFileName != NULL) {
|
||||||
|
if (strcmp((char*) mCDE.mFileName, (char*) mLFH.mFileName) != 0) {
|
||||||
|
LOGV("cmp: FileName\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert the DOS date/time stamp into a UNIX time stamp.
|
||||||
|
*/
|
||||||
|
time_t ZipEntry::getModWhen(void) const
|
||||||
|
{
|
||||||
|
struct tm parts;
|
||||||
|
|
||||||
|
parts.tm_sec = (mCDE.mLastModFileTime & 0x001f) << 1;
|
||||||
|
parts.tm_min = (mCDE.mLastModFileTime & 0x07e0) >> 5;
|
||||||
|
parts.tm_hour = (mCDE.mLastModFileTime & 0xf800) >> 11;
|
||||||
|
parts.tm_mday = (mCDE.mLastModFileDate & 0x001f);
|
||||||
|
parts.tm_mon = ((mCDE.mLastModFileDate & 0x01e0) >> 5) -1;
|
||||||
|
parts.tm_year = ((mCDE.mLastModFileDate & 0xfe00) >> 9) + 80;
|
||||||
|
parts.tm_wday = parts.tm_yday = 0;
|
||||||
|
parts.tm_isdst = -1; // DST info "not available"
|
||||||
|
|
||||||
|
return mktime(&parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the CDE/LFH timestamp from UNIX time.
|
||||||
|
*/
|
||||||
|
void ZipEntry::setModWhen(time_t when)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_LOCALTIME_R
|
||||||
|
struct tm tmResult;
|
||||||
|
#endif
|
||||||
|
time_t even;
|
||||||
|
unsigned short zdate, ztime;
|
||||||
|
|
||||||
|
struct tm* ptm;
|
||||||
|
|
||||||
|
/* round up to an even number of seconds */
|
||||||
|
even = (time_t)(((unsigned long)(when) + 1) & (~1));
|
||||||
|
|
||||||
|
/* expand */
|
||||||
|
#ifdef HAVE_LOCALTIME_R
|
||||||
|
ptm = localtime_r(&even, &tmResult);
|
||||||
|
#else
|
||||||
|
ptm = localtime(&even);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int year;
|
||||||
|
year = ptm->tm_year;
|
||||||
|
if (year < 80)
|
||||||
|
year = 80;
|
||||||
|
|
||||||
|
zdate = (year - 80) << 9 | (ptm->tm_mon+1) << 5 | ptm->tm_mday;
|
||||||
|
ztime = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1;
|
||||||
|
|
||||||
|
mCDE.mLastModFileTime = mLFH.mLastModFileTime = ztime;
|
||||||
|
mCDE.mLastModFileDate = mLFH.mLastModFileDate = zdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ===========================================================================
|
||||||
|
* ZipEntry::LocalFileHeader
|
||||||
|
* ===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read a local file header.
|
||||||
|
*
|
||||||
|
* On entry, "fp" points to the signature at the start of the header.
|
||||||
|
* On exit, "fp" points to the start of data.
|
||||||
|
*/
|
||||||
|
status_t ZipEntry::LocalFileHeader::read(FILE* fp)
|
||||||
|
{
|
||||||
|
status_t result = NO_ERROR;
|
||||||
|
unsigned char buf[kLFHLen];
|
||||||
|
|
||||||
|
assert(mFileName == NULL);
|
||||||
|
assert(mExtraField == NULL);
|
||||||
|
|
||||||
|
if (fread(buf, 1, kLFHLen, fp) != kLFHLen) {
|
||||||
|
result = UNKNOWN_ERROR;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {
|
||||||
|
LOGD("whoops: didn't find expected signature\n");
|
||||||
|
result = UNKNOWN_ERROR;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
mVersionToExtract = ZipEntry::getShortLE(&buf[0x04]);
|
||||||
|
mGPBitFlag = ZipEntry::getShortLE(&buf[0x06]);
|
||||||
|
mCompressionMethod = ZipEntry::getShortLE(&buf[0x08]);
|
||||||
|
mLastModFileTime = ZipEntry::getShortLE(&buf[0x0a]);
|
||||||
|
mLastModFileDate = ZipEntry::getShortLE(&buf[0x0c]);
|
||||||
|
mCRC32 = ZipEntry::getLongLE(&buf[0x0e]);
|
||||||
|
mCompressedSize = ZipEntry::getLongLE(&buf[0x12]);
|
||||||
|
mUncompressedSize = ZipEntry::getLongLE(&buf[0x16]);
|
||||||
|
mFileNameLength = ZipEntry::getShortLE(&buf[0x1a]);
|
||||||
|
mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1c]);
|
||||||
|
|
||||||
|
// TODO: validate sizes
|
||||||
|
|
||||||
|
/* grab filename */
|
||||||
|
if (mFileNameLength != 0) {
|
||||||
|
mFileName = new unsigned char[mFileNameLength+1];
|
||||||
|
if (mFileName == NULL) {
|
||||||
|
result = NO_MEMORY;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {
|
||||||
|
result = UNKNOWN_ERROR;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
mFileName[mFileNameLength] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* grab extra field */
|
||||||
|
if (mExtraFieldLength != 0) {
|
||||||
|
mExtraField = new unsigned char[mExtraFieldLength+1];
|
||||||
|
if (mExtraField == NULL) {
|
||||||
|
result = NO_MEMORY;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {
|
||||||
|
result = UNKNOWN_ERROR;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
mExtraField[mExtraFieldLength] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
bail:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write a local file header.
|
||||||
|
*/
|
||||||
|
status_t ZipEntry::LocalFileHeader::write(FILE* fp)
|
||||||
|
{
|
||||||
|
unsigned char buf[kLFHLen];
|
||||||
|
|
||||||
|
ZipEntry::putLongLE(&buf[0x00], kSignature);
|
||||||
|
ZipEntry::putShortLE(&buf[0x04], mVersionToExtract);
|
||||||
|
ZipEntry::putShortLE(&buf[0x06], mGPBitFlag);
|
||||||
|
ZipEntry::putShortLE(&buf[0x08], mCompressionMethod);
|
||||||
|
ZipEntry::putShortLE(&buf[0x0a], mLastModFileTime);
|
||||||
|
ZipEntry::putShortLE(&buf[0x0c], mLastModFileDate);
|
||||||
|
ZipEntry::putLongLE(&buf[0x0e], mCRC32);
|
||||||
|
ZipEntry::putLongLE(&buf[0x12], mCompressedSize);
|
||||||
|
ZipEntry::putLongLE(&buf[0x16], mUncompressedSize);
|
||||||
|
ZipEntry::putShortLE(&buf[0x1a], mFileNameLength);
|
||||||
|
ZipEntry::putShortLE(&buf[0x1c], mExtraFieldLength);
|
||||||
|
|
||||||
|
if (fwrite(buf, 1, kLFHLen, fp) != kLFHLen)
|
||||||
|
return UNKNOWN_ERROR;
|
||||||
|
|
||||||
|
/* write filename */
|
||||||
|
if (mFileNameLength != 0) {
|
||||||
|
if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)
|
||||||
|
return UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write "extra field" */
|
||||||
|
if (mExtraFieldLength != 0) {
|
||||||
|
if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)
|
||||||
|
return UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dump the contents of a LocalFileHeader object.
|
||||||
|
*/
|
||||||
|
void ZipEntry::LocalFileHeader::dump(void) const
|
||||||
|
{
|
||||||
|
LOGD(" LocalFileHeader contents:\n");
|
||||||
|
LOGD(" versToExt=%u gpBits=0x%04x compression=%u\n",
|
||||||
|
mVersionToExtract, mGPBitFlag, mCompressionMethod);
|
||||||
|
LOGD(" modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n",
|
||||||
|
mLastModFileTime, mLastModFileDate, mCRC32);
|
||||||
|
LOGD(" compressedSize=%lu uncompressedSize=%lu\n",
|
||||||
|
mCompressedSize, mUncompressedSize);
|
||||||
|
LOGD(" filenameLen=%u extraLen=%u\n",
|
||||||
|
mFileNameLength, mExtraFieldLength);
|
||||||
|
if (mFileName != NULL)
|
||||||
|
LOGD(" filename: '%s'\n", mFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ===========================================================================
|
||||||
|
* ZipEntry::CentralDirEntry
|
||||||
|
* ===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the central dir entry that appears next in the file.
|
||||||
|
*
|
||||||
|
* On entry, "fp" should be positioned on the signature bytes for the
|
||||||
|
* entry. On exit, "fp" will point at the signature word for the next
|
||||||
|
* entry or for the EOCD.
|
||||||
|
*/
|
||||||
|
status_t ZipEntry::CentralDirEntry::read(FILE* fp)
|
||||||
|
{
|
||||||
|
status_t result = NO_ERROR;
|
||||||
|
unsigned char buf[kCDELen];
|
||||||
|
|
||||||
|
/* no re-use */
|
||||||
|
assert(mFileName == NULL);
|
||||||
|
assert(mExtraField == NULL);
|
||||||
|
assert(mFileComment == NULL);
|
||||||
|
|
||||||
|
if (fread(buf, 1, kCDELen, fp) != kCDELen) {
|
||||||
|
result = UNKNOWN_ERROR;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {
|
||||||
|
LOGD("Whoops: didn't find expected signature\n");
|
||||||
|
result = UNKNOWN_ERROR;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
mVersionMadeBy = ZipEntry::getShortLE(&buf[0x04]);
|
||||||
|
mVersionToExtract = ZipEntry::getShortLE(&buf[0x06]);
|
||||||
|
mGPBitFlag = ZipEntry::getShortLE(&buf[0x08]);
|
||||||
|
mCompressionMethod = ZipEntry::getShortLE(&buf[0x0a]);
|
||||||
|
mLastModFileTime = ZipEntry::getShortLE(&buf[0x0c]);
|
||||||
|
mLastModFileDate = ZipEntry::getShortLE(&buf[0x0e]);
|
||||||
|
mCRC32 = ZipEntry::getLongLE(&buf[0x10]);
|
||||||
|
mCompressedSize = ZipEntry::getLongLE(&buf[0x14]);
|
||||||
|
mUncompressedSize = ZipEntry::getLongLE(&buf[0x18]);
|
||||||
|
mFileNameLength = ZipEntry::getShortLE(&buf[0x1c]);
|
||||||
|
mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1e]);
|
||||||
|
mFileCommentLength = ZipEntry::getShortLE(&buf[0x20]);
|
||||||
|
mDiskNumberStart = ZipEntry::getShortLE(&buf[0x22]);
|
||||||
|
mInternalAttrs = ZipEntry::getShortLE(&buf[0x24]);
|
||||||
|
mExternalAttrs = ZipEntry::getLongLE(&buf[0x26]);
|
||||||
|
mLocalHeaderRelOffset = ZipEntry::getLongLE(&buf[0x2a]);
|
||||||
|
|
||||||
|
// TODO: validate sizes and offsets
|
||||||
|
|
||||||
|
/* grab filename */
|
||||||
|
if (mFileNameLength != 0) {
|
||||||
|
mFileName = new unsigned char[mFileNameLength+1];
|
||||||
|
if (mFileName == NULL) {
|
||||||
|
result = NO_MEMORY;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {
|
||||||
|
result = UNKNOWN_ERROR;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
mFileName[mFileNameLength] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read "extra field" */
|
||||||
|
if (mExtraFieldLength != 0) {
|
||||||
|
mExtraField = new unsigned char[mExtraFieldLength+1];
|
||||||
|
if (mExtraField == NULL) {
|
||||||
|
result = NO_MEMORY;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {
|
||||||
|
result = UNKNOWN_ERROR;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
mExtraField[mExtraFieldLength] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* grab comment, if any */
|
||||||
|
if (mFileCommentLength != 0) {
|
||||||
|
mFileComment = new unsigned char[mFileCommentLength+1];
|
||||||
|
if (mFileComment == NULL) {
|
||||||
|
result = NO_MEMORY;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if (fread(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)
|
||||||
|
{
|
||||||
|
result = UNKNOWN_ERROR;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
mFileComment[mFileCommentLength] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
bail:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write a central dir entry.
|
||||||
|
*/
|
||||||
|
status_t ZipEntry::CentralDirEntry::write(FILE* fp)
|
||||||
|
{
|
||||||
|
unsigned char buf[kCDELen];
|
||||||
|
|
||||||
|
ZipEntry::putLongLE(&buf[0x00], kSignature);
|
||||||
|
ZipEntry::putShortLE(&buf[0x04], mVersionMadeBy);
|
||||||
|
ZipEntry::putShortLE(&buf[0x06], mVersionToExtract);
|
||||||
|
ZipEntry::putShortLE(&buf[0x08], mGPBitFlag);
|
||||||
|
ZipEntry::putShortLE(&buf[0x0a], mCompressionMethod);
|
||||||
|
ZipEntry::putShortLE(&buf[0x0c], mLastModFileTime);
|
||||||
|
ZipEntry::putShortLE(&buf[0x0e], mLastModFileDate);
|
||||||
|
ZipEntry::putLongLE(&buf[0x10], mCRC32);
|
||||||
|
ZipEntry::putLongLE(&buf[0x14], mCompressedSize);
|
||||||
|
ZipEntry::putLongLE(&buf[0x18], mUncompressedSize);
|
||||||
|
ZipEntry::putShortLE(&buf[0x1c], mFileNameLength);
|
||||||
|
ZipEntry::putShortLE(&buf[0x1e], mExtraFieldLength);
|
||||||
|
ZipEntry::putShortLE(&buf[0x20], mFileCommentLength);
|
||||||
|
ZipEntry::putShortLE(&buf[0x22], mDiskNumberStart);
|
||||||
|
ZipEntry::putShortLE(&buf[0x24], mInternalAttrs);
|
||||||
|
ZipEntry::putLongLE(&buf[0x26], mExternalAttrs);
|
||||||
|
ZipEntry::putLongLE(&buf[0x2a], mLocalHeaderRelOffset);
|
||||||
|
|
||||||
|
if (fwrite(buf, 1, kCDELen, fp) != kCDELen)
|
||||||
|
return UNKNOWN_ERROR;
|
||||||
|
|
||||||
|
/* write filename */
|
||||||
|
if (mFileNameLength != 0) {
|
||||||
|
if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)
|
||||||
|
return UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write "extra field" */
|
||||||
|
if (mExtraFieldLength != 0) {
|
||||||
|
if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)
|
||||||
|
return UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write comment */
|
||||||
|
if (mFileCommentLength != 0) {
|
||||||
|
if (fwrite(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)
|
||||||
|
return UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dump the contents of a CentralDirEntry object.
|
||||||
|
*/
|
||||||
|
void ZipEntry::CentralDirEntry::dump(void) const
|
||||||
|
{
|
||||||
|
LOGD(" CentralDirEntry contents:\n");
|
||||||
|
LOGD(" versMadeBy=%u versToExt=%u gpBits=0x%04x compression=%u\n",
|
||||||
|
mVersionMadeBy, mVersionToExtract, mGPBitFlag, mCompressionMethod);
|
||||||
|
LOGD(" modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n",
|
||||||
|
mLastModFileTime, mLastModFileDate, mCRC32);
|
||||||
|
LOGD(" compressedSize=%lu uncompressedSize=%lu\n",
|
||||||
|
mCompressedSize, mUncompressedSize);
|
||||||
|
LOGD(" filenameLen=%u extraLen=%u commentLen=%u\n",
|
||||||
|
mFileNameLength, mExtraFieldLength, mFileCommentLength);
|
||||||
|
LOGD(" diskNumStart=%u intAttr=0x%04x extAttr=0x%08lx relOffset=%lu\n",
|
||||||
|
mDiskNumberStart, mInternalAttrs, mExternalAttrs,
|
||||||
|
mLocalHeaderRelOffset);
|
||||||
|
|
||||||
|
if (mFileName != NULL)
|
||||||
|
LOGD(" filename: '%s'\n", mFileName);
|
||||||
|
if (mFileComment != NULL)
|
||||||
|
LOGD(" comment: '%s'\n", mFileComment);
|
||||||
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user