auto import from //depot/cupcake/@135843
diff --git a/buildspec.mk.default b/buildspec.mk.default
new file mode 100644
index 0000000..861bb0d
--- /dev/null
+++ b/buildspec.mk.default
@@ -0,0 +1,100 @@
+#
+# Copyright (C) 2007 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 is a do-nothing template file. To use it, copy it to a file
+# named "buildspec.mk" in the root directory, and uncomment or change
+# the variables necessary for your desired configuration. The file
+# "buildspec.mk" should never be checked in to source control.
+######################################################################
+
+# Uncomment this if you want the simulator, otherwise, build for arm
+ifndef TARGET_SIMULATOR
+#TARGET_SIMULATOR:=true
+endif
+
+# Set this to debug or release if you care. Otherwise, it defaults to
+# release for arm and debug for the simulator.
+ifndef TARGET_BUILD_TYPE
+#TARGET_BUILD_TYPE:=release
+#TARGET_BUILD_TYPE:=debug
+endif
+
+# Uncomment this if you want the host tools built in debug mode. Otherwise
+# it defaults to release.
+ifndef HOST_BUILD_TYPE
+#HOST_BUILD_TYPE:=debug
+endif
+
+# Turn on debugging for selected modules. If DEBUG_MODULE_<module-name> is set
+# to a non-empty value, the appropriate HOST_/TARGET_CUSTOM_DEBUG_CFLAGS
+# will be added to LOCAL_CFLAGS when building the module.
+#DEBUG_MODULE_ModuleName:=true
+
+# Specify the extra CFLAGS to use when building a module whose
+# DEBUG_MODULE_ variable is set. Host and device flags are handled
+# separately.
+#HOST_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
+# 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
+# of PRODUCT_LOCALES.
+ifndef CUSTOM_LOCALES
+#CUSTOM_LOCALES:=
+endif
+
+# If you have a special place to put your ouput files, set this, otherwise
+# it goes to <build-root>/out
+#OUT_DIR:=/tmp/stuff
+
+# If you want to always set certain system properties, add them to this list.
+# E.g., "ADDITIONAL_BUILD_PROPERTIES += ro.prop1=5 prop2=value"
+# This mechanism does not currently support values containing spaces.
+#ADDITIONAL_BUILD_PROPERTIES +=
+
+# If you want to reduce the system.img size by several meg, and are willing to
+# lose access to CJK (and other) character sets, define NO_FALLBACK_FONT:=true
+ifndef NO_FALLBACK_FONT
+#NO_FALLBACK_FONT:=true
+endif
+
+# To enabled instrumentation in webcore based apps like gmail and
+# the browser, define WEBCORE_INSTRUMENTATION:=true
+#WEBCORE_INSTRUMENTATION:=true
+#endif
+
+# 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
+# changes (see buildspec.mk.default), update this to the new value from
+# buildspec.mk.default.
+BUILD_ENV_SEQUENCE_NUMBER := 9
diff --git a/cleanspec.mk b/cleanspec.mk
new file mode 100644
index 0000000..794c9cd
--- /dev/null
+++ b/cleanspec.mk
@@ -0,0 +1,74 @@
+# Copyright (C) 2007 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.
+#
+
+# Just bump this if you want to force a clean build.
+# **********************************************************************
+# WHEN DOING SO, DELETE ANY "add-clean-step" ENTRIES THAT HAVE PILED UP.
+# **********************************************************************
+#
+INTERNAL_CLEAN_BUILD_VERSION := 2
+#
+# ***********************************************************************
+# Do not touch INTERNAL_CLEAN_BUILD_VERSION if you've added a clean step!
+# ***********************************************************************
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list. These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/external/zlib/)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list. E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_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, rm -rf $(PRODUCT_OUT)/data/*)
+
+$(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)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
diff --git a/core/Makefile b/core/Makefile
new file mode 100644
index 0000000..9ba117a
--- /dev/null
+++ b/core/Makefile
@@ -0,0 +1,1163 @@
+# Put some miscellaneous rules here
+
+# Pick a reasonable string to use to identify files.
+ifneq "" "$(filter eng.%,$(BUILD_NUMBER))"
+ # BUILD_NUMBER has a timestamp in it, which means that
+ # it will change every time. Pick a stable value.
+ FILE_NAME_TAG := eng.$(USER)
+else
+ FILE_NAME_TAG := $(BUILD_NUMBER)
+endif
+
+# -----------------------------------------------------------------
+# Define rules to copy PRODUCT_COPY_FILES defined by the product.
+# PRODUCT_COPY_FILES contains words like <source file>:<dest file>.
+# <dest file> is relative to $(PRODUCT_OUT), so it should look like,
+# e.g., "system/etc/file.xml".
+$(foreach cf,$(PRODUCT_COPY_FILES), \
+ $(eval _w := $(subst :,$(space),$(cf))) \
+ $(eval _src := $(word 1,$(_w))) \
+ $(eval _dest := $(subst //,/,$(PRODUCT_OUT)/$(word 2,$(_w)))) \
+ $(eval $(call copy-one-file,$(_src),$(_dest))) \
+ $(eval ALL_DEFAULT_INSTALLED_MODULES += $(_dest)) \
+ )
+
+# -----------------------------------------------------------------
+# docs/index.html
+gen := $(OUT_DOCS)/index.html
+ALL_DOCS += $(gen)
+$(gen): frameworks/base/docs/docs-redirect-index.html
+ @mkdir -p $(dir $@)
+ @cp -f $< $@
+
+# -----------------------------------------------------------------
+# default.prop
+INSTALLED_DEFAULT_PROP_TARGET := $(TARGET_ROOT_OUT)/default.prop
+ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_DEFAULT_PROP_TARGET)
+ADDITIONAL_DEFAULT_PROPERTIES := \
+ $(call collapse-pairs, $(ADDITIONAL_DEFAULT_PROPERTIES))
+
+$(INSTALLED_DEFAULT_PROP_TARGET):
+ @echo Target buildinfo: $@
+ @mkdir -p $(dir $@)
+ $(hide) echo "#" > $@; \
+ echo "# ADDITIONAL_DEFAULT_PROPERTIES" >> $@; \
+ echo "#" >> $@;
+ $(hide) $(foreach line,$(ADDITIONAL_DEFAULT_PROPERTIES), \
+ echo "$(line)" >> $@;)
+
+# -----------------------------------------------------------------
+# build.prop
+INSTALLED_BUILD_PROP_TARGET := $(TARGET_OUT)/build.prop
+ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_BUILD_PROP_TARGET)
+ADDITIONAL_BUILD_PROPERTIES := \
+ $(call collapse-pairs, $(ADDITIONAL_BUILD_PROPERTIES))
+
+# A list of arbitrary tags describing the build configuration.
+# Force ":=" so we can use +=
+BUILD_VERSION_TAGS := $(BUILD_VERSION_TAGS)
+ifeq ($(TARGET_BUILD_TYPE),debug)
+ BUILD_VERSION_TAGS += debug
+endif
+# Apps are always signed with test keys, and may be re-signed in a post-build
+# step. If that happens, the "test-keys" tag will be removed by that step.
+BUILD_VERSION_TAGS += test-keys
+ifndef INCLUDE_TEST_OTA_KEYS
+ BUILD_VERSION_TAGS += ota-rel-keys
+endif
+BUILD_VERSION_TAGS := $(subst $(space),$(comma),$(sort $(BUILD_VERSION_TAGS)))
+
+# A human-readable string that descibes this build in detail.
+build_desc := $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT) $(PLATFORM_VERSION) $(BUILD_ID) $(BUILD_NUMBER) $(BUILD_VERSION_TAGS)
+$(INSTALLED_BUILD_PROP_TARGET): PRIVATE_BUILD_DESC := $(build_desc)
+
+# The string used to uniquely identify this build; used by the OTA server.
+ifeq (,$(strip $(BUILD_FINGERPRINT)))
+ BUILD_FINGERPRINT := $(PRODUCT_BRAND)/$(TARGET_PRODUCT)/$(TARGET_DEVICE)/$(TARGET_BOOTLOADER_BOARD_NAME):$(PLATFORM_VERSION)/$(BUILD_ID)/$(BUILD_NUMBER):$(TARGET_BUILD_VARIANT)/$(BUILD_VERSION_TAGS)
+endif
+ifneq ($(words $(BUILD_FINGERPRINT)),1)
+ $(error BUILD_FINGERPRINT cannot contain spaces: "$(BUILD_FINGERPRINT)")
+endif
+
+# Selects the first locale in the list given as the argument,
+# and splits it into language and region, which each may be
+# empty.
+define default-locale
+$(subst _, , $(firstword $(1)))
+endef
+
+# Selects the first locale in the list given as the argument
+# and returns the language (or the region)
+define default-locale-language
+$(word 2, 2, $(call default-locale, $(1)))
+endef
+define default-locale-region
+$(word 3, 3, $(call default-locale, $(1)))
+endef
+
+BUILDINFO_SH := build/tools/buildinfo.sh
+$(INSTALLED_BUILD_PROP_TARGET): $(BUILDINFO_SH) $(INTERNAL_BUILD_ID_MAKEFILE)
+ @echo Target buildinfo: $@
+ @mkdir -p $(dir $@)
+ $(hide) TARGET_BUILD_TYPE="$(TARGET_BUILD_VARIANT)" \
+ TARGET_DEVICE="$(TARGET_DEVICE)" \
+ PRODUCT_NAME="$(TARGET_PRODUCT)" \
+ PRODUCT_BRAND="$(PRODUCT_BRAND)" \
+ PRODUCT_DEFAULT_LANGUAGE="$(call default-locale-language,$(PRODUCT_LOCALES))" \
+ PRODUCT_DEFAULT_REGION="$(call default-locale-region,$(PRODUCT_LOCALES))" \
+ PRODUCT_MODEL="$(PRODUCT_MODEL)" \
+ PRODUCT_MANUFACTURER="$(PRODUCT_MANUFACTURER)" \
+ PRIVATE_BUILD_DESC="$(PRIVATE_BUILD_DESC)" \
+ BUILD_ID="$(BUILD_ID)" \
+ BUILD_DISPLAY_ID="$(BUILD_DISPLAY_ID)" \
+ BUILD_NUMBER="$(BUILD_NUMBER)" \
+ PLATFORM_VERSION="$(PLATFORM_VERSION)" \
+ PLATFORM_SDK_VERSION="$(PLATFORM_SDK_VERSION)" \
+ BUILD_VERSION_TAGS="$(BUILD_VERSION_TAGS)" \
+ TARGET_BOOTLOADER_BOARD_NAME="$(TARGET_BOOTLOADER_BOARD_NAME)" \
+ BUILD_FINGERPRINT="$(BUILD_FINGERPRINT)" \
+ TARGET_BOARD_PLATFORM="$(TARGET_BOARD_PLATFORM)" \
+ bash $(BUILDINFO_SH) > $@
+ $(hide) if [ -f $(TARGET_DEVICE_DIR)/system.prop ]; then \
+ cat $(TARGET_DEVICE_DIR)/system.prop >> $@; \
+ fi
+ $(if $(ADDITIONAL_BUILD_PROPERTIES), \
+ $(hide) echo >> $@; \
+ echo "#" >> $@; \
+ echo "# ADDITIONAL_BUILD_PROPERTIES" >> $@; \
+ echo "#" >> $@; )
+ $(hide) $(foreach line,$(ADDITIONAL_BUILD_PROPERTIES), \
+ echo "$(line)" >> $@;)
+
+build_desc :=
+
+# -----------------------------------------------------------------
+# sdk-build.prop
+#
+# There are certain things in build.prop that we don't want to
+# ship with the sdk; remove them.
+
+# This must be a list of entire property keys followed by
+# "=" characters, without any internal spaces.
+sdk_build_prop_remove := \
+ ro.build.user= \
+ ro.build.host= \
+ ro.product.brand= \
+ ro.product.manufacturer= \
+ ro.product.device=
+# TODO: Remove this soon-to-be obsolete property
+sdk_build_prop_remove += ro.build.product=
+INSTALLED_SDK_BUILD_PROP_TARGET := $(PRODUCT_OUT)/sdk/sdk-build.prop
+$(INSTALLED_SDK_BUILD_PROP_TARGET): $(INSTALLED_BUILD_PROP_TARGET)
+ @echo SDK buildinfo: $@
+ @mkdir -p $(dir $@)
+ $(hide) grep -v "$(subst $(space),\|,$(strip \
+ $(sdk_build_prop_remove)))" $< > $@.tmp
+ $(hide) for x in $(sdk_build_prop_remove); do \
+ echo "$$x"generic >> $@.tmp; done
+ $(hide) mv $@.tmp $@
+
+# -----------------------------------------------------------------
+# package stats
+PACKAGE_STATS_FILE := $(PRODUCT_OUT)/package-stats.txt
+PACKAGES_TO_STAT := \
+ $(sort $(filter $(TARGET_OUT)/% $(TARGET_OUT_DATA)/%, \
+ $(filter %.jar %.apk, $(ALL_DEFAULT_INSTALLED_MODULES))))
+$(PACKAGE_STATS_FILE): $(PACKAGES_TO_STAT)
+ @echo Package stats: $@
+ @mkdir -p $(dir $@)
+ $(hide) rm -f $@
+ $(hide) build/tools/dump-package-stats $^ > $@
+
+.PHONY: package-stats
+package-stats: $(PACKAGE_STATS_FILE)
+
+# -----------------------------------------------------------------
+# Cert-to-package mapping. Used by the post-build signing tools.
+name := $(TARGET_PRODUCT)
+ifeq ($(TARGET_BUILD_TYPE),debug)
+ name := $(name)_debug
+endif
+name := $(name)-apkcerts-$(FILE_NAME_TAG)
+intermediates := \
+ $(call intermediates-dir-for,PACKAGING,apkcerts)
+APKCERTS_FILE := $(intermediates)/$(name).txt
+# Depending on the built packages isn't exactly right,
+# but it should guarantee that the apkcerts file is rebuilt
+# if any packages change which certs they're signed with.
+all_built_packages := $(foreach p,$(PACKAGES),$(ALL_MODULES.$(p).BUILT))
+$(APKCERTS_FILE): $(all_built_packages)
+ @echo APK certs list: $@
+ @mkdir -p $(dir $@)
+ @rm -f $@
+ $(hide) $(foreach p,$(PACKAGES),\
+ echo 'name="$(p).apk" certificate="$(PACKAGES.$(p).CERTIFICATE)" \
+ private_key="$(PACKAGES.$(p).PRIVATE_KEY)"' >> $@;)
+
+.PHONY: apkcerts-list
+apkcerts-list: $(APKCERTS_FILE)
+
+# -----------------------------------------------------------------
+# module info file
+ifdef CREATE_MODULE_INFO_FILE
+ MODULE_INFO_FILE := $(PRODUCT_OUT)/module-info.txt
+ $(info Generating $(MODULE_INFO_FILE)...)
+ $(shell rm -f $(MODULE_INFO_FILE))
+ $(foreach m,$(ALL_MODULES), \
+ $(shell echo "NAME=\"$(m)\"" \
+ "PATH=\"$(strip $(ALL_MODULES.$(m).PATH))\"" \
+ "TAGS=\"$(strip $(filter-out _%,$(ALL_MODULES.$(m).TAGS)))\"" \
+ "BUILT=\"$(strip $(ALL_MODULES.$(m).BUILT))\"" \
+ "INSTALLED=\"$(strip $(ALL_MODULES.$(m).INSTALLED))\"" >> $(MODULE_INFO_FILE)))
+endif
+
+# Rules that need to be present for the simulator, even
+# if they don't do anything.
+.PHONY: systemimage
+systemimage:
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+# #################################################################
+# Targets for boot/OS images
+# #################################################################
+
+# -----------------------------------------------------------------
+# the ramdisk
+INTERNAL_RAMDISK_FILES := $(filter $(TARGET_ROOT_OUT)/%, \
+ $(ALL_PREBUILT) \
+ $(ALL_COPIED_HEADERS) \
+ $(ALL_GENERATED_SOURCES) \
+ $(ALL_DEFAULT_INSTALLED_MODULES))
+
+INSTALLED_RAMDISK_TARGET := $(PRODUCT_OUT)/ramdisk.img
+$(INSTALLED_RAMDISK_TARGET): $(MKBOOTFS) $(INTERNAL_RAMDISK_FILES)
+ $(call pretty,"Target ram disk: $@")
+ $(hide) $(MKBOOTFS) $(TARGET_ROOT_OUT) | gzip > $@
+
+
+ifneq ($(strip $(TARGET_NO_KERNEL)),true)
+
+# -----------------------------------------------------------------
+# the boot image, which is a collection of other images.
+INTERNAL_BOOTIMAGE_ARGS := \
+ $(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \
+ --kernel $(INSTALLED_KERNEL_TARGET) \
+ --ramdisk $(INSTALLED_RAMDISK_TARGET)
+
+INTERNAL_BOOTIMAGE_FILES := $(filter-out --%,$(INTERNAL_BOOTIMAGE_ARGS))
+
+BOARD_KERNEL_CMDLINE := $(strip $(BOARD_KERNEL_CMDLINE))
+ifdef BOARD_KERNEL_CMDLINE
+ INTERNAL_BOOTIMAGE_ARGS += --cmdline "$(BOARD_KERNEL_CMDLINE)"
+endif
+
+INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
+
+ifeq ($(TARGET_BOOTIMAGE_USE_EXT2),true)
+tmp_dir_for_image := $(call intermediates-dir-for,EXECUTABLES,boot_img)/bootimg
+INTERNAL_BOOTIMAGE_ARGS += --tmpdir $(tmp_dir_for_image)
+INTERNAL_BOOTIMAGE_ARGS += --genext2fs $(MKEXT2IMG)
+$(INSTALLED_BOOTIMAGE_TARGET): $(MKEXT2IMG) $(INTERNAL_BOOTIMAGE_FILES)
+ $(call pretty,"Target boot image: $@")
+ $(hide) $(MKEXT2BOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) --output $@
+
+else # TARGET_BOOTIMAGE_USE_EXT2 != true
+
+$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES)
+ $(call pretty,"Target boot image: $@")
+ $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) --output $@
+ $(hide) $(call assert-max-file-size,$@,$(BOARD_BOOTIMAGE_MAX_SIZE))
+endif # TARGET_BOOTIMAGE_USE_EXT2
+
+else # TARGET_NO_KERNEL
+# HACK: The top-level targets depend on the bootimage. Not all targets
+# can produce a bootimage, though, and emulator targets need the ramdisk
+# instead. Fake it out by calling the ramdisk the bootimage.
+# TODO: make the emulator use bootimages, and make mkbootimg accept
+# kernel-less inputs.
+INSTALLED_BOOTIMAGE_TARGET := $(INSTALLED_RAMDISK_TARGET)
+endif
+
+# -----------------------------------------------------------------
+# NOTICE files
+#
+# This needs to be before the systemimage rules, because it adds to
+# ALL_DEFAULT_INSTALLED_MODULES, which those use to pick which files
+# go into the systemimage.
+
+.PHONY: notice_files
+
+# Create the rule to combine the files into text and html forms
+# $(1) - Plain text output file
+# $(2) - HTML output file
+# $(3) - File title
+# $(4) - Directory to use. Notice files are all $(4)/src. Other
+# directories in there will be used for scratch
+# $(5) - Dependencies for the output files
+#
+# The algorithm here is that we go collect a hash for each of the notice
+# files and write the names of the files that match that hash. Then
+# to generate the real files, we go print out all of the files and their
+# hashes.
+#
+# These rules are fairly complex, so they depend on this makefile so if
+# it changes, they'll run again.
+#
+# TODO: We could clean this up so that we just record the locations of the
+# original notice files instead of making rules to copy them somwehere.
+# Then we could traverse that without quite as much bash drama.
+define combine-notice-files
+$(1) $(2): PRIVATE_MESSAGE := $(3)
+$(1) $(2) $(4)/hash-timestamp: PRIVATE_DIR := $(4)
+$(4)/hash-timestamp: $(5) $(BUILD_SYSTEM)/Makefile
+ @echo Finding NOTICE files: $$@
+ $$(hide) rm -rf $$@ $$(PRIVATE_DIR)/hash
+ $$(hide) mkdir -p $$(PRIVATE_DIR)/hash
+ $$(hide) for file in $$$$(find $$(PRIVATE_DIR)/src -type f); do \
+ hash=$$$$($(MD5SUM) $$$$file | sed -e "s/ .*//"); \
+ hashfile=$$(PRIVATE_DIR)/hash/$$$$hash; \
+ echo $$$$file >> $$$$hashfile; \
+ done
+ $$(hide) touch $$@
+$(1): $(4)/hash-timestamp
+ @echo Combining NOTICE files: $$@
+ $$(hide) mkdir -p $$(dir $$@)
+ $$(hide) echo $$(PRIVATE_MESSAGE) > $$@
+ $$(hide) find $$(PRIVATE_DIR)/hash -type f | xargs cat | sort | \
+ sed -e "s:$$(PRIVATE_DIR)/src\(.*\)\.txt: \1:" >> $$@
+ $$(hide) echo >> $$@
+ $$(hide) echo >> $$@
+ $$(hide) echo >> $$@
+ $$(hide) for hashfile in $$$$(find $$(PRIVATE_DIR)/hash -type f); do \
+ echo "============================================================"\
+ >> $$@; \
+ echo "Notices for file(s):" >> $$@; \
+ cat $$$$hashfile | sort | \
+ sed -e "s:$$(PRIVATE_DIR)/src\(.*\)\.txt: \1:" >> \
+ $$@; \
+ echo "------------------------------------------------------------"\
+ >> $$@; \
+ echo >> $$@; \
+ orig=$$$$(head -n 1 $$$$hashfile); \
+ cat $$$$orig >> $$@; \
+ echo >> $$@; \
+ echo >> $$@; \
+ echo >> $$@; \
+ done
+$(2): $(4)/hash-timestamp
+ @echo Combining NOTICE files: $$@
+ $$(hide) mkdir -p $$(dir $$@)
+ $$(hide) echo "<html><head>" > $$@
+ $$(hide) echo "<style type=\"text/css\">" >> $$@
+ $$(hide) echo "body { padding: 0; font-family: sans-serif; }" >> $$@
+ $$(hide) echo ".same-license { background-color: #eeeeee; border-top: 20px solid white; padding: 10px; }" >> $$@
+ $$(hide) echo ".label { font-weight: bold; }" >> $$@
+ $$(hide) echo ".file-list { margin-left: 1em; font-color: blue; }" >> $$@
+ $$(hide) echo "</style>" >> $$@
+ $$(hide) echo "</head><body topmargin=\"0\" leftmargin=\"0\" rightmargin=\"0\" bottommargin=\"0\">" >> $$@
+ $$(hide) echo "<table cellpading=\"0\" cellspacing=\"0\" border=\"0\">" \
+ >> $$@
+ $$(hide) for hashfile in $$$$(find $$(PRIVATE_DIR)/hash -type f); do \
+ cat $$$$hashfile | sort | \
+ sed -e "s:$$(PRIVATE_DIR)/src\(.*\)\.txt: <a name=\"\1\"></a>:" >> \
+ $$@; \
+ echo "<tr><td class=\"same-license\">" >> $$@; \
+ echo "<div class=\"label\">Notices for file(s):</div>" >> $$@; \
+ echo "<div class=\"file-list\">" >> $$@; \
+ cat $$$$hashfile | sort | \
+ sed -e "s:$$(PRIVATE_DIR)/src\(.*\)\.txt: \1<br/>:" >> $$@; \
+ echo "</div><!-- file-list -->" >> $$@; \
+ echo >> $$@; \
+ orig=$$$$(head -n 1 $$$$hashfile); \
+ echo "<pre class=\"license-text\">" >> $$@; \
+ cat $$$$orig | sed -e "s/\&/\&/g" | sed -e "s/</\</g" \
+ | sed -e "s/>/\>/g" >> $$@; \
+ echo "</pre><!-- license-text -->" >> $$@; \
+ echo "</td></tr><!-- same-license -->" >> $$@; \
+ echo >> $$@; \
+ echo >> $$@; \
+ echo >> $$@; \
+ done
+ $$(hide) echo "</table>" >> $$@
+ $$(hide) echo "</body></html>" >> $$@
+notice_files: $(1) $(2)
+endef
+
+# TODO These intermediate NOTICE.txt/NOTICE.html files should go into
+# TARGET_OUT_NOTICE_FILES now that the notice files are gathered from
+# the src subdirectory.
+
+target_notice_file_txt := $(TARGET_OUT_INTERMEDIATES)/NOTICE.txt
+target_notice_file_html := $(TARGET_OUT_INTERMEDIATES)/NOTICE.html
+target_notice_file_html_gz := $(TARGET_OUT_INTERMEDIATES)/NOTICE.html.gz
+tools_notice_file_txt := $(HOST_OUT_INTERMEDIATES)/NOTICE.txt
+tools_notice_file_html := $(HOST_OUT_INTERMEDIATES)/NOTICE.html
+
+kernel_notice_file := $(TARGET_OUT_NOTICE_FILES)/src/kernel.txt
+
+$(eval $(call combine-notice-files, \
+ $(target_notice_file_txt), \
+ $(target_notice_file_html), \
+ "Notices for files contained in the filesystem images in this directory:", \
+ $(TARGET_OUT_NOTICE_FILES), \
+ $(ALL_DEFAULT_INSTALLED_MODULES) $(kernel_notice_file)))
+
+$(eval $(call combine-notice-files, \
+ $(tools_notice_file_txt), \
+ $(tools_notice_file_html), \
+ "Notices for files contained in the tools directory:", \
+ $(HOST_OUT_NOTICE_FILES), \
+ $(ALL_DEFAULT_INSTALLED_MODULES)))
+
+# Install the html file at /system/etc/NOTICE.html.gz.
+# This is not ideal, but this is very late in the game, after a lot of
+# the module processing has already been done -- in fact, we used the
+# fact that all that has been done to get the list of modules that we
+# need notice files for.
+$(target_notice_file_html_gz): $(target_notice_file_html)
+ gzip -c $< > $@
+installed_notice_html_gz := $(TARGET_OUT)/etc/NOTICE.html.gz
+$(installed_notice_html_gz): $(target_notice_file_html_gz) | $(ACP)
+ $(copy-file-to-target)
+ALL_DEFAULT_INSTALLED_MODULES += $(installed_notice_html_gz)
+
+# The kernel isn't really a module, so to get its module file in there, we
+# make the target NOTICE files depend on this particular file too, which will
+# then be in the right directory for the find in combine-notice-files to work.
+$(kernel_notice_file): \
+ prebuilt/$(TARGET_PREBUILT_TAG)/kernel/LINUX_KERNEL_COPYING \
+ | $(ACP)
+ @echo Copying: $@
+ $(hide) mkdir -p $(dir $@)
+ $(hide) $(ACP) $< $@
+
+
+# #################################################################
+# Targets for user images
+# #################################################################
+
+ifeq ($(TARGET_USERIMAGES_USE_EXT2),true)
+include external/genext2fs/Config.mk
+INTERNAL_MKUSERFS := $(MKEXT2IMG)
+else
+INTERNAL_MKUSERFS := $(MKYAFFS2)
+endif
+
+# -----------------------------------------------------------------
+# system yaffs image
+#
+# First, the "unoptimized" image, which contains .apk/.jar files
+# that contain regular, unoptimized/unverified .dex entries.
+#
+systemimage_unopt_intermediates := \
+ $(call intermediates-dir-for,PACKAGING,systemimage_unopt)
+BUILT_SYSTEMIMAGE_UNOPT := $(systemimage_unopt_intermediates)/system.img
+
+INTERNAL_SYSTEMIMAGE_FILES := $(filter $(TARGET_OUT)/%, \
+ $(ALL_PREBUILT) \
+ $(ALL_COPIED_HEADERS) \
+ $(ALL_GENERATED_SOURCES) \
+ $(ALL_DEFAULT_INSTALLED_MODULES))
+
+ifeq ($(TARGET_USERIMAGES_USE_EXT2),true)
+## generate an ext2 image
+# $(1): output file
+define build-systemimage-target
+ @echo "Target system fs image: $(1)"
+ $(call build-userimage-ext2-target,$(TARGET_OUT),$(1),system,)
+endef
+
+else # TARGET_USERIMAGES_USE_EXT2 != true
+
+## generate a yaffs2 image
+# $(1): output file
+define build-systemimage-target
+ @echo "Target system fs image: $(1)"
+ @mkdir -p $(dir $(1))
+ $(hide) $(MKYAFFS2) -f $(TARGET_OUT) $(1)
+endef
+endif # TARGET_USERIMAGES_USE_EXT2
+
+$(BUILT_SYSTEMIMAGE_UNOPT): $(INTERNAL_SYSTEMIMAGE_FILES) $(INTERNAL_MKUSERFS)
+ $(call build-systemimage-target,$@)
+
+# The installed image, which may be optimized or unoptimized.
+#
+INSTALLED_SYSTEMIMAGE := $(PRODUCT_OUT)/system.img
+
+ifdef WITH_DEXPREOPT
+ ifndef DISABLE_DEXPREOPT
+ with_dexpreopt := true
+ endif
+endif
+ifdef with_dexpreopt
+ # This file will set BUILT_SYSTEMIMAGE and SYSTEMIMAGE_SOURCE_DIR
+ include build/tools/dexpreopt/Config.mk
+else
+ BUILT_SYSTEMIMAGE := $(BUILT_SYSTEMIMAGE_UNOPT)
+ SYSTEMIMAGE_SOURCE_DIR := $(TARGET_OUT)
+endif
+
+$(INSTALLED_SYSTEMIMAGE): $(BUILT_SYSTEMIMAGE) | $(ACP)
+ @echo "Install system fs image: $@"
+ $(copy-file-to-target)
+ $(hide) $(call assert-max-file-size,$@,$(BOARD_SYSTEMIMAGE_MAX_SIZE))
+
+systemimage: $(INSTALLED_SYSTEMIMAGE)
+
+.PHONY: systemimage-nodeps snod
+systemimage-nodeps snod: $(filter-out systemimage-nodeps snod,$(MAKECMDGOALS)) \
+ | $(INTERNAL_MKUSERFS)
+ @echo "make $@: ignoring dependencies"
+ $(call build-systemimage-target,$(INSTALLED_SYSTEMIMAGE))
+ $(hide) $(call assert-max-file-size,$(INSTALLED_SYSTEMIMAGE),$(BOARD_SYSTEMIMAGE_MAX_SIZE))
+
+#######
+## system tarball
+define build-systemtarball-target
+ $(call pretty,"Target system fs tarball: $(INSTALLED_SYSTEMTARBALL_TARGET)")
+ $(MKTARBALL) $(FS_GET_STATS) \
+ $(PRODUCT_OUT) system $(PRIVATE_SYSTEM_TAR) \
+ $(INSTALLED_SYSTEMTARBALL_TARGET)
+endef
+
+system_tar := $(PRODUCT_OUT)/system.tar
+INSTALLED_SYSTEMTARBALL_TARGET := $(system_tar).bz2
+$(INSTALLED_SYSTEMTARBALL_TARGET): PRIVATE_SYSTEM_TAR := $(system_tar)
+$(INSTALLED_SYSTEMTARBALL_TARGET): $(FS_GET_STATS) $(INTERNAL_SYSTEMIMAGE_FILES)
+ $(build-systemtarball-target)
+
+.PHONY: systemtarball-nodeps
+systemtarball-nodeps: $(FS_GET_STATS) \
+ $(filter-out systemtarball-nodeps stnod,$(MAKECMDGOALS))
+ $(build-systemtarball-target)
+
+.PHONY: stnod
+stnod: systemtarball-nodeps
+
+
+# -----------------------------------------------------------------
+# data partition image
+INTERNAL_USERDATAIMAGE_FILES := \
+ $(filter $(TARGET_OUT_DATA)/%,$(ALL_DEFAULT_INSTALLED_MODULES))
+
+ifeq ($(TARGET_USERIMAGES_USE_EXT2),true)
+## Generate an ext2 image
+define build-userdataimage-target
+ $(call pretty,"Target userdata fs image: $(INSTALLED_USERDATAIMAGE_TARGET)")
+ @mkdir -p $(TARGET_OUT_DATA)
+ $(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))
+endef
+
+else # TARGET_USERIMAGES_USE_EXT2 != true
+
+## Generate a yaffs2 image
+define build-userdataimage-target
+ $(call pretty,"Target userdata fs image: $(INSTALLED_USERDATAIMAGE_TARGET)")
+ @mkdir -p $(TARGET_OUT_DATA)
+ $(hide) $(MKYAFFS2) -f $(TARGET_OUT_DATA) $(INSTALLED_USERDATAIMAGE_TARGET)
+ $(hide) $(call assert-max-file-size,$(INSTALLED_USERDATAIMAGE_TARGET),$(BOARD_USERDATAIMAGE_MAX_SIZE))
+endef
+endif # TARGET_USERIMAGES_USE_EXT2
+
+INSTALLED_USERDATAIMAGE_TARGET := $(PRODUCT_OUT)/userdata.img
+$(INSTALLED_USERDATAIMAGE_TARGET): $(INTERNAL_MKUSERFS) \
+ $(INTERNAL_USERDATAIMAGE_FILES)
+ $(build-userdataimage-target)
+
+.PHONY: userdataimage-nodeps
+userdataimage-nodeps: $(INTERNAL_MKUSERFS)
+ $(build-userdataimage-target)
+
+#######
+## data partition tarball
+define build-userdatatarball-target
+ $(call pretty,"Target userdata fs tarball: " \
+ "$(INSTALLED_USERDATATARBALL_TARGET)")
+ $(MKTARBALL) $(FS_GET_STATS) \
+ $(PRODUCT_OUT) data $(PRIVATE_USERDATA_TAR) \
+ $(INSTALLED_USERDATATARBALL_TARGET)
+endef
+
+userdata_tar := $(PRODUCT_OUT)/userdata.tar
+INSTALLED_USERDATATARBALL_TARGET := $(userdata_tar).bz2
+$(INSTALLED_USERDATATARBALL_TARGET): PRIVATE_USERDATA_TAR := $(userdata_tar)
+$(INSTALLED_USERDATATARBALL_TARGET): $(FS_GET_STATS) $(INTERNAL_USERDATAIMAGE_FILES)
+ $(build-userdatatarball-target)
+
+.PHONY: userdatatarball-nodeps
+userdatatarball-nodeps: $(FS_GET_STATS)
+ $(build-userdatatarball-target)
+
+
+# If neither TARGET_NO_KERNEL nor TARGET_NO_RECOVERY are true
+ifeq (,$(filter true, $(TARGET_NO_KERNEL) $(TARGET_NO_RECOVERY)))
+
+# -----------------------------------------------------------------
+# Recovery image
+INSTALLED_RECOVERYIMAGE_TARGET := $(PRODUCT_OUT)/recovery.img
+
+recovery_initrc := $(call include-path-for, recovery)/etc/init.rc
+recovery_kernel := $(INSTALLED_KERNEL_TARGET) # same as a non-recovery system
+recovery_ramdisk := $(PRODUCT_OUT)/ramdisk-recovery.img
+recovery_build_prop := $(INSTALLED_BUILD_PROP_TARGET)
+recovery_binary := $(call intermediates-dir-for,EXECUTABLES,recovery)/recovery
+recovery_resources_common := $(call include-path-for, recovery)/res
+recovery_resources_private := $(strip $(wildcard $(TARGET_DEVICE_DIR)/recovery/res))
+recovery_resource_deps := $(shell find $(recovery_resources_common) \
+ $(recovery_resources_private) -type f)
+
+ifeq ($(recovery_resources_private),)
+ $(info No private recovery resources for TARGET_DEVICE $(TARGET_DEVICE))
+endif
+
+INTERNAL_RECOVERYIMAGE_ARGS := \
+ $(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \
+ --kernel $(recovery_kernel) \
+ --ramdisk $(recovery_ramdisk)
+
+# Assumes this has already been stripped
+ifdef BOARD_KERNEL_CMDLINE
+ INTERNAL_RECOVERYIMAGE_ARGS += --cmdline "$(BOARD_KERNEL_CMDLINE)"
+endif
+
+$(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) \
+ $(INSTALLED_RAMDISK_TARGET) \
+ $(INSTALLED_BOOTIMAGE_TARGET) \
+ $(recovery_binary) \
+ $(recovery_initrc) $(recovery_kernel) \
+ $(INSTALLED_2NDBOOTLOADER_TARGET) \
+ $(recovery_build_prop) $(recovery_resource_deps)
+ @echo ----- Making recovery image ------
+ rm -rf $(TARGET_RECOVERY_OUT)
+ mkdir -p $(TARGET_RECOVERY_OUT)
+ mkdir -p $(TARGET_RECOVERY_ROOT_OUT)
+ mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/etc
+ mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/tmp
+ echo Copying baseline ramdisk...
+ cp -R $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT)
+ echo Modifying ramdisk contents...
+ cp -f $(recovery_initrc) $(TARGET_RECOVERY_ROOT_OUT)/
+ cp -f $(recovery_binary) $(TARGET_RECOVERY_ROOT_OUT)/sbin/
+ cp -rf $(recovery_resources_common) $(TARGET_RECOVERY_ROOT_OUT)/
+ $(foreach item,$(recovery_resources_private), \
+ cp -rf $(item) $(TARGET_RECOVERY_ROOT_OUT)/)
+ cat $(INSTALLED_DEFAULT_PROP_TARGET) $(recovery_build_prop) \
+ > $(TARGET_RECOVERY_ROOT_OUT)/default.prop
+ $(MKBOOTFS) $(TARGET_RECOVERY_ROOT_OUT) | gzip > $(recovery_ramdisk)
+ $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) --output $@
+ @echo ----- Made recovery image -------- $@
+ $(hide) $(call assert-max-file-size,$@,$(BOARD_RECOVERYIMAGE_MAX_SIZE))
+
+else
+INSTALLED_RECOVERYIMAGE_TARGET :=
+endif
+
+.PHONY: recoveryimage
+recoveryimage: $(INSTALLED_RECOVERYIMAGE_TARGET)
+
+# -----------------------------------------------------------------
+# bring in the installer image generation defines if necessary
+ifeq ($(TARGET_USE_DISKINSTALLER),true)
+include bootable/diskinstaller/config.mk
+endif
+
+# -----------------------------------------------------------------
+# OTA update package
+name := $(TARGET_PRODUCT)
+ifeq ($(TARGET_BUILD_TYPE),debug)
+ name := $(name)_debug
+endif
+name := $(name)-ota-$(FILE_NAME_TAG)
+
+INTERNAL_OTA_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip
+INTERNAL_OTA_INTERMEDIATES_DIR := $(call intermediates-dir-for,PACKAGING,ota)
+
+# If neither TARGET_NO_KERNEL nor TARGET_NO_RECOVERY are true
+ifeq (,$(filter true, $(TARGET_NO_KERNEL) $(TARGET_NO_RECOVERY)))
+INTERNAL_OTA_RECOVERYIMAGE_TARGET := $(INTERNAL_OTA_INTERMEDIATES_DIR)/system/recovery.img
+else
+INTERNAL_OTA_RECOVERYIMAGE_TARGET :=
+endif
+INTERNAL_OTA_SCRIPT_TARGET := $(INTERNAL_OTA_INTERMEDIATES_DIR)/META-INF/com/google/android/update-script
+
+# Sign OTA packages with the test key by default.
+# Actual product deliverables will be re-signed by hand.
+private_key := $(SRC_TARGET_DIR)/product/security/testkey.pk8
+certificate := $(SRC_TARGET_DIR)/product/security/testkey.x509.pem
+$(INTERNAL_OTA_PACKAGE_TARGET): $(private_key) $(certificate) $(SIGNAPK_JAR)
+$(INTERNAL_OTA_PACKAGE_TARGET): PRIVATE_PRIVATE_KEY := $(private_key)
+$(INTERNAL_OTA_PACKAGE_TARGET): PRIVATE_CERTIFICATE := $(certificate)
+
+# Depending on INSTALLED_SYSTEMIMAGE guarantees that SYSTEMIMAGE_SOURCE_DIR
+# is up-to-date. We use jar instead of zip so that we can use the -C
+# switch to avoid cd-ing all over the place.
+# TODO: Make our own jar-creation tool to avoid all these shenanigans.
+$(INTERNAL_OTA_PACKAGE_TARGET): \
+ $(INTERNAL_OTA_SCRIPT_TARGET) \
+ $(INTERNAL_OTA_RECOVERYIMAGE_TARGET) \
+ $(INSTALLED_BOOTIMAGE_TARGET) \
+ $(INSTALLED_RADIOIMAGE_TARGET) \
+ $(INSTALLED_ANDROID_INFO_TXT_TARGET) \
+ $(INSTALLED_SYSTEMIMAGE)
+ @echo "Package OTA: $@"
+ $(hide) rm -rf $@
+ $(hide) jar cf $@ \
+ $(foreach item, \
+ $(INSTALLED_BOOTIMAGE_TARGET) \
+ $(INSTALLED_RADIOIMAGE_TARGET) \
+ $(INSTALLED_ANDROID_INFO_TXT_TARGET), \
+ -C $(dir $(item)) $(notdir $(item))) \
+ -C $(INTERNAL_OTA_INTERMEDIATES_DIR) .
+ $(hide) find $(SYSTEMIMAGE_SOURCE_DIR) -type f -print | \
+ sed 's|^$(dir $(SYSTEMIMAGE_SOURCE_DIR))|-C & |' | \
+ xargs jar uf $@
+ $(hide) if jar tf $@ | egrep '.{65}' >&2; then \
+ echo "Path too long (>64 chars) for OTA update" >&2; \
+ exit 1; \
+ fi
+ $(sign-package)
+
+$(INTERNAL_OTA_SCRIPT_TARGET): \
+ $(HOST_OUT_EXECUTABLES)/make-update-script \
+ $(INSTALLED_ANDROID_INFO_TXT_TARGET) \
+ $(INSTALLED_SYSTEMIMAGE)
+ @mkdir -p $(dir $@)
+ @rm -rf $@
+ @echo "Update script: $@"
+ $(hide) TARGET_DEVICE=$(TARGET_DEVICE) \
+ $< $(SYSTEMIMAGE_SOURCE_DIR) \
+ $(INSTALLED_ANDROID_INFO_TXT_TARGET) \
+ > $@
+
+ifneq (,$(INTERNAL_OTA_RECOVERYIMAGE_TARGET))
+# This copy is so recovery.img can be in /system within the OTA package.
+# That way it gets installed into the system image, which in turn installs it.
+$(INTERNAL_OTA_RECOVERYIMAGE_TARGET): $(INSTALLED_RECOVERYIMAGE_TARGET) | $(ACP)
+ @mkdir -p $(dir $@)
+ $(hide) $(ACP) $< $@
+endif
+
+.PHONY: otapackage
+otapackage: $(INTERNAL_OTA_PACKAGE_TARGET)
+
+# Keys authorized to sign OTA packages this build will accept.
+ifeq ($(INCLUDE_TEST_OTA_KEYS),true)
+ OTA_PUBLIC_KEYS := \
+ $(sort $(SRC_TARGET_DIR)/product/security/testkey.x509.pem $(OTA_PUBLIC_KEYS))
+endif
+
+ifeq ($(OTA_PUBLIC_KEYS),)
+ $(error No OTA_PUBLIC_KEYS defined)
+endif
+
+# Build a keystore with the authorized keys in it.
+# java/android/android/server/checkin/UpdateVerifier.java uses this.
+ALL_DEFAULT_INSTALLED_MODULES += $(TARGET_OUT_ETC)/security/otacerts.zip
+$(TARGET_OUT_ETC)/security/otacerts.zip: $(OTA_PUBLIC_KEYS)
+ $(hide) rm -f $@
+ $(hide) mkdir -p $(dir $@)
+ zip -qj $@ $(OTA_PUBLIC_KEYS)
+
+# The device does not support JKS.
+# $(hide) for f in $(OTA_PUBLIC_KEYS); do \
+# echo "keytool: $@ <= $$f" && \
+# keytool -keystore $@ -storepass $(notdir $@) -noprompt \
+# -import -file $$f -alias $(notdir $$f) || exit 1; \
+# done
+
+ifdef RECOVERY_INSTALL_OTA_KEYS_INC
+# Generate a C-includable file containing the keys.
+# RECOVERY_INSTALL_OTA_KEYS_INC is defined by recovery/Android.mk.
+# *** THIS IS A TOTAL HACK; EXECUTABLES MUST NOT CHANGE BETWEEN DIFFERENT
+# PRODUCTS/BUILD TYPES. ***
+# TODO: make recovery read the keys from an external file.
+DUMPKEY_JAR := $(HOST_OUT_JAVA_LIBRARIES)/dumpkey.jar
+$(RECOVERY_INSTALL_OTA_KEYS_INC): PRIVATE_OTA_PUBLIC_KEYS := $(OTA_PUBLIC_KEYS)
+$(RECOVERY_INSTALL_OTA_KEYS_INC): $(OTA_PUBLIC_KEYS) $(DUMPKEY_JAR)
+ @echo "DumpPublicKey: $@ <= $(PRIVATE_OTA_PUBLIC_KEYS)"
+ @rm -rf $@
+ @mkdir -p $(dir $@)
+ $(hide) java -jar $(DUMPKEY_JAR) $(PRIVATE_OTA_PUBLIC_KEYS) > $@
+endif
+
+# -----------------------------------------------------------------
+# A zip of the directories that map to the target filesystem.
+# This zip can be used to create an OTA package or filesystem image
+# as a post-build step.
+#
+name := $(TARGET_PRODUCT)
+ifeq ($(TARGET_BUILD_TYPE),debug)
+ name := $(name)_debug
+endif
+name := $(name)-target_files-$(FILE_NAME_TAG)
+
+intermediates := $(call intermediates-dir-for,PACKAGING,target_files)
+BUILT_TARGET_FILES_PACKAGE := $(intermediates)/$(name).zip
+$(BUILT_TARGET_FILES_PACKAGE): intermediates := $(intermediates)
+$(BUILT_TARGET_FILES_PACKAGE): \
+ zip_root := $(intermediates)/$(name)
+
+# $(1): Directory to copy
+# $(2): Location to copy it to
+# The "ls -A" is to prevent "acp s/* d" from failing if s is empty.
+define package_files-copy-root
+ if [ -d "$(strip $(1))" -a "$$(ls -A $(1))" ]; then \
+ mkdir -p $(2) && \
+ $(ACP) -rd $(strip $(1))/* $(2); \
+ fi
+endef
+
+built_ota_tools := \
+ $(call intermediates-dir-for,EXECUTABLES,applypatch)/applypatch \
+ $(call intermediates-dir-for,EXECUTABLES,check_prereq)/check_prereq
+$(BUILT_TARGET_FILES_PACKAGE): PRIVATE_OTA_TOOLS := $(built_ota_tools)
+
+# Depending on the various images guarantees that the underlying
+# directories are up-to-date.
+$(BUILT_TARGET_FILES_PACKAGE): \
+ $(INTERNAL_OTA_SCRIPT_TARGET) \
+ $(INSTALLED_BOOTIMAGE_TARGET) \
+ $(INSTALLED_RADIOIMAGE_TARGET) \
+ $(INSTALLED_RECOVERYIMAGE_TARGET) \
+ $(BUILT_SYSTEMIMAGE) \
+ $(INSTALLED_USERDATAIMAGE_TARGET) \
+ $(INSTALLED_ANDROID_INFO_TXT_TARGET) \
+ $(INTERNAL_OTA_SCRIPT_TARGET) \
+ $(built_ota_tools) \
+ $(APKCERTS_FILE) \
+ | $(ACP)
+ @echo "Package target files: $@"
+ $(hide) rm -rf $@ $(zip_root)
+ $(hide) mkdir -p $(dir $@) $(zip_root)
+ @# Components of the recovery image
+ $(hide) mkdir -p $(zip_root)/RECOVERY
+ $(hide) $(call package_files-copy-root, \
+ $(TARGET_RECOVERY_ROOT_OUT),$(zip_root)/RECOVERY/RAMDISK)
+ifdef INSTALLED_KERNEL_TARGET
+ $(hide) $(ACP) $(INSTALLED_KERNEL_TARGET) $(zip_root)/RECOVERY/kernel
+endif
+ifdef INSTALLED_2NDBOOTLOADER_TARGET
+ $(hide) $(ACP) \
+ $(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/RECOVERY/second
+endif
+ifdef BOARD_KERNEL_CMDLINE
+ $(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/RECOVERY/cmdline
+endif
+ @# Components of the boot image
+ $(hide) mkdir -p $(zip_root)/BOOT
+ $(hide) $(call package_files-copy-root, \
+ $(TARGET_ROOT_OUT),$(zip_root)/BOOT/RAMDISK)
+ifdef INSTALLED_KERNEL_TARGET
+ $(hide) $(ACP) $(INSTALLED_KERNEL_TARGET) $(zip_root)/BOOT/kernel
+endif
+ifdef INSTALLED_2NDBOOTLOADER_TARGET
+ $(hide) $(ACP) \
+ $(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/BOOT/second
+endif
+ifdef BOARD_KERNEL_CMDLINE
+ $(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/BOOT/cmdline
+endif
+ifdef INSTALLED_RADIOIMAGE_TARGET
+ @# The radio image
+ $(hide) mkdir -p $(zip_root)/RADIO
+ $(hide) $(ACP) $(INSTALLED_RADIOIMAGE_TARGET) $(zip_root)/RADIO/image
+endif
+ @# Contents of the system image
+ $(hide) $(call package_files-copy-root, \
+ $(SYSTEMIMAGE_SOURCE_DIR),$(zip_root)/SYSTEM)
+ @# Contents of the data image
+ $(hide) $(call package_files-copy-root, \
+ $(TARGET_OUT_DATA),$(zip_root)/DATA)
+ @# Extra contents of the OTA package
+ $(hide) mkdir -p $(zip_root)/OTA/bin
+ $(hide) $(call package_files-copy-root, \
+ $(INTERNAL_OTA_INTERMEDIATES_DIR),$(zip_root)/OTA)
+ $(hide) $(ACP) $(INSTALLED_ANDROID_INFO_TXT_TARGET) $(zip_root)/OTA/
+ $(hide) $(ACP) $(PRIVATE_OTA_TOOLS) $(zip_root)/OTA/bin/
+ @# Files that don't end up in any images, but are necessary to
+ @# build them.
+ $(hide) mkdir -p $(zip_root)/META
+ $(hide) $(ACP) $(APKCERTS_FILE) $(zip_root)/META/apkcerts.txt
+ @# Zip everything up, preserving symlinks
+ $(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .)
+
+target-files-package: $(BUILT_TARGET_FILES_PACKAGE)
+
+# -----------------------------------------------------------------
+# installed file list
+# Depending on $(INSTALLED_SYSTEMIMAGE) ensures that it
+# gets the DexOpt one if we're doing that.
+INSTALLED_FILES_FILE := $(PRODUCT_OUT)/installed-files.txt
+$(INSTALLED_FILES_FILE): $(INSTALLED_SYSTEMIMAGE)
+ @echo Installed file list: $@
+ @mkdir -p $(dir $@)
+ @rm -f $@
+ $(hide) build/tools/fileslist.py $(TARGET_OUT) $(TARGET_OUT_DATA) > $@
+
+.PHONY: installed-file-list
+installed-file-list: $(INSTALLED_FILES_FILE)
+$(call dist-for-goals, sdk, $(INSTALLED_FILES_FILE))
+
+# -----------------------------------------------------------------
+# A zip of the tests that are built when running "make tests".
+# This is very similar to BUILT_TARGET_FILES_PACKAGE, but we
+# only grab SYSTEM and DATA, and it's called "*-tests-*.zip".
+#
+name := $(TARGET_PRODUCT)
+ifeq ($(TARGET_BUILD_TYPE),debug)
+ name := $(name)_debug
+endif
+name := $(name)-tests-$(FILE_NAME_TAG)
+
+intermediates := $(call intermediates-dir-for,PACKAGING,tests_zip)
+BUILT_TESTS_ZIP_PACKAGE := $(intermediates)/$(name).zip
+$(BUILT_TESTS_ZIP_PACKAGE): intermediates := $(intermediates)
+$(BUILT_TESTS_ZIP_PACKAGE): zip_root := $(intermediates)/$(name)
+
+# Depending on the images guarantees that the underlying
+# directories are up-to-date.
+$(BUILT_TESTS_ZIP_PACKAGE): \
+ $(BUILT_SYSTEMIMAGE) \
+ $(INSTALLED_USERDATAIMAGE_TARGET) \
+ | $(ACP)
+ @echo "Package test files: $@"
+ $(hide) rm -rf $@ $(zip_root)
+ $(hide) mkdir -p $(dir $@) $(zip_root)
+ @# Some parts of the system image
+ $(hide) $(call package_files-copy-root, \
+ $(SYSTEMIMAGE_SOURCE_DIR)/xbin,$(zip_root)/SYSTEM/xbin)
+ $(hide) $(call package_files-copy-root, \
+ $(SYSTEMIMAGE_SOURCE_DIR)/lib,$(zip_root)/SYSTEM/lib)
+ $(hide) $(call package_files-copy-root, \
+ $(SYSTEMIMAGE_SOURCE_DIR)/framework, \
+ $(zip_root)/SYSTEM/framework)
+ $(hide) $(ACP) $(SYSTEMIMAGE_SOURCE_DIR)/build.prop $(zip_root)/SYSTEM
+ @# Contents of the data image
+ $(hide) $(call package_files-copy-root, \
+ $(TARGET_OUT_DATA),$(zip_root)/DATA)
+ $(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .)
+
+tests-zip-package: $(BUILT_TESTS_ZIP_PACKAGE)
+
+# -----------------------------------------------------------------
+# A zip of the symbols directory. Keep the full paths to make it
+# more obvious where these files came from.
+#
+name := $(TARGET_PRODUCT)
+ifeq ($(TARGET_BUILD_TYPE),debug)
+ name := $(name)_debug
+endif
+name := $(name)-symbols-$(FILE_NAME_TAG)
+
+SYMBOLS_ZIP := $(PRODUCT_OUT)/$(name).zip
+$(SYMBOLS_ZIP): $(INSTALLED_SYSTEMIMAGE) $(INSTALLED_BOOTIMAGE_TARGET)
+ @echo "Package symbols: $@"
+ $(hide) rm -rf $@
+ $(hide) mkdir -p $(dir $@)
+ $(hide) zip -qr $@ $(TARGET_OUT_UNSTRIPPED)
+
+# -----------------------------------------------------------------
+# A zip of the Android Apps. Not keeping full path so that we don't
+# include product names when distributing
+#
+name := $(TARGET_PRODUCT)
+ifeq ($(TARGET_BUILD_TYPE),debug)
+ name := $(name)_debug
+endif
+name := $(name)-apps-$(FILE_NAME_TAG)
+
+APPS_ZIP := $(PRODUCT_OUT)/$(name).zip
+$(APPS_ZIP): $(INSTALLED_SYSTEMIMAGE)
+ @echo "Package apps: $@"
+ $(hide) rm -rf $@
+ $(hide) mkdir -p $(dir $@)
+ $(hide) zip -qj $@ $(TARGET_OUT_APPS)/*
+
+endif # TARGET_SIMULATOR != true
+
+# -----------------------------------------------------------------
+# dalvik something
+.PHONY: dalvikfiles
+dalvikfiles: $(INTERNAL_DALVIK_MODULES)
+
+# -----------------------------------------------------------------
+# The update package
+
+INTERNAL_UPDATE_PACKAGE_FILES += \
+ $(INSTALLED_BOOTIMAGE_TARGET) \
+ $(INSTALLED_RECOVERYIMAGE_TARGET) \
+ $(INSTALLED_SYSTEMIMAGE) \
+ $(INSTALLED_USERDATAIMAGE_TARGET) \
+ $(INSTALLED_ANDROID_INFO_TXT_TARGET)
+
+ifneq ($(strip $(INTERNAL_UPDATE_PACKAGE_FILES)),)
+
+name := $(TARGET_PRODUCT)
+ifeq ($(TARGET_BUILD_TYPE),debug)
+ name := $(name)_debug
+endif
+name := $(name)-img-$(FILE_NAME_TAG)
+
+INTERNAL_UPDATE_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip
+
+$(INTERNAL_UPDATE_PACKAGE_TARGET): $(INTERNAL_UPDATE_PACKAGE_FILES)
+ @echo "Package: $@"
+ $(hide) zip -qj $@ $(INTERNAL_UPDATE_PACKAGE_FILES)
+
+else
+INTERNAL_UPDATE_PACKAGE_TARGET :=
+endif
+
+# -----------------------------------------------------------------
+# The emulator package
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+INTERNAL_EMULATOR_PACKAGE_FILES += \
+ $(HOST_OUT_EXECUTABLES)/emulator$(HOST_EXECUTABLE_SUFFIX) \
+ prebuilt/android-arm/kernel/kernel-qemu \
+ $(INSTALLED_RAMDISK_TARGET) \
+ $(INSTALLED_SYSTEMIMAGE) \
+ $(INSTALLED_USERDATAIMAGE_TARGET)
+
+name := $(TARGET_PRODUCT)-emulator-$(FILE_NAME_TAG)
+
+INTERNAL_EMULATOR_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip
+
+$(INTERNAL_EMULATOR_PACKAGE_TARGET): $(INTERNAL_EMULATOR_PACKAGE_FILES)
+ @echo "Package: $@"
+ $(hide) zip -qj $@ $(INTERNAL_EMULATOR_PACKAGE_FILES)
+
+endif
+
+# -----------------------------------------------------------------
+# The pdk package (Platform Development Kit)
+
+ifneq (,$(filter pdk,$(MAKECMDGOALS)))
+ include development/pdk/Pdk.mk
+endif
+
+# -----------------------------------------------------------------
+# The SDK
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+# The SDK includes host-specific components, so it belongs under HOST_OUT.
+sdk_dir := $(HOST_OUT)/sdk
+
+# Build a name that looks like:
+#
+# linux-x86 --> android-sdk_12345_linux-x86
+# darwin-x86 --> android-sdk_12345_mac-x86
+# windows-x86 --> android-sdk_12345_windows
+#
+sdk_name := android-sdk_$(FILE_NAME_TAG)
+ifeq ($(HOST_OS),darwin)
+ sdk_host_os := mac
+else
+ sdk_host_os := $(HOST_OS)
+endif
+ifneq ($(HOST_OS),windows)
+ sdk_host_os := $(sdk_host_os)-$(HOST_ARCH)
+endif
+sdk_name := $(sdk_name)_$(sdk_host_os)
+
+sdk_dep_file := $(sdk_dir)/sdk_deps.mk
+
+ATREE_FILES :=
+-include $(sdk_dep_file)
+
+# if we don't have a real list, then use "everything"
+ifeq ($(strip $(ATREE_FILES)),)
+ATREE_FILES := \
+ $(ALL_PREBUILT) \
+ $(ALL_COPIED_HEADERS) \
+ $(ALL_GENERATED_SOURCES) \
+ $(ALL_DEFAULT_INSTALLED_MODULES) \
+ $(INSTALLED_RAMDISK_TARGET) \
+ $(ALL_DOCS) \
+ $(ALL_SDK_FILES)
+endif
+
+atree_dir := development/build
+
+sdk_atree_files := \
+ $(atree_dir)/sdk.exclude.atree \
+ $(atree_dir)/sdk.atree \
+ $(atree_dir)/sdk-$(HOST_OS)-$(HOST_ARCH).atree
+
+deps := \
+ $(target_notice_file_txt) \
+ $(tools_notice_file_txt) \
+ $(OUT_DOCS)/offline-sdk-timestamp \
+ $(INTERNAL_UPDATE_PACKAGE_TARGET) \
+ $(INSTALLED_SDK_BUILD_PROP_TARGET) \
+ $(ATREE_FILES) \
+ $(atree_dir)/sdk.atree \
+ $(HOST_OUT_EXECUTABLES)/atree \
+ $(HOST_OUT_EXECUTABLES)/line_endings
+
+INTERNAL_SDK_TARGET := $(sdk_dir)/$(sdk_name).zip
+$(INTERNAL_SDK_TARGET): PRIVATE_NAME := $(sdk_name)
+$(INTERNAL_SDK_TARGET): PRIVATE_DIR := $(sdk_dir)/$(sdk_name)
+$(INTERNAL_SDK_TARGET): PRIVATE_DEP_FILE := $(sdk_dep_file)
+$(INTERNAL_SDK_TARGET): PRIVATE_INPUT_FILES := $(sdk_atree_files)
+
+# Set SDK_GNU_ERROR to non-empty to fail when a GNU target is built.
+#
+#SDK_GNU_ERROR := true
+
+$(INTERNAL_SDK_TARGET): $(deps)
+ @echo "Package SDK: $@"
+ $(hide) rm -rf $(PRIVATE_DIR) $@
+ $(hide) for f in $(target_gnu_MODULES); do \
+ if [ -f $$f ]; then \
+ echo SDK: $(if $(SDK_GNU_ERROR),ERROR:,warning:) \
+ including GNU target $$f >&2; \
+ FAIL=$(SDK_GNU_ERROR); \
+ fi; \
+ done; \
+ if [ $$FAIL ]; then exit 1; fi
+ $(hide) ( \
+ $(HOST_OUT_EXECUTABLES)/atree \
+ $(addprefix -f ,$(PRIVATE_INPUT_FILES)) \
+ -m $(PRIVATE_DEP_FILE) \
+ -I . \
+ -I $(PRODUCT_OUT) \
+ -I $(HOST_OUT) \
+ -I $(TARGET_COMMON_OUT_ROOT) \
+ -v "PLATFORM_NAME=android-$(PLATFORM_VERSION)" \
+ -o $(PRIVATE_DIR) && \
+ cp -f $(target_notice_file_txt) \
+ $(PRIVATE_DIR)/platforms/android-$(PLATFORM_VERSION)/images/NOTICE.txt && \
+ cp -f $(tools_notice_file_txt) $(PRIVATE_DIR)/tools/NOTICE.txt && \
+ HOST_OUT_EXECUTABLES=$(HOST_OUT_EXECUTABLES) HOST_OS=$(HOST_OS) \
+ development/tools/scripts/sdk_clean.sh $(PRIVATE_DIR) && \
+ chmod -R ug+rwX $(PRIVATE_DIR) && \
+ cd $(dir $@) && zip -rq $(notdir $@) $(PRIVATE_NAME) \
+ ) || ( rm -rf $(PRIVATE_DIR) $@ && exit 44 )
+
+endif # !simulator
+
+# -----------------------------------------------------------------
+# Findbugs
+INTERNAL_FINDBUGS_XML_TARGET := $(PRODUCT_OUT)/findbugs.xml
+INTERNAL_FINDBUGS_HTML_TARGET := $(PRODUCT_OUT)/findbugs.html
+$(INTERNAL_FINDBUGS_XML_TARGET): $(ALL_FINDBUGS_FILES)
+ @echo UnionBugs: $@
+ $(hide) prebuilt/common/findbugs/bin/unionBugs $(ALL_FINDBUGS_FILES) \
+ > $@
+$(INTERNAL_FINDBUGS_HTML_TARGET): $(INTERNAL_FINDBUGS_XML_TARGET)
+ @echo ConvertXmlToText: $@
+ $(hide) prebuilt/common/findbugs/bin/convertXmlToText -html:fancy.xsl \
+ $(INTERNAL_FINDBUGS_XML_TARGET) > $@
+
+# -----------------------------------------------------------------
+# Findbugs
+
+# -----------------------------------------------------------------
+# These are some additional build tasks that need to be run.
+include $(sort $(wildcard $(BUILD_SYSTEM)/tasks/*.mk))
diff --git a/core/apicheck_msg_current.txt b/core/apicheck_msg_current.txt
new file mode 100644
index 0000000..c277ecd
--- /dev/null
+++ b/core/apicheck_msg_current.txt
@@ -0,0 +1,18 @@
+
+******************************
+You have tried to change the API from what has been previously approved.
+
+To make these errors go away, you have two choices:
+ 1) You can add "@hide" javadoc comments to the methods, etc. listed in the
+ errors above.
+
+ 2) You can update current.xml by executing the following commands:
+
+ p4 edit frameworks/base/api/current.xml
+ make update-api
+
+ To check in the revised current.xml, you will need OWNERS approval.
+******************************
+
+
+
diff --git a/core/apicheck_msg_last.txt b/core/apicheck_msg_last.txt
new file mode 100644
index 0000000..2993157
--- /dev/null
+++ b/core/apicheck_msg_last.txt
@@ -0,0 +1,7 @@
+
+******************************
+You have tried to change the API from what has been previously released in
+an SDK. Please fix the errors listed above.
+******************************
+
+
diff --git a/core/armelf.x b/core/armelf.x
new file mode 100644
index 0000000..766fe88
--- /dev/null
+++ b/core/armelf.x
@@ -0,0 +1,198 @@
+/* Default linker script, for normal executables */
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
+ "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SEARCH_DIR("/usr/local/armdev/arm-elf/lib");
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+/* PROVIDE (__executable_start = 0x8000); . = 0x8000; */
+. = 0x8000 + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rel.init : { *(.rel.init) }
+ .rela.init : { *(.rela.init) }
+ .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
+ .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
+ .rel.fini : { *(.rel.fini) }
+ .rela.fini : { *(.rela.fini) }
+ .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
+ .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
+ .rel.data.rel.ro : { *(.rel.data.rel.ro*) }
+ .rela.data.rel.ro : { *(.rel.data.rel.ro*) }
+ .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+ .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
+ .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
+ .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
+ .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
+ .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
+ .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init :
+ {
+ KEEP (*(.init))
+ } =0
+ .plt : { *(.plt) }
+ .text :
+ {
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ KEEP (*(.text.*personality*))
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.glue_7t) *(.glue_7)
+ } =0
+ .fini :
+ {
+ KEEP (*(.fini))
+ } =0
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+ .rodata1 : { *(.rodata1) }
+ /* We have to wrap extab and exidx sections with KEEP because we use
+ --gc-sections. */
+ .ARM.extab : { KEEP (*(.ARM.extab* .gnu.linkonce.armextab.*)) }
+ __exidx_start = .;
+ .ARM.exidx : { KEEP (*(.ARM.exidx* .gnu.linkonce.armexidx.*)) }
+ __exidx_end = .;
+ .eh_frame_hdr : { *(.eh_frame_hdr) }
+ .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+ .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
+ /* Adjust the address for the data segment. We want to align at exactly
+ a page boundary to make life easier for apriori. */
+ . = ALIGN(4096);
+ /* Exception handling */
+ .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
+ .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
+ /* Thread Local Storage sections */
+ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+ .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+ /* Ensure the __preinit_array_start label is properly aligned. We
+ could instead move the label definition inside the section, but
+ the linker would then create the section even if it turns out to
+ be empty, which isn't pretty. */
+ . = ALIGN(32 / 8);
+ PROVIDE (__preinit_array_start = .);
+ .preinit_array : { KEEP (*(.preinit_array)) }
+ PROVIDE (__preinit_array_end = .);
+ PROVIDE (__init_array_start = .);
+ .init_array : { KEEP (*(.init_array)) }
+ PROVIDE (__init_array_end = .);
+ PROVIDE (__fini_array_start = .);
+ .fini_array : { KEEP (*(.fini_array)) }
+ PROVIDE (__fini_array_end = .);
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin*.o(.ctors))
+ /* We don't want to include the .ctor section from
+ from the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ }
+ .dtors :
+ {
+ KEEP (*crtbegin*.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ }
+ .jcr : { KEEP (*(.jcr)) }
+ .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) }
+ .dynamic : { *(.dynamic) }
+ .got : { *(.got.plt) *(.got) }
+ .data :
+ {
+ __data_start = . ;
+ *(.data .data.* .gnu.linkonce.d.*)
+ KEEP (*(.gnu.linkonce.d.*personality*))
+ SORT(CONSTRUCTORS)
+ }
+ .data1 : { *(.data1) }
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ __bss_start__ = .;
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections. */
+ . = ALIGN(32 / 8);
+ }
+ . = ALIGN(32 / 8);
+ _end = .;
+ _bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
+ PROVIDE (end = .);
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ .stack 0x80000 :
+ {
+ _stack = .;
+ *(.stack)
+ }
+ .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+ /DISCARD/ : { *(.note.GNU-stack) }
+}
diff --git a/core/armelf.xsc b/core/armelf.xsc
new file mode 100644
index 0000000..4253054
--- /dev/null
+++ b/core/armelf.xsc
@@ -0,0 +1,201 @@
+/* Script for --shared -z combreloc: shared library, combine & sort relocs */
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
+ "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0 + SIZEOF_HEADERS;
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rel.dyn :
+ {
+ *(.rel.init)
+ *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+ *(.rel.fini)
+ *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+ *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
+ *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+ *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+ *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+ *(.rel.ctors)
+ *(.rel.dtors)
+ *(.rel.got)
+ *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+ }
+ .rela.dyn :
+ {
+ *(.rela.init)
+ *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+ *(.rela.fini)
+ *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+ *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+ *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+ *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+ *(.rela.ctors)
+ *(.rela.dtors)
+ *(.rela.got)
+ *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+ }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init :
+ {
+ KEEP (*(.init))
+ } =0
+ .plt : { *(.plt) }
+ .text :
+ {
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ KEEP (*(.text.*personality*))
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.glue_7t) *(.glue_7)
+ } =0
+ .fini :
+ {
+ KEEP (*(.fini))
+ } =0
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+ .rodata1 : { *(.rodata1) }
+ /* We have to wrap extab and exidx sections with KEEP because we use
+ --gc-sections. */
+ .ARM.extab : { KEEP (*(.ARM.extab* .gnu.linkonce.armextab.*)) }
+ __exidx_start = .;
+ .ARM.exidx : { KEEP (*(.ARM.exidx* .gnu.linkonce.armexidx.*)) }
+ __exidx_end = .;
+ .eh_frame_hdr : { *(.eh_frame_hdr) }
+ .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+ .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
+ /* Adjust the address for the data segment. We want to align at exactly
+ a page boundary to make life easier for apriori. */
+ . = ALIGN(4096);
+ /* Exception handling */
+ .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
+ .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+ /* Thread Local Storage sections */
+ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+ .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+ .preinit_array :
+ {
+ KEEP (*(.preinit_array))
+ }
+ .init_array :
+ {
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ }
+ .fini_array :
+ {
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ }
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin*.o(.ctors))
+ /* We don't want to include the .ctor section from
+ the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ }
+ .dtors :
+ {
+ KEEP (*crtbegin*.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ }
+ .jcr : { KEEP (*(.jcr)) }
+ .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
+ .dynamic : { *(.dynamic) }
+ .got : { *(.got.plt) *(.got) }
+ .data :
+ {
+ __data_start = . ;
+ *(.data .data.* .gnu.linkonce.d.*)
+ KEEP (*(.gnu.linkonce.d.*personality*))
+ SORT(CONSTRUCTORS)
+ }
+ .data1 : { *(.data1) }
+ _edata = .; PROVIDE (edata = .);
+ __bss_start = .;
+ __bss_start__ = .;
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections.
+ FIXME: Why do we need it? When there is no .bss section, we don't
+ pad the .data section. */
+ . = ALIGN(. != 0 ? 32 / 8 : 1);
+ }
+ _bss_end__ = . ; __bss_end__ = . ;
+ . = ALIGN(32 / 8);
+ . = ALIGN(32 / 8);
+ __end__ = . ;
+ _end = .; PROVIDE (end = .);
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ .stack 0x80000 :
+ {
+ _stack = .;
+ *(.stack)
+ }
+ .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+ .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
+ /DISCARD/ : { *(.note.GNU-stack) }
+}
diff --git a/core/armelflib.x b/core/armelflib.x
new file mode 100644
index 0000000..0150e02
--- /dev/null
+++ b/core/armelflib.x
@@ -0,0 +1,164 @@
+/* Default linker script, for normal executables */
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
+ "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SEARCH_DIR("/usr/local/armdev/arm-elf/lib");
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+/* PROVIDE (__executable_start = 0x8000); . = 0x8000; */
+. = 0 + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .init :
+ {
+ KEEP (*(.init))
+ } =0
+ .plt : { *(.plt) }
+ .text :
+ {
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ KEEP (*(.text.*personality*))
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.glue_7t) *(.glue_7)
+ } =0
+ .fini :
+ {
+ KEEP (*(.fini))
+ } =0
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+ .rodata1 : { *(.rodata1) }
+ .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) }
+ __exidx_start = .;
+ .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+ __exidx_end = .;
+ .eh_frame_hdr : { *(.eh_frame_hdr) }
+ .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+ .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. */
+ . = ALIGN(256) + (. & (256 - 1));
+ /* Exception handling */
+ .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
+ .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
+ /* Thread Local Storage sections */
+ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+ .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+ /* Ensure the __preinit_array_start label is properly aligned. We
+ could instead move the label definition inside the section, but
+ the linker would then create the section even if it turns out to
+ be empty, which isn't pretty. */
+ . = ALIGN(32 / 8);
+ PROVIDE (__preinit_array_start = .);
+ .preinit_array : { KEEP (*(.preinit_array)) }
+ PROVIDE (__preinit_array_end = .);
+ PROVIDE (__init_array_start = .);
+ .init_array : { KEEP (*(.init_array)) }
+ PROVIDE (__init_array_end = .);
+ PROVIDE (__fini_array_start = .);
+ .fini_array : { KEEP (*(.fini_array)) }
+ PROVIDE (__fini_array_end = .);
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin*.o(.ctors))
+ /* We don't want to include the .ctor section from
+ from the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ }
+ .dtors :
+ {
+ KEEP (*crtbegin*.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ }
+ .jcr : { KEEP (*(.jcr)) }
+ .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) }
+ .got : { *(.got.plt) *(.got) }
+ .data :
+ {
+ __data_start = . ;
+ *(.data .data.* .gnu.linkonce.d.*)
+ KEEP (*(.gnu.linkonce.d.*personality*))
+ SORT(CONSTRUCTORS)
+ }
+ .data1 : { *(.data1) }
+ _edata = .;
+ PROVIDE (edata = .);
+ .dynamic : { *(.dynamic) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+/* .shstrtab : { *(.shstrtab) } */
+ .rel.plt : { *(.rel.plt) }
+ .rel.dyn : { *(.rel.*) }
+ __bss_start = .;
+ __bss_start__ = .;
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections. */
+ . = ALIGN(32 / 8);
+ }
+ . = ALIGN(32 / 8);
+ _end = .;
+ _bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
+ PROVIDE (end = .);
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+ /DISCARD/ : { *(.note.GNU-stack) *(.comment*) *(.stack*) *(.shstrtab) }
+}
diff --git a/core/base_rules.mk b/core/base_rules.mk
new file mode 100644
index 0000000..ba89c40
--- /dev/null
+++ b/core/base_rules.mk
@@ -0,0 +1,441 @@
+#
+# 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.
+#
+
+# Users can define base-rules-hook in their buildspec.mk to perform
+# arbitrary operations as each module is included.
+ifdef base-rules-hook
+$(if $(base-rules-hook),)
+endif
+
+###########################################################
+## Common instructions for a generic module.
+###########################################################
+
+LOCAL_MODULE := $(strip $(LOCAL_MODULE))
+ifeq ($(LOCAL_MODULE),)
+ $(error $(LOCAL_PATH): LOCAL_MODULE is not defined)
+endif
+
+LOCAL_IS_HOST_MODULE := $(strip $(LOCAL_IS_HOST_MODULE))
+ifdef LOCAL_IS_HOST_MODULE
+ ifneq ($(LOCAL_IS_HOST_MODULE),true)
+ $(error $(LOCAL_PATH): LOCAL_IS_HOST_MODULE must be "true" or empty, not "$(LOCAL_IS_HOST_MODULE)")
+ endif
+ my_prefix:=HOST_
+ my_host:=host-
+else
+ my_prefix:=TARGET_
+ my_host:=
+endif
+
+###########################################################
+## Validate and define fallbacks for input LOCAL_* variables.
+###########################################################
+
+## Dump a .csv file of all modules and their tags
+#ifneq ($(tag-list-first-time),false)
+#$(shell rm -f tag-list.csv)
+#tag-list-first-time := false
+#endif
+#comma := ,
+#empty :=
+#space := $(empty) $(empty)
+#$(shell echo $(lastword $(filter-out config/% out/%,$(MAKEFILE_LIST))),$(LOCAL_MODULE),$(strip $(LOCAL_MODULE_CLASS)),$(subst $(space),$(comma),$(sort $(LOCAL_MODULE_TAGS))) >> tag-list.csv)
+
+LOCAL_MODULE_TAGS := $(sort $(LOCAL_MODULE_TAGS))
+ifeq (,$(LOCAL_MODULE_TAGS))
+# Modules without tags fall back to user (which is changed to user eng below)
+LOCAL_MODULE_TAGS := user
+#$(warning default tags: $(lastword $(filter-out config/% out/%,$(MAKEFILE_LIST))))
+endif
+
+# Add implicit tags.
+#
+# If the local directory or one of its parents contains a MODULE_LICENSE_GPL
+# file, tag the module as "gnu". Search for "*_GNU*" so that we can also
+# find files like MODULE_LICENSE_GPL_AND_AFL but exclude files like
+# MODULE_LICENSE_LGPL.
+#
+ifneq ($(call find-parent-file,$(LOCAL_PATH),MODULE_LICENSE*_GPL*),)
+ LOCAL_MODULE_TAGS += gnu
+endif
+
+#
+# If this module is listed on CUSTOM_MODULES, promote it to "user"
+# so that it will be installed in $(TARGET_OUT).
+#
+ifneq (,$(filter $(LOCAL_MODULE),$(CUSTOM_MODULES)))
+ LOCAL_MODULE_TAGS := $(sort $(LOCAL_MODULE_TAGS) user)
+endif
+
+# The definition of should-install-to-system will be different depending
+# on which goal (e.g., user/eng/sdk) is being built.
+ifdef LOCAL_IS_HOST_MODULE
+ use_data :=
+else
+ use_data := $(if $(call should-install-to-system,$(LOCAL_MODULE_TAGS)),,_DATA)
+endif
+
+LOCAL_MODULE_CLASS := $(strip $(LOCAL_MODULE_CLASS))
+ifneq ($(words $(LOCAL_MODULE_CLASS)),1)
+ $(error $(LOCAL_PATH): LOCAL_MODULE_CLASS must contain exactly one word, not "$(LOCAL_MODULE_CLASS)")
+endif
+
+# Add a tag like "_class@APPS" to this module so that we can filter
+# based on the class.
+LOCAL_MODULE_TAGS += _class@$(LOCAL_MODULE_CLASS)
+
+LOCAL_MODULE_PATH := $(strip $(LOCAL_MODULE_PATH))
+ifeq ($(LOCAL_MODULE_PATH),)
+ LOCAL_MODULE_PATH := $($(my_prefix)OUT$(use_data)_$(LOCAL_MODULE_CLASS))
+ ifeq ($(strip $(LOCAL_MODULE_PATH)),)
+ $(error $(LOCAL_PATH): unhandled LOCAL_MODULE_CLASS "$(LOCAL_MODULE_CLASS)")
+ endif
+endif
+
+ifneq ($(strip $(LOCAL_BUILT_MODULE)$(LOCAL_INSTALLED_MODULE)),)
+ $(error $(LOCAL_PATH): LOCAL_BUILT_MODULE and LOCAL_INSTALLED_MODULE must not be defined by component makefiles)
+endif
+
+# Make sure that this IS_HOST/CLASS/MODULE combination is unique.
+module_id := MODULE.$(if \
+ $(LOCAL_IS_HOST_MODULE),HOST,TARGET).$(LOCAL_MODULE_CLASS).$(LOCAL_MODULE)
+ifdef $(module_id)
+$(error $(LOCAL_PATH): $(module_id) already defined by $($(module_id)))
+endif
+$(module_id) := $(LOCAL_PATH)
+
+intermediates := $(call local-intermediates-dir)
+intermediates.COMMON := $(call local-intermediates-dir,COMMON)
+
+###########################################################
+# Pick a name for the intermediate and final targets
+###########################################################
+LOCAL_MODULE_STEM := $(strip $(LOCAL_MODULE_STEM))
+ifeq ($(LOCAL_MODULE_STEM),)
+ LOCAL_MODULE_STEM := $(LOCAL_MODULE)
+endif
+LOCAL_INSTALLED_MODULE_STEM := $(LOCAL_MODULE_STEM)$(LOCAL_MODULE_SUFFIX)
+
+LOCAL_BUILT_MODULE_STEM := $(strip $(LOCAL_BUILT_MODULE_STEM))
+ifeq ($(LOCAL_BUILT_MODULE_STEM),)
+ LOCAL_BUILT_MODULE_STEM := $(LOCAL_INSTALLED_MODULE_STEM)
+endif
+
+# OVERRIDE_BUILT_MODULE_PATH is only allowed to be used by the
+# internal SHARED_LIBRARIES build files.
+OVERRIDE_BUILT_MODULE_PATH := $(strip $(OVERRIDE_BUILT_MODULE_PATH))
+ifdef OVERRIDE_BUILT_MODULE_PATH
+ ifneq ($(LOCAL_MODULE_CLASS),SHARED_LIBRARIES)
+ $(error $(LOCAL_PATH): Illegal use of OVERRIDE_BUILT_MODULE_PATH)
+ endif
+ built_module_path := $(OVERRIDE_BUILT_MODULE_PATH)
+else
+ built_module_path := $(intermediates)
+endif
+LOCAL_BUILT_MODULE := $(built_module_path)/$(LOCAL_BUILT_MODULE_STEM)
+built_module_path :=
+
+# LOCAL_UNINSTALLABLE_MODULE is only allowed to be used by the
+# internal STATIC_LIBRARIES build files.
+LOCAL_UNINSTALLABLE_MODULE := $(strip $(LOCAL_UNINSTALLABLE_MODULE))
+ifdef LOCAL_UNINSTALLABLE_MODULE
+ ifeq (,$(filter $(LOCAL_MODULE_CLASS),JAVA_LIBRARIES STATIC_LIBRARIES))
+ $(error $(LOCAL_PATH): Illegal use of LOCAL_UNINSTALLABLE_MODULE)
+ endif
+else
+ LOCAL_INSTALLED_MODULE := $(LOCAL_MODULE_PATH)/$(LOCAL_MODULE_SUBDIR)$(LOCAL_INSTALLED_MODULE_STEM)
+endif
+
+# Assemble the list of targets to create PRIVATE_ variables for.
+LOCAL_INTERMEDIATE_TARGETS += $(LOCAL_BUILT_MODULE)
+
+
+###########################################################
+## AIDL: Compile .aidl files to .java
+###########################################################
+
+aidl_sources := $(filter %.aidl,$(LOCAL_SRC_FILES))
+
+ifneq ($(strip $(aidl_sources)),)
+
+aidl_java_sources := $(patsubst %.aidl,%.java,$(addprefix $(intermediates.COMMON)/src/, $(aidl_sources)))
+aidl_sources := $(addprefix $(TOP_DIR)$(LOCAL_PATH)/, $(aidl_sources))
+
+$(aidl_java_sources): PRIVATE_AIDL_FLAGS := -b -I$(LOCAL_PATH) -I$(LOCAL_PATH)/src $(addprefix -I,$(LOCAL_AIDL_INCLUDES))
+
+$(aidl_java_sources): $(intermediates.COMMON)/src/%.java: $(TOPDIR)$(LOCAL_PATH)/%.aidl $(PRIVATE_ADDITIONAL_DEPENDENCIES) $(AIDL)
+ $(transform-aidl-to-java)
+-include $(aidl_java_sources:%.java=%.P)
+
+else
+aidl_java_sources :=
+endif
+
+###########################################################
+## Java: Compile .java files to .class
+###########################################################
+#TODO: pull this into java.make once host and target are combined
+
+java_sources := $(addprefix $(TOP_DIR)$(LOCAL_PATH)/, $(filter %.java,$(LOCAL_SRC_FILES))) $(aidl_java_sources)
+all_java_sources := $(java_sources) $(addprefix $($(my_prefix)OUT_COMMON_INTERMEDIATES)/, $(filter %.java,$(LOCAL_INTERMEDIATE_SOURCES)))
+
+## Java resources #########################################
+
+# Look for resource files in any specified directories.
+# Non-java and non-doc files will be picked up as resources
+# and included in the output jar file.
+java_resource_file_groups :=
+
+LOCAL_JAVA_RESOURCE_DIRS := $(strip $(LOCAL_JAVA_RESOURCE_DIRS))
+ifneq ($(LOCAL_JAVA_RESOURCE_DIRS),)
+ # This makes a list of words like
+ # <dir1>::<file1>:<file2> <dir2>::<file1> <dir3>:
+ # where each of the files is relative to the directory it's grouped with.
+ # Directories that don't contain any resource files will result in groups
+ # that end with a colon, and they are stripped out in the next step.
+ java_resource_file_groups += \
+ $(foreach dir,$(LOCAL_JAVA_RESOURCE_DIRS), \
+ $(subst $(space),:,$(strip \
+ $(TOP_DIR)$(LOCAL_PATH)/$(dir): \
+ $(patsubst ./%,%,$(shell cd $(TOP_DIR)$(LOCAL_PATH)/$(dir) && \
+ find . \
+ -type d -a -name ".svn" -prune -o \
+ -type f \
+ -a \! -name "*.java" \
+ -a \! -name "package.html" \
+ -a \! -name "overview.html" \
+ -a \! -name ".*.swp" \
+ -a \! -name ".DS_Store" \
+ -a \! -name "*~" \
+ -print \
+ )) \
+ )) \
+ )
+ java_resource_file_groups := $(filter-out %:,$(java_resource_file_groups))
+endif # LOCAL_JAVA_RESOURCE_DIRS
+
+LOCAL_JAVA_RESOURCE_FILES := $(strip $(LOCAL_JAVA_RESOURCE_FILES))
+ifneq ($(LOCAL_JAVA_RESOURCE_FILES),)
+ java_resource_file_groups += \
+ $(foreach f,$(LOCAL_JAVA_RESOURCE_FILES), \
+ $(patsubst %/,%,$(dir $(f)))::$(notdir $(f)) \
+ )
+endif # LOCAL_JAVA_RESOURCE_FILES
+
+ifdef java_resource_file_groups
+ # The full paths to all resources, used for dependencies.
+ java_resource_sources := \
+ $(foreach group,$(java_resource_file_groups), \
+ $(addprefix $(word 1,$(subst :,$(space),$(group)))/, \
+ $(wordlist 2,9999,$(subst :,$(space),$(group))) \
+ ) \
+ )
+ # The arguments to jar that will include these files in a jar file.
+ extra_jar_args := \
+ $(foreach group,$(java_resource_file_groups), \
+ $(addprefix -C $(word 1,$(subst :,$(space),$(group))) , \
+ $(wordlist 2,9999,$(subst :,$(space),$(group))) \
+ ) \
+ )
+ java_resource_file_groups :=
+else
+ java_resource_sources :=
+ extra_jar_args :=
+endif # java_resource_file_groups
+
+## PRIVATE java vars ######################################
+
+ifneq ($(strip $(all_java_sources)$(all_res_assets)),)
+
+full_static_java_libs := \
+ $(foreach lib,$(LOCAL_STATIC_JAVA_LIBRARIES), \
+ $(call intermediates-dir-for, \
+ JAVA_LIBRARIES,$(lib),$(LOCAL_IS_HOST_MODULE))/javalib.jar)
+
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_INSTALL_DIR := $(dir $(LOCAL_INSTALLED_MODULE))
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_INTERMEDIATES_DIR := $(intermediates)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CLASS_INTERMEDIATES_DIR := $(intermediates)/classes
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_SOURCE_INTERMEDIATES_DIR := $(intermediates)/src
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JAVA_SOURCES := $(all_java_sources)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JAVA_OBJECTS := $(patsubst %.java,%.class,$(LOCAL_SRC_FILES))
+ifeq ($(my_prefix),TARGET_)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH := -bootclasspath $(call java-lib-files,core)
+endif
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_RESOURCE_DIR := $(LOCAL_RESOURCE_DIR)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_EXTRA_JAR_ARGS := $(extra_jar_args)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ASSET_DIR := $(LOCAL_ASSET_DIR)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_STATIC_JAVA_LIBRARIES := $(full_static_java_libs)
+
+# full_java_libs: The list of files that should be used as the classpath.
+# Using this list as a dependency list WILL NOT WORK.
+# full_java_lib_deps: Should be specified as a prerequisite of this module
+# to guarantee that the files in full_java_libs will
+# be up-to-date.
+ifdef LOCAL_IS_HOST_MODULE
+# TODO: make prebuilt java libraries use the same
+# intermediates path pattern as target java libraries.
+full_java_libs := $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/,$(addsuffix $(COMMON_JAVA_PACKAGE_SUFFIX),$(LOCAL_JAVA_LIBRARIES)))
+full_java_lib_deps := $(full_java_libs)
+else
+full_java_libs := $(call java-lib-files,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
+full_java_lib_deps := $(call java-lib-deps,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
+endif
+full_java_libs += $(full_static_java_libs) $(LOCAL_CLASSPATH)
+full_java_lib_deps += $(full_static_java_libs) $(LOCAL_CLASSPATH)
+
+# This is set by packages that contain instrumentation, allowing them to
+# link against the package they are instrumenting. Currently only one such
+# package is allowed.
+LOCAL_INSTRUMENTATION_FOR := $(strip $(LOCAL_INSTRUMENTATION_FOR))
+ifdef LOCAL_INSTRUMENTATION_FOR
+ ifneq ($(words $(LOCAL_INSTRUMENTATION_FOR)),1)
+ $(error \
+ $(LOCAL_PATH): Multiple LOCAL_INSTRUMENTATION_FOR members defined)
+ endif
+
+ link_instr_intermediates_dir := $(call intermediates-dir-for, \
+ APPS,$(LOCAL_INSTRUMENTATION_FOR))
+ link_instr_intermediates_dir.COMMON := $(call intermediates-dir-for, \
+ APPS,$(LOCAL_INSTRUMENTATION_FOR),,COMMON)
+
+ full_java_libs += $(link_instr_intermediates_dir.COMMON)/classes.jar
+
+ # We can't depend on the .jar file, so we depend on something that
+ # depends on the jar file; the final built package file.
+ full_java_lib_deps += $(link_instr_intermediates_dir)/package.apk
+endif
+
+ifneq ($(strip $(LOCAL_JAR_MANIFEST)),)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JAR_MANIFEST := $(LOCAL_PATH)/$(LOCAL_JAR_MANIFEST)
+else
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JAR_MANIFEST :=
+endif
+
+endif
+
+
+###########################################################
+## make clean- targets
+###########################################################
+cleantarget := clean-$(LOCAL_MODULE)
+$(cleantarget) : PRIVATE_MODULE := $(LOCAL_MODULE)
+$(cleantarget) : PRIVATE_CLEAN_FILES := \
+ $(PRIVATE_CLEAN_FILES) \
+ $(LOCAL_BUILT_MODULE) \
+ $(LOCAL_INSTALLED_MODULE) \
+ $(intermediates)
+$(cleantarget)::
+ @echo "Clean: $(PRIVATE_MODULE)"
+ $(hide) rm -rf $(PRIVATE_CLEAN_FILES)
+
+###########################################################
+## Common definitions for module.
+###########################################################
+
+# Propagate local configuration options to this target.
+$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_PATH:=$(LOCAL_PATH)
+$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_POST_PROCESS_COMMAND:= $(LOCAL_POST_PROCESS_COMMAND)
+$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_AAPT_FLAGS:= $(LOCAL_AAPT_FLAGS)
+$(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_IS_HOST_MODULE := $(LOCAL_IS_HOST_MODULE)
+$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_HOST:= $(my_host)
+
+# Tell the module and all of its sub-modules who it is.
+$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_MODULE:= $(LOCAL_MODULE)
+
+# Provide a short-hand for building this module.
+# We name both BUILT and INSTALLED in case
+# LOCAL_UNINSTALLABLE_MODULE is set.
+.PHONY: $(LOCAL_MODULE)
+$(LOCAL_MODULE): $(LOCAL_BUILT_MODULE) $(LOCAL_INSTALLED_MODULE)
+
+###########################################################
+## Module installation rule
+###########################################################
+
+# Some hosts do not have ACP; override the LOCAL version if that's the case.
+ifneq ($(strip $(HOST_ACP_UNAVAILABLE)),)
+ LOCAL_ACP_UNAVAILABLE := $(strip $(HOST_ACP_UNAVAILABLE))
+endif
+
+ifndef LOCAL_UNINSTALLABLE_MODULE
+ # Define a copy rule to install the module.
+ # acp and libraries that it uses can't use acp for
+ # installation; hence, LOCAL_ACP_UNAVAILABLE.
+ifneq ($(LOCAL_ACP_UNAVAILABLE),true)
+$(LOCAL_INSTALLED_MODULE): $(LOCAL_BUILT_MODULE) | $(ACP)
+ @echo "Install: $@"
+ $(copy-file-to-target)
+else
+$(LOCAL_INSTALLED_MODULE): $(LOCAL_BUILT_MODULE)
+ @echo "Install: $@"
+ $(copy-file-to-target-with-cp)
+endif
+
+endif # !LOCAL_UNINSTALLABLE_MODULE
+
+###########################################################
+## Register with ALL_MODULES
+###########################################################
+
+ALL_MODULES += $(LOCAL_MODULE)
+
+# Don't use += on subvars, or else they'll end up being
+# recursively expanded.
+ALL_MODULES.$(LOCAL_MODULE).PATH := \
+ $(ALL_MODULES.$(LOCAL_MODULE).PATH) $(LOCAL_PATH)
+ALL_MODULES.$(LOCAL_MODULE).TAGS := \
+ $(ALL_MODULES.$(LOCAL_MODULE).TAGS) $(LOCAL_MODULE_TAGS)
+ALL_MODULES.$(LOCAL_MODULE).BUILT := \
+ $(ALL_MODULES.$(LOCAL_MODULE).BUILT) $(LOCAL_BUILT_MODULE)
+ALL_MODULES.$(LOCAL_MODULE).INSTALLED := \
+ $(ALL_MODULES.$(LOCAL_MODULE).INSTALLED) $(LOCAL_INSTALLED_MODULE)
+ALL_MODULES.$(LOCAL_MODULE).REQUIRED := \
+ $(ALL_MODULES.$(LOCAL_MODULE).REQUIRED) $(LOCAL_REQUIRED_MODULES)
+
+###########################################################
+## Take care of LOCAL_MODULE_TAGS
+###########################################################
+
+# Keep track of all the tags we've seen.
+ALL_MODULE_TAGS := $(sort $(ALL_MODULE_TAGS) $(LOCAL_MODULE_TAGS))
+
+# Add this module to the tag list of each specified tag.
+# Don't use "+=". If the variable hasn't been set with ":=",
+# it will default to recursive expansion.
+$(foreach tag,$(LOCAL_MODULE_TAGS),\
+ $(eval ALL_MODULE_TAGS.$(tag) := \
+ $(ALL_MODULE_TAGS.$(tag)) \
+ $(LOCAL_INSTALLED_MODULE)))
+
+# Add this module name to the tag list of each specified tag.
+$(foreach tag,$(LOCAL_MODULE_TAGS),\
+ $(eval ALL_MODULE_NAME_TAGS.$(tag) += $(LOCAL_MODULE)))
+
+# Always build everything, but only install a subset.
+ALL_BUILT_MODULES += $(LOCAL_BUILT_MODULE)
+
+###########################################################
+## NOTICE files
+###########################################################
+
+include $(BUILD_SYSTEM)/notice_files.mk
+
+#:vi noexpandtab
diff --git a/core/binary.mk b/core/binary.mk
new file mode 100644
index 0000000..0f35d3f
--- /dev/null
+++ b/core/binary.mk
@@ -0,0 +1,403 @@
+###########################################################
+## Standard rules for building binary object files from
+## asm/c/cpp/yacc/lex source files.
+##
+## The list of object files is exported in $(all_objects).
+###########################################################
+
+#######################################
+include $(BUILD_SYSTEM)/base_rules.mk
+#######################################
+
+###########################################################
+## Define PRIVATE_ variables used by multiple module types
+###########################################################
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_NO_DEFAULT_COMPILER_FLAGS := \
+ $(strip $(LOCAL_NO_DEFAULT_COMPILER_FLAGS))
+
+ifeq ($(strip $(LOCAL_CC)),)
+ LOCAL_CC := $($(my_prefix)CC)
+endif
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CC := $(LOCAL_CC)
+
+ifeq ($(strip $(LOCAL_CXX)),)
+ LOCAL_CXX := $($(my_prefix)CXX)
+endif
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CXX := $(LOCAL_CXX)
+
+# TODO: support a mix of standard extensions so that this isn't necessary
+LOCAL_CPP_EXTENSION := $(strip $(LOCAL_CPP_EXTENSION))
+ifeq ($(LOCAL_CPP_EXTENSION),)
+ LOCAL_CPP_EXTENSION := .cpp
+endif
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CPP_EXTENSION := $(LOCAL_CPP_EXTENSION)
+
+# Certain modules like libdl have to have symbols resolved at runtime and blow
+# up if --no-undefined is passed to the linker.
+ifeq ($(strip $(LOCAL_NO_DEFAULT_COMPILER_FLAGS)),)
+ifeq ($(strip $(LOCAL_ALLOW_UNDEFINED_SYMBOLS)),)
+ LOCAL_LDFLAGS := $(LOCAL_LDFLAGS) $($(my_prefix)NO_UNDEFINED_LDFLAGS)
+endif
+endif
+
+###########################################################
+## Define arm-vs-thumb-mode flags.
+###########################################################
+LOCAL_ARM_MODE := $(strip $(LOCAL_ARM_MODE))
+arm_objects_mode := $(if $(LOCAL_ARM_MODE),$(LOCAL_ARM_MODE),arm)
+normal_objects_mode := $(if $(LOCAL_ARM_MODE),$(LOCAL_ARM_MODE),thumb)
+
+# Read the values from something like TARGET_arm_release_CFLAGS or
+# TARGET_thumb_debug_CFLAGS. HOST_(arm|thumb)_(release|debug)_CFLAGS
+# values aren't actually used (although they are usually empty).
+arm_objects_cflags := $($(my_prefix)$(arm_objects_mode)_$($(my_prefix)BUILD_TYPE)_CFLAGS)
+normal_objects_cflags := $($(my_prefix)$(normal_objects_mode)_$($(my_prefix)BUILD_TYPE)_CFLAGS)
+
+###########################################################
+## Define per-module debugging flags. Users can turn on
+## debugging for a particular module by setting DEBUG_MODULE_ModuleName
+## to a non-empty value in their environment or buildspec.mk,
+## and setting HOST_/TARGET_CUSTOM_DEBUG_CFLAGS to the
+## debug flags that they want to use.
+###########################################################
+ifdef DEBUG_MODULE_$(strip $(LOCAL_MODULE))
+ debug_cflags := $($(my_prefix)CUSTOM_DEBUG_CFLAGS)
+else
+ debug_cflags :=
+endif
+
+###########################################################
+## Stuff source generated from one-off tools
+###########################################################
+$(LOCAL_GENERATED_SOURCES): PRIVATE_MODULE := $(LOCAL_MODULE)
+
+ALL_GENERATED_SOURCES += $(LOCAL_GENERATED_SOURCES)
+
+
+###########################################################
+## YACC: Compile .y files to .cpp and the to .o.
+###########################################################
+
+yacc_sources := $(filter %.y,$(LOCAL_SRC_FILES))
+yacc_cpps := $(addprefix \
+ $(intermediates)/,$(yacc_sources:.y=$(LOCAL_CPP_EXTENSION)))
+yacc_headers := $(yacc_cpps:$(LOCAL_CPP_EXTENSION)=.h)
+yacc_objects := $(yacc_cpps:$(LOCAL_CPP_EXTENSION)=.o)
+
+ifneq ($(strip $(yacc_cpps)),)
+$(yacc_cpps): $(intermediates)/%$(LOCAL_CPP_EXTENSION): \
+ $(TOPDIR)$(LOCAL_PATH)/%.y \
+ $(lex_cpps) $(PRIVATE_ADDITIONAL_DEPENDENCIES)
+ $(call transform-y-to-cpp,$(PRIVATE_CPP_EXTENSION))
+$(yacc_headers): $(intermediates)/%.h: $(intermediates)/%$(LOCAL_CPP_EXTENSION)
+
+$(yacc_objects): PRIVATE_ARM_MODE := $(normal_objects_mode)
+$(yacc_objects): PRIVATE_ARM_CFLAGS := $(normal_objects_cflags)
+$(yacc_objects): $(intermediates)/%.o: $(intermediates)/%$(LOCAL_CPP_EXTENSION)
+ $(transform-$(PRIVATE_HOST)cpp-to-o)
+endif
+
+###########################################################
+## LEX: Compile .l files to .cpp and then to .o.
+###########################################################
+
+lex_sources := $(filter %.l,$(LOCAL_SRC_FILES))
+lex_cpps := $(addprefix \
+ $(intermediates)/,$(lex_sources:.l=$(LOCAL_CPP_EXTENSION)))
+lex_objects := $(lex_cpps:$(LOCAL_CPP_EXTENSION)=.o)
+
+ifneq ($(strip $(lex_cpps)),)
+$(lex_cpps): $(intermediates)/%$(LOCAL_CPP_EXTENSION): \
+ $(TOPDIR)$(LOCAL_PATH)/%.l
+ $(transform-l-to-cpp)
+
+$(lex_objects): PRIVATE_ARM_MODE := $(normal_objects_mode)
+$(lex_objects): PRIVATE_ARM_CFLAGS := $(normal_objects_cflags)
+$(lex_objects): $(intermediates)/%.o: \
+ $(intermediates)/%$(LOCAL_CPP_EXTENSION) \
+ $(PRIVATE_ADDITIONAL_DEPENDENCIES) \
+ $(yacc_headers)
+ $(transform-$(PRIVATE_HOST)cpp-to-o)
+endif
+
+###########################################################
+## C++: Compile .cpp files to .o.
+###########################################################
+
+# we also do this on host modules and sim builds, even though
+# it's not really arm, because there are files that are shared.
+cpp_arm_sources := $(patsubst %$(LOCAL_CPP_EXTENSION).arm,%$(LOCAL_CPP_EXTENSION),$(filter %$(LOCAL_CPP_EXTENSION).arm,$(LOCAL_SRC_FILES)))
+cpp_arm_objects := $(addprefix $(intermediates)/,$(cpp_arm_sources:$(LOCAL_CPP_EXTENSION)=.o))
+
+cpp_normal_sources := $(filter %$(LOCAL_CPP_EXTENSION),$(LOCAL_SRC_FILES))
+cpp_normal_objects := $(addprefix $(intermediates)/,$(cpp_normal_sources:$(LOCAL_CPP_EXTENSION)=.o))
+
+$(cpp_arm_objects): PRIVATE_ARM_MODE := $(arm_objects_mode)
+$(cpp_arm_objects): PRIVATE_ARM_CFLAGS := $(arm_objects_cflags)
+$(cpp_normal_objects): PRIVATE_ARM_MODE := $(normal_objects_mode)
+$(cpp_normal_objects): PRIVATE_ARM_CFLAGS := $(normal_objects_cflags)
+
+cpp_objects := $(cpp_arm_objects) $(cpp_normal_objects)
+
+ifneq ($(strip $(cpp_objects)),)
+$(cpp_objects): $(intermediates)/%.o: \
+ $(TOPDIR)$(LOCAL_PATH)/%$(LOCAL_CPP_EXTENSION) \
+ $(yacc_cpps) $(PRIVATE_ADDITIONAL_DEPENDENCIES)
+ $(transform-$(PRIVATE_HOST)cpp-to-o)
+-include $(cpp_objects:%.o=%.P)
+endif
+
+###########################################################
+## C++: Compile generated .cpp files to .o.
+###########################################################
+
+gen_cpp_sources := $(filter %$(LOCAL_CPP_EXTENSION),$(LOCAL_GENERATED_SOURCES))
+gen_cpp_objects := $(gen_cpp_sources:%$(LOCAL_CPP_EXTENSION)=%.o)
+
+ifneq ($(strip $(gen_cpp_objects)),)
+# Compile all generated files as thumb.
+# TODO: support compiling certain generated files as arm.
+$(gen_cpp_objects): PRIVATE_ARM_MODE := $(normal_objects_mode)
+$(gen_cpp_objects): PRIVATE_ARM_CFLAGS := $(normal_objects_cflags)
+$(gen_cpp_objects): $(intermediates)/%.o: $(intermediates)/%$(LOCAL_CPP_EXTENSION) $(yacc_cpps) $(PRIVATE_ADDITIONAL_DEPENDENCIES)
+ $(transform-$(PRIVATE_HOST)cpp-to-o)
+-include $(gen_cpp_objects:%.o=%.P)
+endif
+
+###########################################################
+## S: Compile generated .S and .s files to .o.
+###########################################################
+
+gen_S_sources := $(filter %.S,$(LOCAL_GENERATED_SOURCES))
+gen_S_objects := $(gen_S_sources:%.S=%.o)
+
+ifneq ($(strip $(gen_S_sources)),)
+$(gen_S_objects): $(intermediates)/%.o: $(intermediates)/%.S $(PRIVATE_ADDITIONAL_DEPENDENCIES)
+ $(transform-$(PRIVATE_HOST)s-to-o)
+-include $(gen_S_objects:%.o=%.P)
+endif
+
+gen_s_sources := $(filter %.s,$(LOCAL_GENERATED_SOURCES))
+gen_s_objects := $(gen_s_sources:%.s=%.o)
+
+ifneq ($(strip $(gen_s_objects)),)
+$(gen_s_objects): $(intermediates)/%.o: $(intermediates)/%.s $(PRIVATE_ADDITIONAL_DEPENDENCIES)
+ $(transform-$(PRIVATE_HOST)s-to-o-no-deps)
+-include $(gen_s_objects:%.o=%.P)
+endif
+
+gen_asm_objects := $(gen_S_objects) $(gen_s_objects)
+
+###########################################################
+## C: Compile .c files to .o.
+###########################################################
+
+c_arm_sources := $(patsubst %.c.arm,%.c,$(filter %.c.arm,$(LOCAL_SRC_FILES)))
+c_arm_objects := $(addprefix $(intermediates)/,$(c_arm_sources:.c=.o))
+
+c_normal_sources := $(filter %.c,$(LOCAL_SRC_FILES))
+c_normal_objects := $(addprefix $(intermediates)/,$(c_normal_sources:.c=.o))
+
+$(c_arm_objects): PRIVATE_ARM_MODE := $(arm_objects_mode)
+$(c_arm_objects): PRIVATE_ARM_CFLAGS := $(arm_objects_cflags)
+$(c_normal_objects): PRIVATE_ARM_MODE := $(normal_objects_mode)
+$(c_normal_objects): PRIVATE_ARM_CFLAGS := $(normal_objects_cflags)
+
+c_objects := $(c_arm_objects) $(c_normal_objects)
+
+ifneq ($(strip $(c_objects)),)
+$(c_objects): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.c $(yacc_cpps) $(PRIVATE_ADDITIONAL_DEPENDENCIES)
+ $(transform-$(PRIVATE_HOST)c-to-o)
+-include $(c_objects:%.o=%.P)
+endif
+
+###########################################################
+## AS: Compile .S files to .o.
+###########################################################
+
+asm_sources_S := $(filter %.S,$(LOCAL_SRC_FILES))
+asm_objects_S := $(addprefix $(intermediates)/,$(asm_sources_S:.S=.o))
+
+ifneq ($(strip $(asm_objects_S)),)
+$(asm_objects_S): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.S $(PRIVATE_ADDITIONAL_DEPENDENCIES)
+ $(transform-$(PRIVATE_HOST)s-to-o)
+-include $(asm_objects_S:%.o=%.P)
+endif
+
+asm_sources_s := $(filter %.s,$(LOCAL_SRC_FILES))
+asm_objects_s := $(addprefix $(intermediates)/,$(asm_sources_s:.s=.o))
+
+ifneq ($(strip $(asm_objects_s)),)
+$(asm_objects_s): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.s $(PRIVATE_ADDITIONAL_DEPENDENCIES)
+ $(transform-$(PRIVATE_HOST)s-to-o-no-deps)
+-include $(asm_objects_s:%.o=%.P)
+endif
+
+asm_objects := $(asm_objects_S) $(asm_objects_s)
+
+
+###########################################################
+## Common object handling.
+###########################################################
+
+# some rules depend on asm_objects being first. If your code depends on
+# being first, it's reasonable to require it to be assembly
+all_objects := \
+ $(asm_objects) \
+ $(cpp_objects) \
+ $(gen_cpp_objects) \
+ $(gen_asm_objects) \
+ $(c_objects) \
+ $(yacc_objects) \
+ $(lex_objects) \
+ $(addprefix $(TOPDIR)$(LOCAL_PATH)/,$(LOCAL_PREBUILT_OBJ_FILES))
+
+LOCAL_C_INCLUDES += $(TOPDIR)$(LOCAL_PATH) $(intermediates) $(base_intermediates)
+
+$(all_objects) : | $(LOCAL_GENERATED_SOURCES)
+ALL_C_CPP_ETC_OBJECTS += $(all_objects)
+
+###########################################################
+## Copy headers to the install tree
+###########################################################
+include $(BUILD_COPY_HEADERS)
+
+###########################################################
+# Standard library handling.
+#
+# On the target, we compile with -nostdlib, so we must add in the
+# default system shared libraries, unless they have requested not
+# to by supplying a LOCAL_SYSTEM_SHARED_LIBRARIES value. One would
+# supply that, for example, when building libc itself.
+###########################################################
+ifndef LOCAL_IS_HOST_MODULE
+ ifeq ($(LOCAL_SYSTEM_SHARED_LIBRARIES),none)
+ LOCAL_SHARED_LIBRARIES += $($(my_prefix)DEFAULT_SYSTEM_SHARED_LIBRARIES)
+ else
+ LOCAL_SHARED_LIBRARIES += $(LOCAL_SYSTEM_SHARED_LIBRARIES)
+ endif
+endif
+
+# Logging used to be part of libcutils (target) and libutils (sim);
+# hack modules that use those other libs to also include liblog.
+# All of this complexity is to make sure that liblog only appears
+# once, and appears just before libcutils or libutils on the link
+# line.
+# TODO: remove this hack and change all modules to use liblog
+# when necessary.
+define insert-liblog
+ $(if $(filter liblog,$(1)),$(1), \
+ $(if $(filter libcutils,$(1)), \
+ $(patsubst libcutils,liblog libcutils,$(1)) \
+ , \
+ $(patsubst libutils,liblog libutils,$(1)) \
+ ) \
+ )
+endef
+ifneq (,$(filter libcutils libutils,$(LOCAL_SHARED_LIBRARIES)))
+ LOCAL_SHARED_LIBRARIES := $(call insert-liblog,$(LOCAL_SHARED_LIBRARIES))
+endif
+ifneq (,$(filter libcutils libutils,$(LOCAL_STATIC_LIBRARIES)))
+ LOCAL_STATIC_LIBRARIES := $(call insert-liblog,$(LOCAL_STATIC_LIBRARIES))
+endif
+ifneq (,$(filter libcutils libutils,$(LOCAL_WHOLE_STATIC_LIBRARIES)))
+ LOCAL_WHOLE_STATIC_LIBRARIES := $(call insert-liblog,$(LOCAL_WHOLE_STATIC_LIBRARIES))
+endif
+
+###########################################################
+# The list of libraries that this module will link against are in
+# these variables. Each is a list of bare module names like "libc libm".
+#
+# LOCAL_SHARED_LIBRARIES
+# LOCAL_STATIC_LIBRARIES
+# LOCAL_WHOLE_STATIC_LIBRARIES
+#
+# We need to convert the bare names into the dependencies that
+# we'll use for LOCAL_BUILT_MODULE and LOCAL_INSTALLED_MODULE.
+# LOCAL_BUILT_MODULE should depend on the BUILT versions of the
+# libraries, so that simply building this module doesn't force
+# an install of a library. Similarly, LOCAL_INSTALLED_MODULE
+# should depend on the INSTALLED versions of the libraries so
+# that they get installed when this module does.
+###########################################################
+# NOTE:
+# WHOLE_STATIC_LIBRARIES are libraries that are pulled into the
+# module without leaving anything out, which is useful for turning
+# a collection of .a files into a .so file. Linking against a
+# normal STATIC_LIBRARY will only pull in code/symbols that are
+# referenced by the module. (see gcc/ld's --whole-archive option)
+###########################################################
+
+# Get the list of BUILT libraries, which are under
+# various intermediates directories.
+so_suffix := $($(my_prefix)SHLIB_SUFFIX)
+a_suffix := $($(my_prefix)STATIC_LIB_SUFFIX)
+
+built_shared_libraries := \
+ $(addprefix $($(my_prefix)OUT_INTERMEDIATE_LIBRARIES)/, \
+ $(addsuffix $(so_suffix), \
+ $(LOCAL_SHARED_LIBRARIES)))
+
+built_static_libraries := \
+ $(foreach lib,$(LOCAL_STATIC_LIBRARIES), \
+ $(call intermediates-dir-for, \
+ STATIC_LIBRARIES,$(lib),$(LOCAL_IS_HOST_MODULE))/$(lib)$(a_suffix))
+
+built_whole_libraries := \
+ $(foreach lib,$(LOCAL_WHOLE_STATIC_LIBRARIES), \
+ $(call intermediates-dir-for, \
+ STATIC_LIBRARIES,$(lib),$(LOCAL_IS_HOST_MODULE))/$(lib)$(a_suffix))
+
+# Get the list of INSTALLED libraries. Strip off the various
+# intermediates directories and point to the common lib dirs.
+installed_shared_libraries := \
+ $(addprefix $($(my_prefix)OUT_SHARED_LIBRARIES)/, \
+ $(notdir $(built_shared_libraries)))
+
+# We don't care about installed static libraries, since the
+# libraries have already been linked into the module at that point.
+# We do, however, care about the NOTICE files for any static
+# libraries that we use. (see notice_files.make)
+
+installed_static_library_notice_file_targets := \
+ $(foreach lib,$(LOCAL_STATIC_LIBRARIES) $(LOCAL_WHOLE_STATIC_LIBRARIES), \
+ NOTICE-$(if $(LOCAL_IS_HOST_MODULE),HOST,TARGET)-STATIC_LIBRARIES-$(lib))
+
+###########################################################
+# Rule-specific variable definitions
+###########################################################
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_YACCFLAGS := $(LOCAL_YACCFLAGS)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ASFLAGS := $(LOCAL_ASFLAGS)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CFLAGS := $(LOCAL_CFLAGS)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CPPFLAGS := $(LOCAL_CPPFLAGS)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_DEBUG_CFLAGS := $(debug_cflags)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_C_INCLUDES := $(LOCAL_C_INCLUDES)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_LDFLAGS := $(LOCAL_LDFLAGS)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_LDLIBS := $(LOCAL_LDLIBS)
+
+# this is really the way to get the files onto the command line instead
+# of using $^, because then LOCAL_ADDITIONAL_DEPENDENCIES doesn't work
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ALL_SHARED_LIBRARIES := $(built_shared_libraries)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ALL_STATIC_LIBRARIES := $(built_static_libraries)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ALL_WHOLE_STATIC_LIBRARIES := $(built_whole_libraries)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ALL_OBJECTS := $(all_objects)
+
+###########################################################
+# Define library dependencies.
+###########################################################
+# all_libraries is used for the dependencies on LOCAL_BUILT_MODULE.
+all_libraries := \
+ $(built_shared_libraries) \
+ $(built_static_libraries) \
+ $(built_whole_libraries)
+
+# Make LOCAL_INSTALLED_MODULE depend on the installed versions of the
+# libraries so they get installed along with it. We don't need to
+# rebuild it when installing it, though, so this can be an order-only
+# dependency.
+$(LOCAL_INSTALLED_MODULE): | $(installed_shared_libraries)
+
+# Also depend on the notice files for any static libraries that
+# are linked into this module. This will force them to be installed
+# when this module is.
+$(LOCAL_INSTALLED_MODULE): | $(installed_static_library_notice_file_targets)
diff --git a/core/build_id.mk b/core/build_id.mk
new file mode 100644
index 0000000..cb18bc4
--- /dev/null
+++ b/core/build_id.mk
@@ -0,0 +1,32 @@
+#
+# 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.
+#
+
+#
+# Defines branch-specific values.
+#
+
+# BUILD_ID is usually used to specify the branch name
+# (like "MAIN") or a branch name and a release candidate
+# (like "TC1-RC5"). It must be a single word, and is
+# capitalized by convention.
+#
+BUILD_ID := CUPCAKE
+
+# DISPLAY_BUILD_NUMBER should only be set for development branches,
+# If set, the BUILD_NUMBER (cl) is appended to the BUILD_ID for
+# a more descriptive BUILD_ID_DISPLAY, otherwise BUILD_ID_DISPLAY
+# is the same as BUILD_ID
+DISPLAY_BUILD_NUMBER := true
diff --git a/core/checktree b/core/checktree
new file mode 100755
index 0000000..b0b9cfa
--- /dev/null
+++ b/core/checktree
@@ -0,0 +1,113 @@
+#!/usr/bin/python -E
+
+import sys, os, re
+
+excludes = [r'.*?/\.obj.*?',
+ r'.*?~',
+ r'.*?\/.DS_Store',
+ r'.*?\/.gdb_history',
+ r'.*?\/buildspec.mk',
+ r'.*?/\..*?\.swp',
+ r'.*?/out/.*?',
+ r'.*?/install/.*?']
+
+excludes_compiled = map(re.compile, excludes)
+
+def filter_excludes(str):
+ for e in excludes_compiled:
+ if e.match(str):
+ return False
+ return True
+
+def split_perforce_parts(s):
+ spaces = ((s.count(" ") + 1) / 3) * 2
+ pos = 0
+ while spaces > 0:
+ pos = s.find(" ", pos) + 1
+ spaces = spaces - 1
+ return s[pos:]
+
+def quotate(s):
+ return '"' + s + '"'
+
+class PerforceError(Exception):
+ def __init__(self,value):
+ self.value = value
+ def __str__(self):
+ return repr(self.value)
+
+
+def run(command, regex, filt):
+ def matchit(s):
+ m = regex_compiled.match(s)
+ if m:
+ return m.group(1)
+ else:
+ return ""
+ def filterit(s):
+ if filt_compiled.match(s):
+ return True
+ else:
+ return False
+
+ fd = os.popen(command);
+ lines = fd.readlines()
+ status = fd.close()
+ if status:
+ raise PerforceError("error calling " + command)
+
+ regex_compiled = re.compile(regex)
+ filt_compiled = re.compile(filt)
+
+ if len(lines) >= 1:
+ lines = filter(filterit, lines)
+ if len(lines) >= 1:
+ return map(matchit, lines)
+ return None
+
+try:
+ if len(sys.argv) == 1:
+ do_exclude = True
+ elif len(sys.argv) == 2 and sys.argv[1] == "-a":
+ do_exclude = False
+ else:
+ print "usage: checktree [-a]"
+ print " -a don't filter common crud in the tree"
+ sys.exit(1)
+
+ have = run("p4 have ...", r'[^#]+#[0-9]+ - (.*)', r'.*')
+
+ cwd = os.getcwd()
+ files = run("find . -not -type d", r'.(.*)', r'.*')
+ files = map(lambda s: cwd+s, files)
+
+ added_depot_path = run("p4 opened ...", r'([^#]+)#.*', r'.*?#[0-9]+ - add .*');
+ added = []
+ if added_depot_path:
+ added_depot_path = map(quotate, added_depot_path)
+
+ where = "p4 where " + " ".join(added_depot_path)
+ added = run(where, r'(.*)', r'.*')
+ added = map(split_perforce_parts, added)
+
+ extras = []
+
+ # Python 2.3 -- still default on Mac OS X -- does not have set()
+ # Make dict's here to support the "in" operations below
+ have = dict().fromkeys(have, 1)
+ added = dict().fromkeys(added, 1)
+
+ for file in files:
+ if not file in have:
+ if not file in added:
+ extras.append(file)
+
+ if do_exclude:
+ extras = filter(filter_excludes, extras)
+
+ for s in extras:
+ print s.replace(" ", "\\ ")
+
+except PerforceError, e:
+ sys.exit(2)
+
diff --git a/core/cleanbuild.mk b/core/cleanbuild.mk
new file mode 100644
index 0000000..50b56f9
--- /dev/null
+++ b/core/cleanbuild.mk
@@ -0,0 +1,204 @@
+# Copyright (C) 2007 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.
+#
+
+INTERNAL_CLEAN_STEPS :=
+
+# Builds up a list of clean steps. Creates a unique
+# id for each step by taking INTERNAL_CLEAN_BUILD_VERSION
+# and appending an increasing number of '@' characters.
+#
+# $(1): shell command to run
+define _add-clean-step
+ $(if $(strip $(INTERNAL_CLEAN_BUILD_VERSION)),, \
+ $(error INTERNAL_CLEAN_BUILD_VERSION not set))
+ $(eval _acs_id := $(strip $(lastword $(INTERNAL_CLEAN_STEPS))))
+ $(if $(_acs_id),,$(eval _acs_id := $(INTERNAL_CLEAN_BUILD_VERSION)))
+ $(eval _acs_id := $(_acs_id)@)
+ $(eval INTERNAL_CLEAN_STEPS += $(_acs_id))
+ $(eval INTERNAL_CLEAN_STEP.$(_acs_id) := $(1))
+ $(eval _acs_id :=)
+endef
+define add-clean-step
+$(if $(call _add-clean-step,$(1)),)
+endef
+
+# Defines INTERNAL_CLEAN_BUILD_VERSION and the individual clean steps.
+# cleanspec.mk is outside of the core directory so that more people
+# can have permission to touch it.
+include build/cleanspec.mk
+INTERNAL_CLEAN_BUILD_VERSION := $(strip $(INTERNAL_CLEAN_BUILD_VERSION))
+
+# If the clean_steps.mk file is missing (usually after a clean build)
+# then we won't do anything.
+CURRENT_CLEAN_BUILD_VERSION := $(INTERNAL_CLEAN_BUILD_VERSION)
+CURRENT_CLEAN_STEPS := $(INTERNAL_CLEAN_STEPS)
+
+# Read the current state from the file, if present.
+# Will set CURRENT_CLEAN_BUILD_VERSION and CURRENT_CLEAN_STEPS.
+#
+clean_steps_file := $(PRODUCT_OUT)/clean_steps.mk
+-include $(clean_steps_file)
+
+ifneq ($(CURRENT_CLEAN_BUILD_VERSION),$(INTERNAL_CLEAN_BUILD_VERSION))
+ # The major clean version is out-of-date. Do a full clean, and
+ # don't even bother with the clean steps.
+ $(info *** A clean build is required because of a recent change.)
+ $(shell rm -rf $(OUT_DIR))
+ $(info *** Done with the cleaning, now starting the real build.)
+else
+ # The major clean version is correct. Find the list of clean steps
+ # that we need to execute to get up-to-date.
+ steps := \
+ $(filter-out $(CURRENT_CLEAN_STEPS),$(INTERNAL_CLEAN_STEPS))
+ $(foreach step,$(steps), \
+ $(info Clean step: $(INTERNAL_CLEAN_STEP.$(step))) \
+ $(shell $(INTERNAL_CLEAN_STEP.$(step))) \
+ )
+ steps :=
+endif
+CURRENT_CLEAN_BUILD_VERSION :=
+CURRENT_CLEAN_STEPS :=
+
+# Write the new state to the file.
+#
+$(shell \
+ mkdir -p $(dir $(clean_steps_file)) && \
+ echo "CURRENT_CLEAN_BUILD_VERSION := $(INTERNAL_CLEAN_BUILD_VERSION)" > \
+ $(clean_steps_file) ;\
+ echo "CURRENT_CLEAN_STEPS := $(INTERNAL_CLEAN_STEPS)" >> \
+ $(clean_steps_file) \
+ )
+
+clean_steps_file :=
+INTERNAL_CLEAN_STEPS :=
+INTERNAL_CLEAN_BUILD_VERSION :=
+
+
+# Since products and build variants (unfortunately) share the same
+# PRODUCT_OUT staging directory, things can get out of sync if different
+# build configurations are built in the same tree. The following logic
+# will notice when the configuration has changed and remove the files
+# necessary to keep things consistent.
+
+previous_build_config_file := $(PRODUCT_OUT)/previous_build_config.mk
+
+# TODO: this special case for the sdk is only necessary while "sdk"
+# is a valid make target. Eventually, it will just be a product, at
+# which point TARGET_PRODUCT will handle it and we can avoid this check
+# of MAKECMDGOALS. The "addprefix" is just to keep things pretty.
+ifneq ($(TARGET_PRODUCT),sdk)
+ building_sdk := $(addprefix -,$(filter sdk,$(MAKECMDGOALS)))
+else
+ # Don't bother with this extra part when explicitly building the sdk product.
+ building_sdk :=
+endif
+
+# A change in the list of locales warrants an installclean, too.
+locale_list := $(subst $(space),$(comma),$(strip $(PRODUCT_LOCALES)))
+
+current_build_config := \
+ $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)$(building_sdk)-{$(locale_list)}
+building_sdk :=
+locale_list :=
+force_installclean := false
+
+# Read the current state from the file, if present.
+# Will set PREVIOUS_BUILD_CONFIG.
+#
+PREVIOUS_BUILD_CONFIG :=
+-include $(previous_build_config_file)
+PREVIOUS_BUILD_CONFIG := $(strip $(PREVIOUS_BUILD_CONFIG))
+ifdef PREVIOUS_BUILD_CONFIG
+ ifneq "$(current_build_config)" "$(PREVIOUS_BUILD_CONFIG)"
+ $(info *** Build configuration changed: "$(PREVIOUS_BUILD_CONFIG)" -> "$(current_build_config)")
+ ifneq ($(DISABLE_AUTO_INSTALLCLEAN),true)
+ force_installclean := true
+ else
+ $(info DISABLE_AUTO_INSTALLCLEAN is set; skipping auto-clean. Your tree may be in an inconsistent state.)
+ endif
+ endif
+endif # else, this is the first build, so no need to clean.
+PREVIOUS_BUILD_CONFIG :=
+
+# Write the new state to the file.
+#
+$(shell \
+ mkdir -p $(dir $(previous_build_config_file)) && \
+ echo "PREVIOUS_BUILD_CONFIG := $(current_build_config)" > \
+ $(previous_build_config_file) \
+ )
+previous_build_config_file :=
+current_build_config :=
+
+#
+# installclean logic
+#
+
+# The files/dirs to delete during an installclean. This includes the
+# non-common APPS directory, which may contain the wrong resources.
+# Use "./" in front of the paths to avoid accidentally deleting random
+# parts of the filesystem if any of the *_OUT vars resolve to blank.
+#
+# Deletes all of the files that change between different build types,
+# like "make user" vs. "make sdk". This lets you work with different
+# build types without having to do a full clean each time. E.g.:
+#
+# $ make -j8 all
+# $ make installclean
+# $ make -j8 user
+# $ make installclean
+# $ make -j8 sdk
+#
+installclean_files := \
+ ./$(HOST_OUT)/obj/NOTICE_FILES \
+ ./$(HOST_OUT)/sdk \
+ ./$(PRODUCT_OUT)/*.img \
+ ./$(PRODUCT_OUT)/*.txt \
+ ./$(PRODUCT_OUT)/*.xlb \
+ ./$(PRODUCT_OUT)/*.zip \
+ ./$(PRODUCT_OUT)/data \
+ ./$(PRODUCT_OUT)/obj/APPS \
+ ./$(PRODUCT_OUT)/obj/NOTICE_FILES \
+ ./$(PRODUCT_OUT)/obj/PACKAGING \
+ ./$(PRODUCT_OUT)/recovery \
+ ./$(PRODUCT_OUT)/root \
+ ./$(PRODUCT_OUT)/system
+
+# The files/dirs to delete during a dataclean, which removes any files
+# in the staging and emulator data partitions.
+dataclean_files := \
+ ./$(PRODUCT_OUT)/data/* \
+ ./$(PRODUCT_OUT)/data-qemu/* \
+ ./$(PRODUCT_OUT)/userdata-qemu.img
+
+# Define the rules for commandline invocation.
+.PHONY: dataclean
+dataclean: FILES := $(dataclean_files)
+dataclean:
+ $(hide) rm -rf $(FILES)
+ @echo "Deleted emulator userdata images."
+
+.PHONY: installclean
+installclean: FILES := $(installclean_files)
+installclean: dataclean
+ $(hide) rm -rf $(FILES)
+ @echo "Deleted images and staging directories."
+
+ifeq "$(force_installclean)" "true"
+ $(info *** Forcing "make installclean"...)
+ $(shell rm -rf $(dataclean_files) $(installclean_files))
+ $(info *** Done with the cleaning, now starting the real build.)
+endif
+force_installclean :=
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
new file mode 100644
index 0000000..f090507
--- /dev/null
+++ b/core/clear_vars.mk
@@ -0,0 +1,91 @@
+###########################################################
+## Clear out values of all variables used by rule templates.
+###########################################################
+
+LOCAL_MODULE:=
+LOCAL_MODULE_PATH:=
+LOCAL_MODULE_STEM:=
+LOCAL_BUILT_MODULE:=
+LOCAL_BUILT_MODULE_STEM:=
+OVERRIDE_BUILT_MODULE_PATH:=
+LOCAL_INSTALLED_MODULE:=
+LOCAL_UNINSTALLABLE_MODULE:=
+LOCAL_INTERMEDIATE_TARGETS:=
+LOCAL_UNSTRIPPED_PATH:=
+LOCAL_MODULE_CLASS:=
+LOCAL_MODULE_SUFFIX:=
+LOCAL_PACKAGE_NAME:=
+LOCAL_OVERRIDES_PACKAGES:=
+LOCAL_EXPORT_PACKAGE_RESOURCES:=
+LOCAL_REQUIRED_MODULES:=
+LOCAL_ACP_UNAVAILABLE:=
+LOCAL_MODULE_TAGS:=
+LOCAL_SRC_FILES:=
+LOCAL_PREBUILT_OBJ_FILES:=
+LOCAL_STATIC_JAVA_LIBRARIES:=
+LOCAL_STATIC_LIBRARIES:=
+LOCAL_WHOLE_STATIC_LIBRARIES:=
+LOCAL_SHARED_LIBRARIES:=
+LOCAL_IS_HOST_MODULE:=
+LOCAL_CC:=
+LOCAL_CXX:=
+LOCAL_CPP_EXTENSION:=
+LOCAL_NO_DEFAULT_COMPILER_FLAGS:=
+LOCAL_ARM_MODE:=
+LOCAL_YACCFLAGS:=
+LOCAL_ASFLAGS:=
+LOCAL_CFLAGS:=
+LOCAL_CPPFLAGS:=
+LOCAL_C_INCLUDES:=
+LOCAL_LDFLAGS:=
+LOCAL_LDLIBS:=
+LOCAL_AAPT_FLAGS:=
+LOCAL_SYSTEM_SHARED_LIBRARIES:=none
+LOCAL_PREBUILT_LIBS:=
+LOCAL_PREBUILT_EXECUTABLES:=
+LOCAL_PREBUILT_JAVA_LIBRARIES:=
+LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES:=
+LOCAL_INTERMEDIATE_SOURCES:=
+LOCAL_JAVA_LIBRARIES:=
+LOCAL_NO_STANDARD_LIBRARIES:=
+LOCAL_CLASSPATH:=
+LOCAL_DROIDDOC_SOURCE_PATH:=
+LOCAL_DROIDDOC_TEMPLATE_DIR:=
+LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=
+LOCAL_DROIDDOC_ASSET_DIR:=
+LOCAL_DROIDDOC_CUSTOM_ASSET_DIR:=
+LOCAL_DROIDDOC_OPTIONS:=
+LOCAL_DROIDDOC_HTML_DIR:=
+LOCAL_ASSET_FILES:=
+LOCAL_ASSET_DIR:=
+LOCAL_RESOURCE_DIR:=
+LOCAL_JAVA_RESOURCE_DIRS:=
+LOCAL_JAVA_RESOURCE_FILES:=
+LOCAL_GENERATED_SOURCES:=
+LOCAL_COPY_HEADERS_TO:=
+LOCAL_COPY_HEADERS:=
+LOCAL_FORCE_STATIC_EXECUTABLE:=
+LOCAL_ADDITIONAL_DEPENDENCIES:=
+LOCAL_PRELINK_MODULE:=
+LOCAL_COMPRESS_MODULE_SYMBOLS:=
+LOCAL_STRIP_MODULE:=
+LOCAL_POST_PROCESS_COMMAND:=true
+LOCAL_JNI_SHARED_LIBRARIES:=
+LOCAL_JAR_MANIFEST:=
+LOCAL_INSTRUMENTATION_FOR:=
+LOCAL_INSTRUMENTATION_FOR_PACKAGE_NAME:=
+LOCAL_AIDL_INCLUDES:=
+LOCAL_JARJAR_RULES:=
+LOCAL_ADDITIONAL_JAVA_DIR:=
+LOCAL_ALLOW_UNDEFINED_SYMBOLS:=
+LOCAL_DX_FLAGS:=
+LOCAL_CERTIFICATE:=
+LOCAL_SDK_VERSION:=
+LOCAL_NO_EMMA_INSTRUMENT:=
+LOCAL_NO_EMMA_COMPILE:=
+
+# Trim MAKEFILE_LIST so that $(call my-dir) doesn't need to
+# iterate over thousands of entries every time.
+# Leave the current makefile to make sure we don't break anything
+# that expects to be able to find the name of the current makefile.
+MAKEFILE_LIST := $(lastword $(MAKEFILE_LIST))
diff --git a/core/combo/darwin-x86.mk b/core/combo/darwin-x86.mk
new file mode 100644
index 0000000..2150960
--- /dev/null
+++ b/core/combo/darwin-x86.mk
@@ -0,0 +1,97 @@
+# Configuration for Darwin (Mac OS X) on PPC.
+# Included by combo/select.make
+
+$(combo_target)GLOBAL_CFLAGS += -fPIC
+$(combo_target)NO_UNDEFINED_LDFLAGS := -Wl,-undefined,error
+
+$(combo_target)CC := $(CC)
+$(combo_target)CXX := $(CXX)
+$(combo_target)AR := $(AR)
+
+$(combo_target)SHLIB_SUFFIX := .dylib
+$(combo_target)JNILIB_SUFFIX := .jnilib
+
+$(combo_target)GLOBAL_CFLAGS += \
+ -include $(call select-android-config-h,darwin-x86)
+$(combo_target)RUN_RANLIB_AFTER_COPYING := true
+
+ifeq ($(combo_target),TARGET_)
+$(combo_target)CUSTOM_LD_COMMAND := true
+define transform-o-to-shared-lib-inner
+ $(TARGET_CXX) \
+ -dynamiclib -single_module -read_only_relocs suppress \
+ $(TARGET_GLOBAL_LD_DIRS) \
+ $(PRIVATE_ALL_OBJECTS) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(PRIVATE_LDLIBS) \
+ -o $@ \
+ $(PRIVATE_LDFLAGS) \
+ $(if $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES),-all_load) \
+ $(TARGET_LIBGCC)
+endef
+
+define transform-o-to-executable-inner
+ $(TARGET_CXX) \
+ -o $@ \
+ -Wl,-dynamic -headerpad_max_install_names \
+ $(TARGET_GLOBAL_LD_DIRS) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+ $(PRIVATE_ALL_OBJECTS) \
+ $(PRIVATE_LDLIBS) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(TARGET_LIBGCC)
+endef
+
+define transform-o-to-static-executable-inner
+ $(TARGET_CXX) \
+ -static \
+ -o $@ \
+ $(TARGET_GLOBAL_LD_DIRS) \
+ $(PRIVATE_LDFLAGS) \
+ $(PRIVATE_ALL_OBJECTS) \
+ $(PRIVATE_LDLIBS) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(TARGET_LIBGCC)
+endef
+
+else
+$(combo_target)CUSTOM_LD_COMMAND := true
+
+define transform-host-o-to-shared-lib-inner
+ $(HOST_CXX) \
+ -dynamiclib -single_module -read_only_relocs suppress \
+ $(HOST_GLOBAL_LD_DIRS) \
+ $(PRIVATE_ALL_OBJECTS) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(PRIVATE_LDLIBS) \
+ -o $@ \
+ $(PRIVATE_LDFLAGS) \
+ $(HOST_LIBGCC)
+endef
+
+define transform-host-o-to-executable-inner
+$(HOST_CXX) \
+ -o $@ \
+ -Wl,-dynamic -headerpad_max_install_names \
+ $(HOST_GLOBAL_LD_DIRS) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+ $(PRIVATE_ALL_OBJECTS) \
+ $(PRIVATE_LDLIBS) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(HOST_LIBGCC)
+endef
+
+# $(1): The file to check
+define get-file-size
+stat -f "%z" $(1)
+endef
+
+endif
+
diff --git a/core/combo/javac.mk b/core/combo/javac.mk
new file mode 100644
index 0000000..d4c04e7
--- /dev/null
+++ b/core/combo/javac.mk
@@ -0,0 +1,37 @@
+# Selects a Java compiler.
+#
+# Inputs:
+# CUSTOM_JAVA_COMPILER -- "eclipse", "openjdk". or nothing for the system
+# default
+#
+# Outputs:
+# COMMON_JAVAC -- Java compiler command with common arguments
+
+# Whatever compiler is on this system.
+ifeq ($(HOST_OS), windows)
+ COMMON_JAVAC := development/host/windows/prebuilt/javawrap.exe -J-Xmx256m \
+ -target 1.5 -Xmaxerrs 9999999
+else
+ COMMON_JAVAC := javac -J-Xmx512M -target 1.5 -Xmaxerrs 9999999
+endif
+
+# Eclipse.
+ifeq ($(CUSTOM_JAVA_COMPILER), eclipse)
+ COMMON_JAVAC := java -Xmx256m -jar prebuilt/common/ecj/ecj.jar -5 \
+ -maxProblems 9999999 -nowarn
+ $(info CUSTOM_JAVA_COMPILER=eclipse)
+endif
+
+# OpenJDK.
+ifeq ($(CUSTOM_JAVA_COMPILER), openjdk)
+ # We set the VM options (like -Xmx) in the javac script.
+ COMMON_JAVAC := prebuilt/common/openjdk/bin/javac -target 1.5 \
+ -Xmaxerrs 9999999
+ $(info CUSTOM_JAVA_COMPILER=openjdk)
+endif
+
+HOST_JAVAC ?= $(COMMON_JAVAC)
+TARGET_JAVAC ?= $(COMMON_JAVAC)
+
+#$(info HOST_JAVAC=$(HOST_JAVAC))
+#$(info TARGET_JAVAC=$(TARGET_JAVAC))
diff --git a/core/combo/linux-arm.mk b/core/combo/linux-arm.mk
new file mode 100644
index 0000000..507e4dd
--- /dev/null
+++ b/core/combo/linux-arm.mk
@@ -0,0 +1,154 @@
+# Configuration for Linux on ARM.
+# Included by combo/select.make
+
+# You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
+ifeq ($(strip $($(combo_target)TOOLS_PREFIX)),)
+$(combo_target)TOOLS_PREFIX := \
+ prebuilt/$(HOST_PREBUILT_TAG)/toolchain/arm-eabi-4.2.1/bin/arm-eabi-
+endif
+
+$(combo_target)CC := $($(combo_target)TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
+$(combo_target)CXX := $($(combo_target)TOOLS_PREFIX)g++$(HOST_EXECUTABLE_SUFFIX)
+$(combo_target)AR := $($(combo_target)TOOLS_PREFIX)ar$(HOST_EXECUTABLE_SUFFIX)
+$(combo_target)OBJCOPY := $($(combo_target)TOOLS_PREFIX)objcopy$(HOST_EXECUTABLE_SUFFIX)
+$(combo_target)LD := $($(combo_target)TOOLS_PREFIX)ld$(HOST_EXECUTABLE_SUFFIX)
+
+$(combo_target)NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
+
+TARGET_arm_release_CFLAGS := -fomit-frame-pointer \
+ -fstrict-aliasing \
+ -funswitch-loops \
+ -finline-limit=300
+
+TARGET_thumb_release_CFLAGS := -mthumb \
+ -Os \
+ -fomit-frame-pointer \
+ -fno-strict-aliasing \
+ -finline-limit=64
+
+# When building for debug, compile everything as arm.
+TARGET_arm_debug_CFLAGS := $(TARGET_arm_release_CFLAGS) -fno-omit-frame-pointer -fno-strict-aliasing
+TARGET_thumb_debug_CFLAGS := $(TARGET_thumb_release_CFLAGS) -marm -fno-omit-frame-pointer
+
+# NOTE: if you try to build a debug build with thumb, several
+# of the libraries (libpv, libwebcore, libkjs) need to be built
+# 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.
+
+## As hopefully a temporary hack,
+## use this to force a full ARM build (for easier debugging in gdb)
+## (don't forget to do a clean build)
+##TARGET_arm_release_CFLAGS := $(TARGET_arm_release_CFLAGS) -fno-omit-frame-pointer
+##TARGET_thumb_release_CFLAGS := $(TARGET_thumb_release_CFLAGS) -marm -fno-omit-frame-pointer
+
+## on some hosts, the target cross-compiler is not available so do not run this command
+ifneq ($(wildcard $($(combo_target)CC)),)
+$(combo_target)LIBGCC := $(shell $($(combo_target)CC) -mthumb-interwork -print-libgcc-file-name)
+endif
+
+$(combo_target)GLOBAL_CFLAGS += \
+ -march=armv5te -mtune=xscale \
+ -msoft-float -fpic \
+ -mthumb-interwork \
+ -ffunction-sections \
+ -funwind-tables \
+ -fstack-protector \
+ -fno-short-enums \
+ -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ \
+ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ \
+ -include $(call select-android-config-h,linux-arm)
+
+$(combo_target)GLOBAL_CPPFLAGS += -fvisibility-inlines-hidden
+
+$(combo_target)RELEASE_CFLAGS := \
+ -DSK_RELEASE -DNDEBUG \
+ -O2 -g \
+ -Wstrict-aliasing=2 \
+ -finline-functions \
+ -fno-inline-functions-called-once \
+ -fgcse-after-reload \
+ -frerun-cse-after-loop \
+ -frename-registers
+
+libc_root := bionic/libc
+libm_root := bionic/libm
+libstdc++_root := bionic/libstdc++
+libthread_db_root := bionic/libthread_db
+
+# unless CUSTOM_KERNEL_HEADERS is defined, we're going to use
+# symlinks located in out/ to point to the appropriate kernel
+# headers. see 'config/kernel_headers.make' for more details
+#
+ifneq ($(CUSTOM_KERNEL_HEADERS),)
+ KERNEL_HEADERS_COMMON := $(CUSTOM_KERNEL_HEADERS)
+ KERNEL_HEADERS_ARCH := $(CUSTOM_KERNEL_HEADERS)
+else
+ KERNEL_HEADERS_COMMON := $(libc_root)/kernel/common
+ KERNEL_HEADERS_ARCH := $(libc_root)/kernel/arch-$(TARGET_ARCH)
+endif
+KERNEL_HEADERS := $(KERNEL_HEADERS_COMMON) $(KERNEL_HEADERS_ARCH)
+
+$(combo_target)C_INCLUDES := \
+ $(libc_root)/arch-arm/include \
+ $(libc_root)/include \
+ $(libstdc++_root)/include \
+ $(KERNEL_HEADERS) \
+ $(libm_root)/include \
+ $(libm_root)/include/arch/arm \
+ $(libthread_db_root)/include
+
+TARGET_CRTBEGIN_STATIC_O := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_static.o
+TARGET_CRTBEGIN_DYNAMIC_O := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_dynamic.o
+TARGET_CRTEND_O := $(TARGET_OUT_STATIC_LIBRARIES)/crtend_android.o
+
+TARGET_STRIP_MODULE:=true
+
+$(combo_target)DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libm
+
+$(combo_target)CUSTOM_LD_COMMAND := true
+define transform-o-to-shared-lib-inner
+$(TARGET_CXX) \
+ -nostdlib -Wl,-soname,$(notdir $@) -Wl,-T,$(BUILD_SYSTEM)/armelf.xsc \
+ -Wl,--gc-sections \
+ -Wl,-shared,-Bsymbolic \
+ $(TARGET_GLOBAL_LD_DIRS) \
+ $(PRIVATE_ALL_OBJECTS) \
+ -Wl,--whole-archive \
+ $(call normalize-host-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ -Wl,--no-whole-archive \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+ -o $@ \
+ $(PRIVATE_LDFLAGS) \
+ $(TARGET_LIBGCC)
+endef
+
+define transform-o-to-executable-inner
+$(TARGET_CXX) -nostdlib -Bdynamic -Wl,-T,$(BUILD_SYSTEM)/armelf.x \
+ -Wl,-dynamic-linker,/system/bin/linker \
+ -Wl,--gc-sections \
+ -Wl,-z,nocopyreloc \
+ -o $@ \
+ $(TARGET_GLOBAL_LD_DIRS) \
+ -Wl,-rpath-link=$(TARGET_OUT_INTERMEDIATE_LIBRARIES) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+ $(TARGET_CRTBEGIN_DYNAMIC_O) \
+ $(PRIVATE_ALL_OBJECTS) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(PRIVATE_LDFLAGS) \
+ $(TARGET_LIBGCC) \
+ $(TARGET_CRTEND_O)
+endef
+
+define transform-o-to-static-executable-inner
+$(TARGET_CXX) -nostdlib -Bstatic -Wl,-T,$(BUILD_SYSTEM)/armelf.x \
+ -Wl,--gc-sections \
+ -o $@ \
+ $(TARGET_GLOBAL_LD_DIRS) \
+ $(TARGET_CRTBEGIN_STATIC_O) \
+ $(PRIVATE_LDFLAGS) \
+ $(PRIVATE_ALL_OBJECTS) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(TARGET_LIBGCC) \
+ $(TARGET_CRTEND_O)
+endef
diff --git a/core/combo/linux-x86.mk b/core/combo/linux-x86.mk
new file mode 100644
index 0000000..372c63e
--- /dev/null
+++ b/core/combo/linux-x86.mk
@@ -0,0 +1,33 @@
+# Configuration for Linux on x86.
+# Included by combo/select.make
+
+# right now we get these from the environment, but we should
+# pick them from the tree somewhere
+$(combo_target)CC := $(CC)
+$(combo_target)CXX := $(CXX)
+$(combo_target)AR := $(AR)
+
+ifeq ($(combo_target),HOST_)
+# $(1): The file to check
+define get-file-size
+stat --format "%s" "$(1)"
+endef
+endif
+
+# On the sim, we build the "host" tools in 64 bit iff the compiler
+# does it for us automatically. In other words, that means on 64 bit
+# system, they're 64 bit and on 32 bit systems, they're 32 bits. In
+# all other cases, we build 32 bit, since this is what we release.
+ifneq ($(combo_target)$(TARGET_SIMULATOR),HOST_true)
+$(combo_target)GLOBAL_CFLAGS := $($(combo_target)GLOBAL_CFLAGS) -m32
+$(combo_target)GLOBAL_LDFLAGS := $($(combo_target)GLOBAL_LDFLAGS) -m32
+endif
+
+
+$(combo_target)GLOBAL_CFLAGS += -fPIC
+$(combo_target)GLOBAL_CFLAGS += \
+ -include $(call select-android-config-h,linux-x86)
+
+$(combo_target)NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
+
+
diff --git a/core/combo/select.mk b/core/combo/select.mk
new file mode 100644
index 0000000..c54da22
--- /dev/null
+++ b/core/combo/select.mk
@@ -0,0 +1,81 @@
+# Select a combo based on the compiler being used.
+#
+# Inputs:
+# combo_target -- prefix for final variables (HOST_ or TARGET_)
+#
+# Outputs:
+# $(combo_target)OS -- standard name for this host (LINUX, DARWIN, etc.)
+# $(combo_target)ARCH -- standard name for process architecture (powerpc, x86, etc.)
+# $(combo_target)GLOBAL_CFLAGS -- C compiler flags to use for everything
+# $(combo_target)DEBUG_CFLAGS -- additional C compiler flags for debug builds
+# $(combo_target)RELEASE_CFLAGS -- additional C compiler flags for release builds
+# $(combo_target)GLOBAL_ARFLAGS -- flags to use for static linking everything
+# $(combo_target)SHLIB_SUFFIX -- suffix of shared libraries
+
+# Build a target string like "linux-arm" or "darwin-x86".
+combo_os_arch := $($(combo_target)OS)-$($(combo_target)ARCH)
+
+# Set the defaults.
+
+HOST_CC ?= $(CC)
+HOST_CXX ?= $(CXX)
+HOST_AR ?= $(AR)
+
+$(combo_target)BINDER_MINI := 0
+
+$(combo_target)HAVE_EXCEPTIONS := 0
+$(combo_target)HAVE_UNIX_FILE_PATH := 1
+$(combo_target)HAVE_WINDOWS_FILE_PATH := 0
+$(combo_target)HAVE_RTTI := 1
+$(combo_target)HAVE_CALL_STACKS := 1
+$(combo_target)HAVE_64BIT_IO := 1
+$(combo_target)HAVE_CLOCK_TIMERS := 1
+$(combo_target)HAVE_PTHREAD_RWLOCK := 1
+$(combo_target)HAVE_STRNLEN := 1
+$(combo_target)HAVE_STRERROR_R_STRRET := 1
+$(combo_target)HAVE_STRLCPY := 0
+$(combo_target)HAVE_STRLCAT := 0
+$(combo_target)HAVE_KERNEL_MODULES := 0
+
+# These flags might (will) be overridden by the target makefiles
+$(combo_target)GLOBAL_CFLAGS := -fno-exceptions -Wno-multichar
+$(combo_target)DEBUG_CFLAGS := -O0 -g
+$(combo_target)RELEASE_CFLAGS := -O2 -g -fno-strict-aliasing
+$(combo_target)GLOBAL_ARFLAGS := crs
+
+$(combo_target)EXECUTABLE_SUFFIX :=
+$(combo_target)SHLIB_SUFFIX := .so
+$(combo_target)JNILIB_SUFFIX := $($(combo_target)SHLIB_SUFFIX)
+$(combo_target)STATIC_LIB_SUFFIX := .a
+
+$(combo_target)PRELINKER_MAP := $(BUILD_SYSTEM)/prelink-$(combo_os_arch).map
+
+# We try to find a target or host specific file for the os/arch specified, and
+# default to just looking for the os/arch one. This will allow us to define
+# things separately for targets and hosts that have the same architecture
+# but need different defines. e.g. target_linux-x86 and host_linux-x86
+
+ifneq ($(TARGET_SIMULATOR),true)
+# Convert the combo_target string to lowercase
+combo_target_lc := $(shell echo $(combo_target) | tr '[A-Z]' '[a-z]')
+
+# form combo makefile name like "<path>/target_linux-x86.make",
+# "<path>/host_darwin-x86.make", etc.
+combo_target_os_arch := $(BUILD_COMBOS)/$(combo_target_lc)$(combo_os_arch).mk
+else
+combo_target_os_arch :=
+endif
+
+# Now include the combo for this specific target.
+ifneq ($(wildcard $(combo_target_os_arch)),)
+include $(combo_target_os_arch)
+else
+include $(BUILD_COMBOS)/$(combo_os_arch).mk
+endif
+
+ifneq ($(USE_CCACHE),)
+ ccache := prebuilt/$(HOST_PREBUILT_TAG)/ccache/ccache
+ $(combo_target)CC := $(ccache) $($(combo_target)CC)
+ $(combo_target)CXX := $(ccache) $($(combo_target)CXX)
+ ccache =
+endif
diff --git a/core/combo/target_linux-x86.mk b/core/combo/target_linux-x86.mk
new file mode 100644
index 0000000..2d359ff
--- /dev/null
+++ b/core/combo/target_linux-x86.mk
@@ -0,0 +1,129 @@
+# Configuration for Linux on x86 as a target.
+# Included by combo/select.make
+
+# You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
+ifeq ($(strip $($(combo_target)TOOLS_PREFIX)),)
+$(combo_target)TOOLS_PREFIX := \
+ prebuilt/$(HOST_PREBUILT_TAG)/toolchain/i686-unknown-linux-gnu-4.2.1/bin/i686-unknown-linux-gnu-
+endif
+
+$(combo_target)CC := $($(combo_target)TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
+$(combo_target)CXX := $($(combo_target)TOOLS_PREFIX)g++$(HOST_EXECUTABLE_SUFFIX)
+$(combo_target)AR := $($(combo_target)TOOLS_PREFIX)ar$(HOST_EXECUTABLE_SUFFIX)
+$(combo_target)OBJCOPY := $($(combo_target)TOOLS_PREFIX)objcopy$(HOST_EXECUTABLE_SUFFIX)
+$(combo_target)LD := $($(combo_target)TOOLS_PREFIX)ld$(HOST_EXECUTABLE_SUFFIX)
+
+ifneq ($(wildcard $($(combo_target)CC)),)
+$(combo_target)LIBGCC := \
+ $(shell $($(combo_target)CC) -m32 -print-file-name=libgcc.a) \
+ $(shell $($(combo_target)CC) -m32 -print-file-name=libgcc_eh.a)
+endif
+
+$(combo_target)NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
+
+libc_root := bionic/libc
+libm_root := bionic/libm
+libstdc++_root := bionic/libstdc++
+libthread_db_root := bionic/libthread_db
+
+# unless CUSTOM_KERNEL_HEADERS is defined, we're going to use
+# symlinks located in out/ to point to the appropriate kernel
+# headers. see 'config/kernel_headers.make' for more details
+#
+ifneq ($(CUSTOM_KERNEL_HEADERS),)
+ KERNEL_HEADERS_COMMON := $(CUSTOM_KERNEL_HEADERS)
+ KERNEL_HEADERS_ARCH := $(CUSTOM_KERNEL_HEADERS)
+else
+ KERNEL_HEADERS_COMMON := $(libc_root)/kernel/common
+ KERNEL_HEADERS_ARCH := $(libc_root)/kernel/arch-$(TARGET_ARCH)
+endif
+KERNEL_HEADERS := $(KERNEL_HEADERS_COMMON) $(KERNEL_HEADERS_ARCH)
+
+$(combo_target)GLOBAL_CFLAGS += \
+ -march=i686 \
+ -m32 \
+ -fPIC \
+ -include $(call select-android-config-h,target_linux-x86)
+
+$(combo_target)GLOBAL_CPPFLAGS += \
+ -fno-use-cxa-atexit
+
+$(combo_target)C_INCLUDES := \
+ $(libc_root)/arch-x86/include \
+ $(libc_root)/include \
+ $(libstdc++_root)/include \
+ $(KERNEL_HEADERS) \
+ $(libm_root)/include \
+ $(libm_root)/include/i387 \
+ $(libthread_db_root)/include
+
+TARGET_CRTBEGIN_STATIC_O := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_static.o
+TARGET_CRTBEGIN_DYNAMIC_O := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_dynamic.o
+TARGET_CRTEND_O := $(TARGET_OUT_STATIC_LIBRARIES)/crtend_android.o
+
+
+TARGET_CRTBEGIN_SO_O := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_so.o
+TARGET_CRTEND_SO_O := $(TARGET_OUT_STATIC_LIBRARIES)/crtend_so.o
+
+# TARGET_STRIP_MODULE:=true
+
+$(combo_target)DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libm
+
+$(combo_target)CUSTOM_LD_COMMAND := true
+define transform-o-to-shared-lib-inner
+$(TARGET_CXX) \
+ $(TARGET_GLOBAL_LDFLAGS) \
+ -nostdlib -Wl,-soname,$(notdir $@) \
+ -shared -Bsymbolic \
+ -fPIC -march=i686 \
+ $(TARGET_GLOBAL_LD_DIRS) \
+ $(TARGET_CRTBEGIN_SO_O) \
+ $(PRIVATE_ALL_OBJECTS) \
+ -Wl,--whole-archive \
+ $(call normalize-host-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ -Wl,--no-whole-archive \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+ -o $@ \
+ $(PRIVATE_LDFLAGS) \
+ $(TARGET_LIBGCC) \
+ $(TARGET_CRTEND_SO_O)
+endef
+
+
+define transform-o-to-executable-inner
+$(TARGET_CXX) \
+ $(TARGET_GLOBAL_LDFLAGS) \
+ -nostdlib -Bdynamic \
+ -Wl,-dynamic-linker,/system/bin/linker \
+ -Wl,-z,nocopyreloc \
+ -o $@ \
+ $(TARGET_GLOBAL_LD_DIRS) \
+ -Wl,-rpath-link=$(TARGET_OUT_INTERMEDIATE_LIBRARIES) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+ $(TARGET_CRTBEGIN_DYNAMIC_O) \
+ $(PRIVATE_ALL_OBJECTS) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(PRIVATE_LDFLAGS) \
+ $(TARGET_LIBGCC) \
+ $(TARGET_CRTEND_O)
+endef
+
+define transform-o-to-static-executable-inner
+$(TARGET_CXX) \
+ $(TARGET_GLOBAL_LDFLAGS) \
+ -nostdlib -Bstatic \
+ -o $@ \
+ $(TARGET_GLOBAL_LD_DIRS) \
+ $(TARGET_CRTBEGIN_STATIC_O) \
+ $(PRIVATE_LDFLAGS) \
+ $(PRIVATE_ALL_OBJECTS) \
+ -Wl,--start-group \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(TARGET_LIBGCC) \
+ -Wl,--end-group \
+ $(TARGET_CRTEND_O)
+endef
+
+$(combo_target)GLOBAL_CFLAGS += -m32
+$(combo_target)GLOBAL_LDFLAGS += -m32
diff --git a/core/combo/windows-x86.mk b/core/combo/windows-x86.mk
new file mode 100644
index 0000000..e32a077
--- /dev/null
+++ b/core/combo/windows-x86.mk
@@ -0,0 +1,53 @@
+# Configuration for Linux on x86.
+# Included by combo/select.make
+
+# right now we get these from the environment, but we should
+# pick them from the tree somewhere
+TOOLS_PREFIX := #prebuilt/windows/host/bin/
+TOOLS_EXE_SUFFIX := .exe
+
+# Settings to use MinGW has a cross-compiler under Linux
+ifneq ($(findstring Linux,$(UNAME)),)
+ifneq ($(strip $(USE_MINGW)),)
+HOST_ACP_UNAVAILABLE := true
+TOOLS_PREFIX := /usr/bin/i586-mingw32msvc-
+TOOLS_EXE_SUFFIX :=
+$(combo_target)GLOBAL_CFLAGS += -DUSE_MINGW
+$(combo_target)C_INCLUDES += /usr/lib/gcc/i586-mingw32msvc/3.4.4/include
+$(combo_target)GLOBAL_LD_DIRS += -L/usr/i586-mingw32msvc/lib
+endif
+endif
+
+$(combo_target)CC := $(TOOLS_PREFIX)gcc$(TOOLS_EXE_SUFFIX)
+$(combo_target)CXX := $(TOOLS_PREFIX)g++$(TOOLS_EXE_SUFFIX)
+$(combo_target)AR := $(TOOLS_PREFIX)ar$(TOOLS_EXE_SUFFIX)
+
+$(combo_target)GLOBAL_CFLAGS += -include $(call select-android-config-h,windows)
+$(combo_target)GLOBAL_LDFLAGS += --enable-stdcall-fixup
+
+# when building under Cygwin, ensure that we use Mingw compilation by default.
+# you can disable this (i.e. to generate Cygwin executables) by defining the
+# USE_CYGWIN variable in your environment, e.g.:
+#
+# export USE_CYGWIN=1
+#
+# note that the -mno-cygwin flags are not needed when cross-compiling the
+# Windows host tools on Linux
+#
+ifneq ($(findstring CYGWIN,$(UNAME)),)
+ifeq ($(strip $(USE_CYGWIN)),)
+$(combo_target)GLOBAL_CFLAGS += -mno-cygwin
+$(combo_target)GLOBAL_LDFLAGS += -mno-cygwin -mconsole
+endif
+endif
+
+$(combo_target)SHLIB_SUFFIX := .dll
+$(combo_target)EXECUTABLE_SUFFIX := .exe
+
+ifeq ($(combo_target),HOST_)
+# $(1): The file to check
+# TODO: find out what format cygwin's stat(1) uses
+define get-file-size
+999999999
+endef
+endif
diff --git a/core/config.mk b/core/config.mk
new file mode 100644
index 0000000..90a40a7
--- /dev/null
+++ b/core/config.mk
@@ -0,0 +1,310 @@
+# This is included by the top-level Makefile.
+# It sets up standard variables based on the
+# current configuration and platform, which
+# are not specific to what is being built.
+
+# Use bash, not whatever shell somebody has installed as /bin/sh
+# This is repeated from main.mk, since envsetup.sh runs this file
+# directly.
+SHELL := /bin/bash
+
+# Standard source directories.
+SRC_DOCS:= $(TOPDIR)docs
+# TODO: Enforce some kind of layering; only add include paths
+# when a module links against a particular library.
+# TODO: See if we can remove most of these from the global list.
+SRC_HEADERS := \
+ $(TOPDIR)system/core/include \
+ $(TOPDIR)hardware/libhardware/include \
+ $(TOPDIR)hardware/libhardware_legacy/include \
+ $(TOPDIR)hardware/ril/include \
+ $(TOPDIR)dalvik/libnativehelper/include \
+ $(TOPDIR)frameworks/base/include \
+ $(TOPDIR)frameworks/base/opengl/include \
+ $(TOPDIR)external/skia/include
+SRC_HOST_HEADERS:=$(TOPDIR)tools/include
+SRC_LIBRARIES:= $(TOPDIR)libs
+SRC_SERVERS:= $(TOPDIR)servers
+SRC_TARGET_DIR := $(TOPDIR)build/target
+SRC_API_DIR := $(TOPDIR)frameworks/base/api
+
+# Some specific paths to tools
+SRC_DROIDDOC_DIR := $(TOPDIR)build/tools/droiddoc
+
+# Various mappings to avoid hard-coding paths all over the place
+include $(BUILD_SYSTEM)/pathmap.mk
+
+# ###############################################################
+# Build system internal files
+# ###############################################################
+
+BUILD_COMBOS:= $(BUILD_SYSTEM)/combo
+
+CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk
+BUILD_HOST_STATIC_LIBRARY:= $(BUILD_SYSTEM)/host_static_library.mk
+BUILD_HOST_SHARED_LIBRARY:= $(BUILD_SYSTEM)/host_shared_library.mk
+BUILD_STATIC_LIBRARY:= $(BUILD_SYSTEM)/static_library.mk
+BUILD_RAW_STATIC_LIBRARY := $(BUILD_SYSTEM)/raw_static_library.mk
+BUILD_SHARED_LIBRARY:= $(BUILD_SYSTEM)/shared_library.mk
+BUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mk
+BUILD_RAW_EXECUTABLE:= $(BUILD_SYSTEM)/raw_executable.mk
+BUILD_HOST_EXECUTABLE:= $(BUILD_SYSTEM)/host_executable.mk
+BUILD_PACKAGE:= $(BUILD_SYSTEM)/package.mk
+BUILD_HOST_PREBUILT:= $(BUILD_SYSTEM)/host_prebuilt.mk
+BUILD_PREBUILT:= $(BUILD_SYSTEM)/prebuilt.mk
+BUILD_MULTI_PREBUILT:= $(BUILD_SYSTEM)/multi_prebuilt.mk
+BUILD_JAVA_LIBRARY:= $(BUILD_SYSTEM)/java_library.mk
+BUILD_STATIC_JAVA_LIBRARY:= $(BUILD_SYSTEM)/static_java_library.mk
+BUILD_HOST_JAVA_LIBRARY:= $(BUILD_SYSTEM)/host_java_library.mk
+BUILD_DROIDDOC:= $(BUILD_SYSTEM)/droiddoc.mk
+BUILD_COPY_HEADERS := $(BUILD_SYSTEM)/copy_headers.mk
+BUILD_KEY_CHAR_MAP := $(BUILD_SYSTEM)/key_char_map.mk
+
+# ###############################################################
+# Parse out any modifier targets.
+# ###############################################################
+
+# The 'showcommands' goal says to show the full command
+# lines being executed, instead of a short message about
+# the kind of operation being done.
+SHOW_COMMANDS:= $(filter showcommands,$(MAKECMDGOALS))
+
+
+# ###############################################################
+# Set common values
+# ###############################################################
+
+# These can be changed to modify both host and device modules.
+COMMON_GLOBAL_CFLAGS:= -DANDROID -fmessage-length=0 -W -Wall -Wno-unused
+COMMON_DEBUG_CFLAGS:=
+COMMON_RELEASE_CFLAGS:= -DNDEBUG -UDEBUG
+
+COMMON_GLOBAL_CPPFLAGS:=
+COMMON_DEBUG_CPPFLAGS:=
+COMMON_RELEASE_CPPFLAGS:=
+
+# Set the extensions used for various packages
+COMMON_PACKAGE_SUFFIX := .zip
+COMMON_JAVA_PACKAGE_SUFFIX := .jar
+COMMON_ANDROID_PACKAGE_SUFFIX := .apk
+
+# list of flags to turn specific warnings in to errors
+TARGET_ERROR_FLAGS := -Werror=return-type
+
+# ###############################################################
+# Include sub-configuration files
+# ###############################################################
+
+# ---------------------------------------------------------------
+# Try to include buildspec.mk, which will try to set stuff up.
+# If this file doesn't exist, the environemnt variables will
+# be used, and if that doesn't work, then the default is an
+# arm build
+-include $(TOPDIR)buildspec.mk
+
+# ---------------------------------------------------------------
+# Define most of the global variables. These are the ones that
+# are specific to the user's build configuration.
+include $(BUILD_SYSTEM)/envsetup.mk
+
+# $(1): os/arch
+define select-android-config-h
+system/core/include/arch/$(1)/AndroidConfig.h
+endef
+
+combo_target := HOST_
+include $(BUILD_SYSTEM)/combo/select.mk
+
+# on windows, the tools have .exe at the end, and we depend on the
+# host config stuff being done first
+
+combo_target := TARGET_
+include $(BUILD_SYSTEM)/combo/select.mk
+
+# Pick a Java compiler.
+include $(BUILD_SYSTEM)/combo/javac.mk
+
+# ---------------------------------------------------------------
+# Check that the configuration is current. We check that
+# BUILD_ENV_SEQUENCE_NUMBER is current against this value.
+# Don't fail if we're called from envsetup, so they have a
+# chance to update their environment.
+
+ifeq (,$(strip $(CALLED_FROM_SETUP)))
+ifneq (,$(strip $(BUILD_ENV_SEQUENCE_NUMBER)))
+ifneq ($(BUILD_ENV_SEQUENCE_NUMBER),$(CORRECT_BUILD_ENV_SEQUENCE_NUMBER))
+$(warning BUILD_ENV_SEQUENCE_NUMBER is set incorrectly.)
+$(info *** If you use envsetup/lunch/choosecombo:)
+$(info *** - Re-execute envsetup (". envsetup.sh"))
+$(info *** - Re-run lunch or choosecombo)
+$(info *** If you use buildspec.mk:)
+$(info *** - Look at buildspec.mk.default to see what has changed)
+$(info *** - Update BUILD_ENV_SEQUENCE_NUMBER to "$(CORRECT_BUILD_ENV_SEQUENCE_NUMBER)")
+$(error bailing..)
+endif
+endif
+endif
+
+
+# ---------------------------------------------------------------
+# Generic tools.
+
+LEX:= flex
+YACC:= bison -d
+DOXYGEN:= doxygen
+AAPT := $(HOST_OUT_EXECUTABLES)/aapt$(HOST_EXECUTABLE_SUFFIX)
+ACP := $(HOST_OUT_EXECUTABLES)/acp$(HOST_EXECUTABLE_SUFFIX)
+AIDL := $(HOST_OUT_EXECUTABLES)/aidl$(HOST_EXECUTABLE_SUFFIX)
+ICUDATA := $(HOST_OUT_EXECUTABLES)/icudata$(HOST_EXECUTABLE_SUFFIX)
+SIGNAPK_JAR := $(HOST_OUT_JAVA_LIBRARIES)/signapk$(COMMON_JAVA_PACKAGE_SUFFIX)
+MKBOOTFS := $(HOST_OUT_EXECUTABLES)/mkbootfs$(HOST_EXECUTABLE_SUFFIX)
+MKBOOTIMG := $(HOST_OUT_EXECUTABLES)/mkbootimg$(HOST_EXECUTABLE_SUFFIX)
+MKYAFFS2 := $(HOST_OUT_EXECUTABLES)/mkyaffs2image$(HOST_EXECUTABLE_SUFFIX)
+APICHECK := $(HOST_OUT_EXECUTABLES)/apicheck$(HOST_EXECUTABLE_SUFFIX)
+FS_GET_STATS := $(HOST_OUT_EXECUTABLES)/fs_get_stats$(HOST_EXECUTABLE_SUFFIX)
+MKEXT2IMG := $(HOST_OUT_EXECUTABLES)/genext2fs$(HOST_EXECUTABLE_SUFFIX)
+MKEXT2BOOTIMG := external/genext2fs/mkbootimg_ext2.sh
+MKTARBALL := build/tools/mktarball.sh
+TUNE2FS := tune2fs
+E2FSCK := e2fsck
+JARJAR := java -jar $(HOST_OUT_JAVA_LIBRARIES)/jarjar.jar
+
+# dx is java behind a shell script; no .exe necessary.
+DX := $(HOST_OUT_EXECUTABLES)/dx
+KCM := $(HOST_OUT_EXECUTABLES)/kcm$(HOST_EXECUTABLE_SUFFIX)
+ZIPALIGN := $(HOST_OUT_EXECUTABLES)/zipalign$(HOST_EXECUTABLE_SUFFIX)
+FINDBUGS := prebuilt/common/findbugs/bin/findbugs
+LOCALIZE := $(HOST_OUT_EXECUTABLES)/localize$(HOST_EXECUTABLE_SUFFIX)
+EMMA_JAR := external/emma/lib/emma$(COMMON_JAVA_PACKAGE_SUFFIX)
+
+# Binary prelinker/compressor tools
+APRIORI := $(HOST_OUT_EXECUTABLES)/apriori$(HOST_EXECUTABLE_SUFFIX)
+LSD := $(HOST_OUT_EXECUTABLES)/lsd$(HOST_EXECUTABLE_SUFFIX)
+SOSLIM := $(HOST_OUT_EXECUTABLES)/soslim$(HOST_EXECUTABLE_SUFFIX)
+
+# Deal with archaic version of bison on Mac OS X.
+ifeq ($(filter 1.28,$(shell $(YACC) -V)),)
+YACC_HEADER_SUFFIX:= .hpp
+else
+YACC_HEADER_SUFFIX:= .cpp.h
+endif
+
+# Don't use column under Windows, cygwin or not
+ifeq ($(HOST_OS),windows)
+COLUMN:= cat
+else
+COLUMN:= column
+endif
+
+dir := $(shell uname)
+ifeq ($(HOST_OS),windows)
+dir := $(HOST_OS)
+endif
+ifeq ($(HOST_OS),darwin)
+dir := $(HOST_OS)-$(HOST_ARCH)
+endif
+OLD_FLEX := prebuilt/$(HOST_PREBUILT_TAG)/flex/flex-2.5.4a$(HOST_EXECUTABLE_SUFFIX)
+
+ifeq ($(HOST_OS),darwin)
+# Mac OS' screwy version of java uses a non-standard directory layout
+# and doesn't even seem to have tools.jar. On the other hand, javac seems
+# to be able to magically find the classes in there, wherever they are, so
+# leave this blank
+HOST_JDK_TOOLS_JAR :=
+else
+HOST_JDK_TOOLS_JAR:= $(shell $(BUILD_SYSTEM)/find-jdk-tools-jar.sh)
+endif
+
+# It's called md5 on Mac OS and md5sum on Linux
+ifeq ($(HOST_OS),darwin)
+MD5SUM:=md5 -q
+else
+MD5SUM:=md5sum
+endif
+
+# ###############################################################
+# Set up final options.
+# ###############################################################
+
+HOST_GLOBAL_CFLAGS += $(COMMON_GLOBAL_CFLAGS)
+HOST_DEBUG_CFLAGS += $(COMMON_DEBUG_CFLAGS)
+HOST_RELEASE_CFLAGS += $(COMMON_RELEASE_CFLAGS)
+
+HOST_GLOBAL_CPPFLAGS += $(COMMON_GLOBAL_CPPFLAGS)
+HOST_DEBUG_CPPFLAGS += $(COMMON_DEBUG_CPPFLAGS)
+HOST_RELEASE_CPPFLAGS += $(COMMON_RELEASE_CPPFLAGS)
+
+TARGET_GLOBAL_CFLAGS += $(COMMON_GLOBAL_CFLAGS)
+TARGET_DEBUG_CFLAGS += $(COMMON_DEBUG_CFLAGS)
+TARGET_RELEASE_CFLAGS += $(COMMON_RELEASE_CFLAGS)
+
+TARGET_GLOBAL_CPPFLAGS += $(COMMON_GLOBAL_CPPFLAGS)
+TARGET_DEBUG_CPPFLAGS += $(COMMON_DEBUG_CPPFLAGS)
+TARGET_RELEASE_CPPFLAGS += $(COMMON_RELEASE_CPPFLAGS)
+
+HOST_GLOBAL_LD_DIRS += -L$(HOST_OUT_INTERMEDIATE_LIBRARIES)
+TARGET_GLOBAL_LD_DIRS += -L$(TARGET_OUT_INTERMEDIATE_LIBRARIES)
+
+HOST_PROJECT_INCLUDES:= $(SRC_HEADERS) $(SRC_HOST_HEADERS) $(HOST_OUT_HEADERS)
+TARGET_PROJECT_INCLUDES:= $(SRC_HEADERS) $(TARGET_OUT_HEADERS)
+
+# Many host compilers don't support these flags, so we have to make
+# sure to only specify them for the target compilers checked in to
+# the source tree. The simulator uses the target flags but the
+# host compiler, so only set them for the target when the target
+# is not the simulator.
+ifneq ($(TARGET_SIMULATOR),true)
+TARGET_GLOBAL_CFLAGS += $(TARGET_ERROR_FLAGS)
+TARGET_GLOBAL_CPPFLAGS += $(TARGET_ERROR_FLAGS)
+endif
+
+ifeq ($(HOST_BUILD_TYPE),release)
+HOST_GLOBAL_CFLAGS+= $(HOST_RELEASE_CFLAGS)
+HOST_GLOBAL_CPPFLAGS+= $(HOST_RELEASE_CPPFLAGS)
+else
+HOST_GLOBAL_CFLAGS+= $(HOST_DEBUG_CFLAGS)
+HOST_GLOBAL_CPPFLAGS+= $(HOST_DEBUG_CPPFLAGS)
+endif
+
+ifeq ($(TARGET_BUILD_TYPE),release)
+TARGET_GLOBAL_CFLAGS+= $(TARGET_RELEASE_CFLAGS)
+TARGET_GLOBAL_CPPFLAGS+= $(TARGET_RELEASE_CPPFLAGS)
+else
+TARGET_GLOBAL_CFLAGS+= $(TARGET_DEBUG_CFLAGS)
+TARGET_GLOBAL_CPPFLAGS+= $(TARGET_DEBUG_CPPFLAGS)
+endif
+
+# TODO: do symbol compression
+TARGET_COMPRESS_MODULE_SYMBOLS := false
+TARGET_PRELINK_MODULE := true
+
+PREBUILT_IS_PRESENT := $(if $(wildcard prebuilt/Android.mk),true)
+
+
+# ###############################################################
+# Collect a list of the SDK versions that we could compile against
+# For use with the LOCAL_SDK_VERSION variable for include $(BUILD_PACKAGE)
+# ###############################################################
+
+# The files that we can convert into android.jars are are in config/api/*.xml
+# The 'current' version is whatever this source tree is. Once the apicheck
+# tool can generate the stubs from the xml files, we'll use that to be
+# able to build back-versions. In the meantime, 'current' is the only
+# one supported.
+#
+# sgrax is the opposite of xargs. It takes the list of args and puts them
+# on each line for sort to process.
+# sort -g is a numeric sort, so 1 2 3 10 instead of 1 10 2 3.
+TARGET_AVAILABLE_SDK_VERSIONS := current \
+ $(shell function sgrax() { \
+ while [ -n "$$1" ] ; do echo $$1 ; shift ; done \
+ } ; \
+ ( sgrax $(patsubst $(SRC_API_DIR)/%.xml,%, \
+ $(filter-out $(SRC_API_DIR)/current.xml, \
+ $(shell find $(SRC_API_DIR) -name "*.xml"))) | sort -g ) )
+
+
+INTERNAL_PLATFORM_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/public_api.xml
+
+
+
diff --git a/core/copy_headers.mk b/core/copy_headers.mk
new file mode 100644
index 0000000..dac07d5
--- /dev/null
+++ b/core/copy_headers.mk
@@ -0,0 +1,23 @@
+###########################################################
+## Copy headers to the install tree
+###########################################################
+ifneq ($(strip $(LOCAL_IS_HOST_MODULE)),)
+ my_prefix := HOST_
+else
+ my_prefix := TARGET_
+endif
+
+# Create a rule to copy each header, and make the
+# all_copied_headers phony target depend on each
+# destination header. copy-one-header defines the
+# actual rule.
+#
+$(foreach header,$(LOCAL_COPY_HEADERS), \
+ $(eval _chFrom := $(LOCAL_PATH)/$(header)) \
+ $(eval _chTo := \
+ $($(my_prefix)OUT_HEADERS)/$(LOCAL_COPY_HEADERS_TO)/$(notdir $(header))) \
+ $(eval $(call copy-one-header,$(_chFrom),$(_chTo))) \
+ $(eval all_copied_headers: $(_chTo)) \
+ )
+_chFrom :=
+_chTo :=
diff --git a/core/definitions.mk b/core/definitions.mk
new file mode 100644
index 0000000..3efef8d
--- /dev/null
+++ b/core/definitions.mk
@@ -0,0 +1,1488 @@
+#
+# 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.
+#
+
+##
+## Common build system definitions. Mostly standard
+## commands for building various types of targets, which
+## are used by others to construct the final targets.
+##
+
+# These are variables we use to collect overall lists
+# of things being processed.
+
+# Full paths to all of the documentation
+ALL_DOCS:=
+
+# The short names of all of the targets in the system.
+# For each element of ALL_MODULES, two other variables
+# are defined:
+# $(ALL_MODULES.$(target)).BUILT
+# $(ALL_MODULES.$(target)).INSTALLED
+# The BUILT variable contains LOCAL_BUILT_MODULE for that
+# target, and the INSTALLED variable contains the LOCAL_INSTALLED_MODULE.
+# Some targets may have multiple files listed in the BUILT and INSTALLED
+# sub-variables.
+ALL_MODULES:=
+
+# Full paths to targets that should be added to the "make droid"
+# set of installed targets.
+ALL_DEFAULT_INSTALLED_MODULES:=
+
+# Full paths to all targets that will be built.
+ALL_BUILT_MODULES:=
+
+# The list of tags that have been defined by
+# LOCAL_MODULE_TAGS. Each word in this variable maps
+# to a corresponding ALL_MODULE_TAGS.<tagname> variable
+# that contains all of the INSTALLED_MODULEs with that tag.
+ALL_MODULE_TAGS:=
+
+# Similar to ALL_MODULE_TAGS, but contains the short names
+# of all targets for a particular tag. The top-level variable
+# won't have the list of tags; ust ALL_MODULE_TAGS to get
+# the list of all known tags. (This means that this variable
+# will always be empty; it's just here as a placeholder for
+# its sub-variables.)
+ALL_MODULE_NAME_TAGS:=
+
+# Full paths to all prebuilt files that will be copied
+# (used to make the dependency on acp)
+ALL_PREBUILT:=
+
+# Full path to all files that are made by some tool
+ALL_GENERATED_SOURCES:=
+
+# Full path to all asm, C, C++, lex and yacc generated C files.
+# These all have an order-only dependency on the copied headers
+ALL_C_CPP_ETC_OBJECTS:=
+
+# The list of dynamic binaries that haven't been stripped/compressed/prelinked.
+ALL_ORIGINAL_DYNAMIC_BINARIES:=
+
+# These files go into the SDK
+ALL_SDK_FILES:=
+
+# Files for dalvik. This is often build without building the rest of the OS.
+INTERNAL_DALVIK_MODULES:=
+
+# All findbugs xml files
+ALL_FINDBUGS_FILES:=
+
+###########################################################
+## Debugging; prints a variable list to stdout
+###########################################################
+
+# $(1): variable name list, not variable values
+define print-vars
+$(foreach var,$(1), \
+ $(info $(var):) \
+ $(foreach word,$($(var)), \
+ $(info $(space)$(space)$(word)) \
+ ) \
+ )
+endef
+
+###########################################################
+## Retrieve the directory of the current makefile
+###########################################################
+
+# Figure out where we are.
+define my-dir
+$(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST),$(MAKEFILE_LIST))))
+endef
+
+###########################################################
+## Retrieve a list of all makefiles immediately below some directory
+###########################################################
+
+define all-makefiles-under
+$(wildcard $(1)/*/Android.mk)
+endef
+
+###########################################################
+## Look under a directory for makefiles that don't have parent
+## makefiles.
+###########################################################
+
+# $(1): directory to search under
+# Ignores $(1)/Android.mk
+define first-makefiles-under
+$(shell build/tools/findleaves.sh --mindepth=2 $(1) Android.mk)
+endef
+
+###########################################################
+## Retrieve a list of all makefiles immediately below your directory
+###########################################################
+
+define all-subdir-makefiles
+$(call all-makefiles-under,$(call my-dir))
+endef
+
+###########################################################
+## Look in the named list of directories for makefiles,
+## relative to the current directory.
+###########################################################
+
+# $(1): List of directories to look for under this directory
+define all-named-subdir-makefiles
+$(wildcard $(addsuffix /Android.mk, $(addprefix $(my-dir)/,$(1))))
+endef
+
+###########################################################
+## Find all of the java files under the named directories.
+## Meant to be used like:
+## SRC_FILES := $(call all-java-files-under,src tests)
+###########################################################
+
+define all-java-files-under
+$(patsubst ./%,%, \
+ $(shell cd $(LOCAL_PATH) ; \
+ find $(1) -name "*.java" -and -not -name ".*") \
+ )
+endef
+
+###########################################################
+## Find all of the java files from here. Meant to be used like:
+## SRC_FILES := $(call all-subdir-java-files)
+###########################################################
+
+define all-subdir-java-files
+$(call all-java-files-under,.)
+endef
+
+###########################################################
+## Find all of the c files under the named directories.
+## Meant to be used like:
+## SRC_FILES := $(call all-c-files-under,src tests)
+###########################################################
+
+define all-c-files-under
+$(patsubst ./%,%, \
+ $(shell cd $(LOCAL_PATH) ; \
+ find $(1) -name "*.c" -and -not -name ".*") \
+ )
+endef
+
+###########################################################
+## Find all of the c files from here. Meant to be used like:
+## SRC_FILES := $(call all-subdir-c-files)
+###########################################################
+
+define all-subdir-c-files
+$(call all-c-files-under,.)
+endef
+
+###########################################################
+## Find all files named "I*.aidl" under the named directories,
+## which must be relative to $(LOCAL_PATH). The returned list
+## is relative to $(LOCAL_PATH).
+###########################################################
+
+define all-Iaidl-files-under
+$(patsubst ./%,%, \
+ $(shell cd $(LOCAL_PATH) ; \
+ find $(1) -name "I*.aidl" -and -not -name ".*") \
+ )
+endef
+
+###########################################################
+## Find all of the "I*.aidl" files under $(LOCAL_PATH).
+###########################################################
+
+define all-subdir-Iaidl-files
+$(call all-Iaidl-files-under,.)
+endef
+
+###########################################################
+## Find all of the html files from here. Meant to be used like:
+## SRC_FILES := $(call all-subdir-html-files)
+###########################################################
+
+define all-subdir-html-files
+$(patsubst ./%,%,$(shell cd $(LOCAL_PATH) ; find . -name "*.html"))
+endef
+
+###########################################################
+## Find all of the files matching pattern
+## SRC_FILES := $(call find-subdir-files, <pattern>)
+###########################################################
+
+define find-subdir-files
+$(patsubst ./%,%,$(shell cd $(LOCAL_PATH) ; find $(1)))
+endef
+
+###########################################################
+# find the files in the subdirectory $1 of LOCAL_DIR
+# matching pattern $2, filtering out files $3
+# e.g.
+# SRC_FILES += $(call find-subdir-subdir-files, \
+# css, *.cpp, DontWantThis.cpp)
+###########################################################
+
+define find-subdir-subdir-files
+$(filter-out $(patsubst %,$(1)/%,$(3)),$(patsubst ./%,%,$(shell cd \
+ $(LOCAL_PATH) ; find $(1) -maxdepth 1 -name $(2))))
+endef
+
+###########################################################
+## Find all of the files matching pattern
+## SRC_FILES := $(call all-subdir-java-files)
+###########################################################
+
+define find-subdir-assets
+$(if $(1),$(patsubst ./%,%, \
+ $(shell if [ -d $(1) ] ; then cd $(1) ; find ./ -type f -and -not -type l ; fi)), \
+ $(warning Empty argument supplied to find-subdir-assets) \
+)
+endef
+
+###########################################################
+## Find various file types in a list of directories relative to $(LOCAL_PATH)
+###########################################################
+
+define find-other-java-files
+ $(call find-subdir-files,$(1) -name "*.java" -and -not -name ".*")
+endef
+
+define find-other-html-files
+ $(call find-subdir-files,$(1) -name "*.html" -and -not -name ".*")
+endef
+
+###########################################################
+## Scan through each directory of $(1) looking for files
+## that match $(2) using $(wildcard). Useful for seeing if
+## a given directory or one of its parents contains
+## a particular file. Returns the first match found,
+## starting furthest from the root.
+###########################################################
+
+define find-parent-file
+$(strip \
+ $(eval _fpf := $(wildcard $(strip $(1))/$(strip $(2)))) \
+ $(if $(_fpf),$(_fpf), \
+ $(if $(filter-out ./ .,$(1)), \
+ $(call find-parent-file,$(patsubst %/,%,$(dir $(1))),$(2)) \
+ ) \
+ ) \
+)
+endef
+
+###########################################################
+## Function we can evaluate to introduce a dynamic dependency
+###########################################################
+
+define add-dependency
+$(1): $(2)
+endef
+
+###########################################################
+## Set up the dependencies for a prebuilt target
+## $(call add-prebuilt-file, srcfile, [targetclass])
+###########################################################
+
+define add-prebuilt-file
+ $(eval $(include-prebuilt))
+endef
+
+define include-prebuilt
+ include $$(CLEAR_VARS)
+ LOCAL_SRC_FILES := $(1)
+ LOCAL_BUILT_MODULE_STEM := $(1)
+ LOCAL_MODULE_SUFFIX := $$(suffix $(1))
+ LOCAL_MODULE := $$(basename $(1))
+ LOCAL_MODULE_CLASS := $(2)
+ include $$(BUILD_PREBUILT)
+endef
+
+###########################################################
+## do multiple prebuilts
+## $(call target class, files ...)
+###########################################################
+
+define add-prebuilt-files
+ $(foreach f,$(2),$(call add-prebuilt-file,$f,$(1)))
+endef
+
+
+
+###########################################################
+## The intermediates directory. Where object files go for
+## a given target. We could technically get away without
+## the "_intermediates" suffix on the directory, but it's
+## nice to be able to grep for that string to find out if
+## anyone's abusing the system.
+###########################################################
+
+# $(1): target class, like "APPS"
+# $(2): target name, like "NotePad"
+# $(3): if non-empty, this is a HOST target.
+# $(4): if non-empty, force the intermediates to be COMMON
+define intermediates-dir-for
+$(strip \
+ $(eval _idfClass := $(strip $(1))) \
+ $(if $(_idfClass),, \
+ $(error $(LOCAL_PATH): Class not defined in call to intermediates-dir-for)) \
+ $(eval _idfName := $(strip $(2))) \
+ $(if $(_idfName),, \
+ $(error $(LOCAL_PATH): Name not defined in call to intermediates-dir-for)) \
+ $(eval _idfPrefix := $(if $(strip $(3)),HOST,TARGET)) \
+ $(if $(filter $(_idfClass),$(COMMON_MODULE_CLASSES))$(4), \
+ $(eval _idfIntBase := $($(_idfPrefix)_OUT_COMMON_INTERMEDIATES)) \
+ , \
+ $(eval _idfIntBase := $($(_idfPrefix)_OUT_INTERMEDIATES)) \
+ ) \
+ $(_idfIntBase)/$(_idfClass)/$(_idfName)_intermediates \
+)
+endef
+
+# Uses LOCAL_MODULE_CLASS, LOCAL_MODULE, and LOCAL_IS_HOST_MODULE
+# to determine the intermediates directory.
+#
+# $(1): if non-empty, force the intermediates to be COMMON
+define local-intermediates-dir
+$(strip \
+ $(if $(strip $(LOCAL_MODULE_CLASS)),, \
+ $(error $(LOCAL_PATH): LOCAL_MODULE_CLASS not defined before call to local-intermediates-dir)) \
+ $(if $(strip $(LOCAL_MODULE)),, \
+ $(error $(LOCAL_PATH): LOCAL_MODULE not defined before call to local-intermediates-dir)) \
+ $(call intermediates-dir-for,$(LOCAL_MODULE_CLASS),$(LOCAL_MODULE),$(LOCAL_IS_HOST_MODULE),$(1)) \
+)
+endef
+
+###########################################################
+## Convert "path/to/libXXX.so" to "-lXXX".
+## Any "path/to/libXXX.a" elements pass through unchanged.
+###########################################################
+
+define normalize-libraries
+$(foreach so,$(filter %.so,$(1)),-l$(patsubst lib%.so,%,$(notdir $(so))))\
+$(filter-out %.so,$(1))
+endef
+
+# TODO: change users to call the common version.
+define normalize-host-libraries
+$(call normalize-libraries,$(1))
+endef
+
+define normalize-target-libraries
+$(call normalize-libraries,$(1))
+endef
+
+###########################################################
+## Convert a list of short module names (e.g., "framework", "Browser")
+## into the list of files that are built for those modules.
+## NOTE: this won't return reliable results until after all
+## sub-makefiles have been included.
+## $(1): target list
+###########################################################
+
+define module-built-files
+$(foreach module,$(1),$(ALL_MODULES.$(module).BUILT))
+endef
+
+###########################################################
+## Convert a list of short modules names (e.g., "framework", "Browser")
+## into the list of files that are installed for those modules.
+## NOTE: this won't return reliable results until after all
+## sub-makefiles have been included.
+## $(1): target list
+###########################################################
+
+define module-installed-files
+$(foreach module,$(1),$(ALL_MODULES.$(module).INSTALLED))
+endef
+
+###########################################################
+## Convert "framework framework-res ext" to "out/.../javalib.jar ..."
+## This lets us treat framework-res as a normal library.
+## $(1): library list
+## $(2): Non-empty if IS_HOST_MODULE
+###########################################################
+
+# $(1): library name
+# $(2): Non-empty if IS_HOST_MODULE
+define _java-lib-dir
+$(call intermediates-dir-for, \
+ $(if $(filter framework-res,$(1)),APPS,JAVA_LIBRARIES),$(1),$(2))
+endef
+
+# $(1): library name
+define _java-lib-classes.jar
+$(if $(filter framework-res,$(1)),package$(COMMON_ANDROID_PACKAGE_SUFFIX),classes$(COMMON_JAVA_PACKAGE_SUFFIX))
+endef
+
+# $(1): library name
+# $(2): Non-empty if IS_HOST_MODULE
+define _java-lib-full-classes.jar
+$(call _java-lib-dir,$(1),$(2))/$(call _java-lib-classes.jar,$(1))
+endef
+
+# $(1): library name list
+# $(2): Non-empty if IS_HOST_MODULE
+define java-lib-files
+$(foreach lib,$(1),$(call _java-lib-full-classes.jar,$(lib),$(2)))
+endef
+
+# $(1): library name
+define _java-lib-dep
+$(if $(filter framework-res,$(1)),package$(COMMON_ANDROID_PACKAGE_SUFFIX),javalib$(COMMON_JAVA_PACKAGE_SUFFIX))
+endef
+
+# $(1): library name
+# $(2): Non-empty if IS_HOST_MODULE
+define _java-lib-full-dep
+$(call _java-lib-dir,$(1),$(2))/$(call _java-lib-dep,$(1))
+endef
+
+# $(1): library name list
+# $(2): Non-empty if IS_HOST_MODULE
+define java-lib-deps
+$(foreach lib,$(1),$(call _java-lib-full-dep,$(lib),$(2)))
+endef
+
+###########################################################
+## Convert "a b c" into "a:b:c"
+###########################################################
+
+empty :=
+space := $(empty) $(empty)
+
+define normalize-path-list
+$(subst $(space),:,$(strip $(1)))
+endef
+
+###########################################################
+## Convert "a=b c= d e = f" into "a=b c=d e=f"
+##
+## $(1): list to collapse
+## $(2): if set, separator word; usually "=", ":", or ":="
+## Defaults to "=" if not set.
+###########################################################
+
+define collapse-pairs
+$(eval _cpSEP := $(strip $(if $(2),$(2),=)))\
+$(subst $(space)$(_cpSEP)$(space),$(_cpSEP),$(strip \
+ $(subst $(_cpSEP), $(_cpSEP) ,$(1))))
+endef
+
+
+###########################################################
+## MODULE_TAG set operations
+###########################################################
+
+# Given a list of tags, return the targets that specify
+# any of those tags.
+# $(1): tag list
+define modules-for-tag-list
+$(sort $(foreach tag,$(1),$(ALL_MODULE_TAGS.$(tag))))
+endef
+
+# Same as modules-for-tag-list, but operates on
+# ALL_MODULE_NAME_TAGS.
+# $(1): tag list
+define module-names-for-tag-list
+$(sort $(foreach tag,$(1),$(ALL_MODULE_NAME_TAGS.$(tag))))
+endef
+
+# Given an accept and reject list, find the matching
+# set of targets. If a target has multiple tags and
+# any of them are rejected, the target is rejected.
+# Reject overrides accept.
+# $(1): list of tags to accept
+# $(2): list of tags to reject
+#TODO(dbort): do $(if $(strip $(1)),$(1),$(ALL_MODULE_TAGS))
+define get-tagged-modules
+$(filter-out \
+ $(call modules-for-tag-list,$(2)), \
+ $(call modules-for-tag-list,$(1)))
+endef
+
+
+###########################################################
+## Package filtering
+###########################################################
+
+# Given a list of installed modules (short or long names)
+# return a list of the packages (yes, .apk packages, not
+# modules in general) that are overridden by this list and,
+# therefore, should not be installed.
+# $(1): mixed list of installed modules
+# TODO: This is fragile; find a reliable way to get this information.
+define _get-package-overrides
+ $(eval ### Discard any words containing slashes, unless they end in .apk, \
+ ### in which case trim off the directory component and the suffix. \
+ ### If there are no slashes, keep the entire word.)
+ $(eval _gpo_names := $(subst /,@@@ @@@,$(1)))
+ $(eval _gpo_names := \
+ $(filter %.apk,$(_gpo_names)) \
+ $(filter-out %@@@ @@@%,$(_gpo_names)))
+ $(eval _gpo_names := $(patsubst %.apk,%,$(_gpo_names)))
+ $(eval _gpo_names := $(patsubst @@@%,%,$(_gpo_names)))
+
+ $(eval ### Remove any remaining words that contain dots.)
+ $(eval _gpo_names := $(subst .,@@@ @@@,$(_gpo_names)))
+ $(eval _gpo_names := $(filter-out %@@@ @@@%,$(_gpo_names)))
+
+ $(eval ### Now we have a list of any words that could possibly refer to \
+ ### packages, although there may be words that do not. Only \
+ ### real packages will be present under PACKAGES.*, though.)
+ $(foreach _gpo_name,$(_gpo_names),$(PACKAGES.$(_gpo_name).OVERRIDES))
+endef
+
+define get-package-overrides
+$(strip $(sort $(call _get-package-overrides,$(1))))
+endef
+
+###########################################################
+## Output the command lines, or not
+###########################################################
+
+ifeq ($(strip $(SHOW_COMMANDS)),)
+define pretty
+@echo $1
+endef
+hide := @
+else
+define pretty
+endef
+hide :=
+endif
+
+###########################################################
+## Dump the variables that are associated with targets
+###########################################################
+
+define dump-module-variables
+@echo all_dependencies=$^
+@echo PRIVATE_YACCFLAGS=$(PRIVATE_YACCFLAGS);
+@echo PRIVATE_CFLAGS=$(PRIVATE_CFLAGS);
+@echo PRIVATE_CPPFLAGS=$(PRIVATE_CPPFLAGS);
+@echo PRIVATE_DEBUG_CFLAGS=$(PRIVATE_DEBUG_CFLAGS);
+@echo PRIVATE_C_INCLUDES=$(PRIVATE_C_INCLUDES);
+@echo PRIVATE_LDFLAGS=$(PRIVATE_LDFLAGS);
+@echo PRIVATE_LDLIBS=$(PRIVATE_LDLIBS);
+@echo PRIVATE_ARFLAGS=$(PRIVATE_ARFLAGS);
+@echo PRIVATE_AAPT_FLAGS=$(PRIVATE_AAPT_FLAGS);
+@echo PRIVATE_DX_FLAGS=$(PRIVATE_DX_FLAGS);
+@echo PRIVATE_JAVA_LIBRARIES=$(PRIVATE_JAVA_LIBRARIES);
+@echo PRIVATE_ALL_SHARED_LIBRARIES=$(PRIVATE_ALL_SHARED_LIBRARIES);
+@echo PRIVATE_ALL_STATIC_LIBRARIES=$(PRIVATE_ALL_STATIC_LIBRARIES);
+@echo PRIVATE_ALL_WHOLE_STATIC_LIBRARIES=$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES);
+@echo PRIVATE_ALL_OBJECTS=$(PRIVATE_ALL_OBJECTS);
+endef
+
+###########################################################
+## Commands for using sed to replace given variable values
+###########################################################
+
+define transform-variables
+@mkdir -p $(dir $@)
+@echo "Sed: $(if $(PRIVATE_MODULE),$(PRIVATE_MODULE),$@) <= $<"
+$(hide) sed $(foreach var,$(REPLACE_VARS),-e "s/{{$(var)}}/$(subst /,\/,$(PWD)/$($(var)))/g") $< >$@
+$(hide) if [ "$(suffix $@)" = ".sh" ]; then chmod a+rx $@; fi
+endef
+
+
+###########################################################
+## Commands for munging the dependency files GCC generates
+###########################################################
+
+define transform-d-to-p
+@cp $(@:%.o=%.d) $(@:%.o=%.P); \
+ sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
+ -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
+ rm -f $(@:%.o=%.d)
+endef
+
+###########################################################
+## Commands for running lex
+###########################################################
+
+define transform-l-to-cpp
+@mkdir -p $(dir $@)
+@echo "Lex: $(PRIVATE_MODULE) <= $<"
+$(hide) $(LEX) -o$@ $<
+endef
+
+###########################################################
+## Commands for running yacc
+##
+## Because the extension of c++ files can change, the
+## extension must be specified in $1.
+## E.g, "$(call transform-y-to-cpp,.cpp)"
+###########################################################
+
+define transform-y-to-cpp
+@mkdir -p $(dir $@)
+@echo "Yacc: $(PRIVATE_MODULE) <= $<"
+$(YACC) $(PRIVATE_YACCFLAGS) -o $@ $<
+touch $(@:$1=$(YACC_HEADER_SUFFIX))
+echo '#ifndef '$(@F:$1=_h) > $(@:$1=.h)
+echo '#define '$(@F:$1=_h) >> $(@:$1=.h)
+cat $(@:$1=$(YACC_HEADER_SUFFIX)) >> $(@:$1=.h)
+echo '#endif' >> $(@:$1=.h)
+rm -f $(@:$1=$(YACC_HEADER_SUFFIX))
+endef
+
+
+###########################################################
+## Commands for running aidl
+###########################################################
+
+define transform-aidl-to-java
+@mkdir -p $(dir $@)
+@echo "Aidl: $(PRIVATE_MODULE) <= $<"
+$(hide) $(AIDL) -d$(patsubst %.java,%.P,$@) $(PRIVATE_AIDL_FLAGS) $< $@
+endef
+#$(AIDL) $(PRIVATE_AIDL_FLAGS) $< - | indent -nut -br -npcs -l1000 > $@
+
+
+
+###########################################################
+## Commands for running gcc to compile a C++ file
+###########################################################
+
+define transform-cpp-to-o
+@mkdir -p $(dir $@)
+@echo "target $(PRIVATE_ARM_MODE) C++: $(PRIVATE_MODULE) <= $<"
+$(hide) $(PRIVATE_CXX) \
+ $(foreach incdir, \
+ $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
+ $(TARGET_PROJECT_INCLUDES) \
+ $(TARGET_C_INCLUDES) \
+ ) \
+ $(PRIVATE_C_INCLUDES) \
+ , \
+ -I $(incdir) \
+ ) \
+ -c \
+ $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
+ $(TARGET_GLOBAL_CFLAGS) \
+ $(TARGET_GLOBAL_CPPFLAGS) \
+ $(PRIVATE_ARM_CFLAGS) \
+ ) \
+ -fno-rtti \
+ $(PRIVATE_CFLAGS) \
+ $(PRIVATE_CPPFLAGS) \
+ $(PRIVATE_DEBUG_CFLAGS) \
+ -MD -o $@ $<
+$(hide) $(transform-d-to-p)
+endef
+
+
+###########################################################
+## Commands for running gcc to compile a C file
+###########################################################
+
+# $(1): extra flags
+define transform-c-or-s-to-o-no-deps
+@mkdir -p $(dir $@)
+$(hide) $(PRIVATE_CC) \
+ $(foreach incdir, \
+ $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
+ $(TARGET_PROJECT_INCLUDES) \
+ $(TARGET_C_INCLUDES) \
+ ) \
+ $(PRIVATE_C_INCLUDES) \
+ , \
+ -I $(incdir) \
+ ) \
+ -c \
+ $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
+ $(TARGET_GLOBAL_CFLAGS) \
+ $(PRIVATE_ARM_CFLAGS) \
+ ) \
+ $(PRIVATE_CFLAGS) \
+ $(1) \
+ $(PRIVATE_DEBUG_CFLAGS) \
+ -MD -o $@ $<
+endef
+
+define transform-c-to-o-no-deps
+@echo "target $(PRIVATE_ARM_MODE) C: $(PRIVATE_MODULE) <= $<"
+$(call transform-c-or-s-to-o-no-deps, )
+endef
+
+define transform-s-to-o-no-deps
+@echo "target asm: $(PRIVATE_MODULE) <= $<"
+$(call transform-c-or-s-to-o-no-deps, $(PRIVATE_ASFLAGS))
+endef
+
+define transform-c-to-o
+$(transform-c-to-o-no-deps)
+$(hide) $(transform-d-to-p)
+endef
+
+define transform-s-to-o
+$(transform-s-to-o-no-deps)
+$(hide) $(transform-d-to-p)
+endef
+
+###########################################################
+## Commands for running gcc to compile a host C++ file
+###########################################################
+
+define transform-host-cpp-to-o
+@mkdir -p $(dir $@)
+@echo "host C++: $(PRIVATE_MODULE) <= $<"
+$(hide) $(PRIVATE_CXX) \
+ $(foreach incdir, \
+ $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
+ $(HOST_PROJECT_INCLUDES) \
+ $(HOST_C_INCLUDES) \
+ ) \
+ $(PRIVATE_C_INCLUDES) \
+ , \
+ -I $(incdir) \
+ ) \
+ -c \
+ $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
+ $(HOST_GLOBAL_CFLAGS) \
+ $(HOST_GLOBAL_CPPFLAGS) \
+ ) \
+ $(PRIVATE_CFLAGS) \
+ $(PRIVATE_CPPFLAGS) \
+ $(PRIVATE_DEBUG_CFLAGS) \
+ -MD -o $@ $<
+$(transform-d-to-p)
+endef
+
+
+###########################################################
+## Commands for running gcc to compile a host C file
+###########################################################
+
+# $(1): extra flags
+define transform-host-c-or-s-to-o-no-deps
+@mkdir -p $(dir $@)
+$(hide) $(PRIVATE_CC) \
+ $(foreach incdir, \
+ $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
+ $(HOST_PROJECT_INCLUDES) \
+ $(HOST_C_INCLUDES) \
+ ) \
+ $(PRIVATE_C_INCLUDES) \
+ , \
+ -I $(incdir) \
+ ) \
+ -c \
+ $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
+ $(HOST_GLOBAL_CFLAGS) \
+ ) \
+ $(PRIVATE_CFLAGS) \
+ $(1) \
+ $(PRIVATE_DEBUG_CFLAGS) \
+ -MD -o $@ $<
+endef
+
+define transform-host-c-to-o-no-deps
+@echo "host C: $(PRIVATE_MODULE) <= $<"
+$(call transform-host-c-or-s-to-o-no-deps, )
+endef
+
+define transform-host-s-to-o-no-deps
+@echo "host asm: $(PRIVATE_MODULE) <= $<"
+$(call transform-host-c-or-s-to-o-no-deps, $(PRIVATE_ASFLAGS))
+endef
+
+define transform-host-c-to-o
+$(transform-host-c-to-o-no-deps)
+$(transform-d-to-p)
+endef
+
+define transform-host-s-to-o
+$(transform-host-s-to-o-no-deps)
+$(transform-d-to-p)
+endef
+
+###########################################################
+## Commands for running ar
+###########################################################
+
+# Explicitly delete the archive first so that ar doesn't
+# try to add to an existing archive.
+define transform-o-to-static-lib
+@mkdir -p $(dir $@)
+@echo "target StaticLib: $(PRIVATE_MODULE) ($@)"
+@rm -f $@
+$(hide) $(TARGET_AR) $(TARGET_GLOBAL_ARFLAGS) $(PRIVATE_ARFLAGS) $@ $^
+endef
+
+###########################################################
+## Commands for running host ar
+###########################################################
+
+# Explicitly delete the archive first so that ar doesn't
+# try to add to an existing archive.
+define transform-host-o-to-static-lib
+@mkdir -p $(dir $@)
+@echo "host StaticLib: $(PRIVATE_MODULE) ($@)"
+@rm -f $@
+$(HOST_AR) $(HOST_GLOBAL_ARFLAGS) $(PRIVATE_ARFLAGS) $@ $^
+endef
+
+
+###########################################################
+## Commands for running gcc to link a shared library or package
+###########################################################
+
+# ld just seems to be so finicky with command order that we allow
+# it to be overriden en-masse see combo/linux-arm.make for an example.
+ifneq ($(HOST_CUSTOM_LD_COMMAND),true)
+define transform-host-o-to-shared-lib-inner
+$(HOST_CXX) \
+ -Wl,-rpath-link=$(TARGET_OUT_INTERMEDIATE_LIBRARIES) \
+ -Wl,-rpath,\$$ORIGIN/../lib \
+ -shared -Wl,-soname,$(notdir $@) \
+ $(PRIVATE_LDFLAGS) \
+ $(HOST_GLOBAL_LD_DIRS) \
+ $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
+ $(HOST_GLOBAL_LDFLAGS) \
+ ) \
+ $(PRIVATE_ALL_OBJECTS) \
+ -Wl,--whole-archive \
+ $(call normalize-host-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ -Wl,--no-whole-archive \
+ $(call normalize-host-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(call normalize-host-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+ -o $@ \
+ $(PRIVATE_LDLIBS)
+endef
+endif
+
+define transform-host-o-to-shared-lib
+@mkdir -p $(dir $@)
+@echo "host SharedLib: $(PRIVATE_MODULE) ($@)"
+$(hide) $(transform-host-o-to-shared-lib-inner)
+endef
+
+define transform-host-o-to-package
+@mkdir -p $(dir $@)
+@echo "host Package: $(PRIVATE_MODULE) ($@)"
+$(hide) $(transform-host-o-to-shared-lib-inner)
+endef
+
+
+###########################################################
+## Commands for running gcc to link a shared library or package
+###########################################################
+
+#echo >$@.vers "{"; \
+#echo >>$@.vers " global:"; \
+#$(BUILD_SYSTEM)/filter_symbols.sh $(TARGET_NM) " " ";" $(filter %.o,$^) | sort -u >>$@.vers; \
+#echo >>$@.vers " local:"; \
+#echo >>$@.vers " *;"; \
+#echo >>$@.vers "};"; \
+
+# -Wl,--version-script=$@.vers \
+
+# ld just seems to be so finicky with command order that we allow
+# it to be overriden en-masse see combo/linux-arm.make for an example.
+ifneq ($(TARGET_CUSTOM_LD_COMMAND),true)
+define transform-o-to-shared-lib-inner
+$(TARGET_CXX) \
+ $(TARGET_GLOBAL_LDFLAGS) \
+ -Wl,-rpath-link=$(TARGET_OUT_INTERMEDIATE_LIBRARIES) \
+ -Wl,-rpath,\$$ORIGIN/../lib \
+ -shared -Wl,-soname,$(notdir $@) \
+ $(PRIVATE_LDFLAGS) \
+ $(TARGET_GLOBAL_LD_DIRS) \
+ $(PRIVATE_ALL_OBJECTS) \
+ -Wl,--whole-archive \
+ $(call normalize-host-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ -Wl,--no-whole-archive \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+ -o $@ \
+ $(PRIVATE_LDLIBS)
+endef
+endif
+
+define transform-o-to-shared-lib
+@mkdir -p $(dir $@)
+@echo "target SharedLib: $(PRIVATE_MODULE) ($@)"
+$(hide) $(transform-o-to-shared-lib-inner)
+endef
+
+define transform-o-to-package
+@mkdir -p $(dir $@)
+@echo "target Package: $(PRIVATE_MODULE) ($@)"
+$(hide) $(transform-o-to-shared-lib-inner)
+endef
+
+
+###########################################################
+## Commands for filtering a target executable or library
+###########################################################
+
+# Because of bug 743462 ("Prelinked image magic gets stripped
+# by arm-elf-objcopy"), we have to use soslim to strip target
+# binaries.
+define transform-to-stripped
+@mkdir -p $(dir $@)
+@echo "target Strip: $(PRIVATE_MODULE) ($@)"
+$(hide) $(SOSLIM) --strip --shady --quiet $< --outfile $@
+endef
+
+define transform-to-prelinked
+@mkdir -p $(dir $@)
+@echo "target Prelink: $(PRIVATE_MODULE) ($@)"
+$(hide) $(APRIORI) \
+ --prelinkmap $(TARGET_PRELINKER_MAP) \
+ --locals-only \
+ --quiet \
+ $< \
+ --output $@
+endef
+
+
+###########################################################
+## Commands for running gcc to link an executable
+###########################################################
+
+ifneq ($(TARGET_CUSTOM_LD_COMMAND),true)
+define transform-o-to-executable-inner
+$(TARGET_CXX) \
+ $(TARGET_GLOBAL_LDFLAGS) \
+ -Wl,-rpath-link=$(TARGET_OUT_INTERMEDIATE_LIBRARIES) \
+ $(TARGET_GLOBAL_LD_DIRS) \
+ -Wl,-rpath-link=$(TARGET_OUT_INTERMEDIATE_LIBRARIES) \
+ -Wl,-rpath,\$$ORIGIN/../lib \
+ $(PRIVATE_LDFLAGS) \
+ $(TARGET_GLOBAL_LD_DIRS) \
+ $(PRIVATE_ALL_OBJECTS) \
+ -Wl,--whole-archive \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ -Wl,--no-whole-archive \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+ -o $@ \
+ $(PRIVATE_LDLIBS)
+endef
+endif
+
+define transform-o-to-executable
+@mkdir -p $(dir $@)
+@echo "target Executable: $(PRIVATE_MODULE) ($@)"
+$(hide) $(transform-o-to-executable-inner)
+endef
+
+
+###########################################################
+## Commands for running gcc to link a statically linked
+## executable. In practice, we only use this on arm, so
+## the other platforms don't have the
+## transform-o-to-static-executable defined
+###########################################################
+
+ifneq ($(TARGET_CUSTOM_LD_COMMAND),true)
+define transform-o-to-static-executable-inner
+endef
+endif
+
+define transform-o-to-static-executable
+@mkdir -p $(dir $@)
+@echo "target StaticExecutable: $(PRIVATE_MODULE) ($@)"
+$(hide) $(transform-o-to-static-executable-inner)
+endef
+
+
+###########################################################
+## Commands for running gcc to link a host executable
+###########################################################
+
+ifneq ($(HOST_CUSTOM_LD_COMMAND),true)
+define transform-host-o-to-executable-inner
+$(HOST_CXX) \
+ -Wl,-rpath-link=$(TARGET_OUT_INTERMEDIATE_LIBRARIES) \
+ -Wl,-rpath,\$$ORIGIN/../lib \
+ $(HOST_GLOBAL_LD_DIRS) \
+ $(PRIVATE_LDFLAGS) \
+ $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
+ $(HOST_GLOBAL_LDFLAGS) \
+ ) \
+ $(PRIVATE_ALL_OBJECTS) \
+ -Wl,--whole-archive \
+ $(call normalize-host-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ -Wl,--no-whole-archive \
+ $(call normalize-host-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(call normalize-host-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+ -o $@ \
+ $(PRIVATE_LDLIBS)
+endef
+endif
+
+define transform-host-o-to-executable
+@mkdir -p $(dir $@)
+@echo "host Executable: $(PRIVATE_MODULE) ($@)"
+$(hide) $(transform-host-o-to-executable-inner)
+endef
+
+
+###########################################################
+## Commands for running javac to make .class files
+###########################################################
+
+#@echo "Source intermediates dir: $(PRIVATE_SOURCE_INTERMEDIATES_DIR)"
+#@echo "Source intermediates: $$(find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name '*.java')"
+
+# TODO: Right now we generate the asset resources twice, first as part
+# of generating the Java classes, then at the end when packaging the final
+# assets. This should be changed to do one of two things: (1) Don't generate
+# any resource files the first time, only create classes during that stage;
+# or (2) Don't use the -c flag with the second stage, instead taking the
+# resource files from the first stage as additional input. My original intent
+# was to use approach (2), but this requires a little more work in the tool.
+# Maybe we should just use approach (1).
+
+# This rule creates the R.java and Manifest.java files, both of which
+# are PRODUCT-neutral. Don't pass PRODUCT_AAPT_CONFIG to this invocation.
+define create-resource-java-files
+@mkdir -p $(PRIVATE_SOURCE_INTERMEDIATES_DIR)
+@mkdir -p $(dir $(PRIVATE_RESOURCE_PUBLICS_OUTPUT))
+$(hide) $(AAPT) package $(PRIVATE_AAPT_FLAGS) -m -z \
+ $(eval # PRODUCT_AAPT_CONFIG is intentionally missing-- see comment.) \
+ $(addprefix -J , $(PRIVATE_SOURCE_INTERMEDIATES_DIR)) \
+ $(addprefix -M , $(PRIVATE_ANDROID_MANIFEST)) \
+ $(addprefix -P , $(PRIVATE_RESOURCE_PUBLICS_OUTPUT)) \
+ $(addprefix -S , $(PRIVATE_RESOURCE_DIR)) \
+ $(addprefix -A , $(PRIVATE_ASSET_DIR)) \
+ $(addprefix -I , $(PRIVATE_AAPT_INCLUDES))
+endef
+
+ifeq ($(HOST_OS),windows)
+xlint_unchecked :=
+else
+#xlint_unchecked := -Xlint:unchecked
+endif
+
+# emit-line, <word list>, <output file>
+define emit-line
+ $(if $(1),echo -n '$(strip $(1)) ' >> $(2))
+endef
+
+# dump-words-to-file, <word list>, <output file>
+define dump-words-to-file
+ @rm -f $(2)
+ @$(call emit-line,$(wordlist 1,200,$(1)),$(2))
+ @$(call emit-line,$(wordlist 201,400,$(1)),$(2))
+ @$(call emit-line,$(wordlist 401,600,$(1)),$(2))
+ @$(call emit-line,$(wordlist 601,800,$(1)),$(2))
+ @$(call emit-line,$(wordlist 801,1000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 1001,1200,$(1)),$(2))
+ @$(call emit-line,$(wordlist 1201,1400,$(1)),$(2))
+ @$(call emit-line,$(wordlist 1401,1600,$(1)),$(2))
+ @$(call emit-line,$(wordlist 1601,1800,$(1)),$(2))
+ @$(call emit-line,$(wordlist 1801,2000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 2001,2200,$(1)),$(2))
+ @$(call emit-line,$(wordlist 2201,2400,$(1)),$(2))
+ @$(call emit-line,$(wordlist 2401,2600,$(1)),$(2))
+ @$(call emit-line,$(wordlist 2601,2800,$(1)),$(2))
+ @$(call emit-line,$(wordlist 2801,3000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 3001,3200,$(1)),$(2))
+ @$(call emit-line,$(wordlist 3201,3400,$(1)),$(2))
+ @$(call emit-line,$(wordlist 3401,3600,$(1)),$(2))
+ @$(call emit-line,$(wordlist 3601,3800,$(1)),$(2))
+ @$(call emit-line,$(wordlist 3801,4000,$(1)),$(2))
+ @$(if $(wordlist 4001,4002,$(1)),$(error Too many words ($(words $(1)))))
+endef
+
+# For a list of jar files, unzip them to a specified directory,
+# but make sure that no META-INF files come along for the ride.
+#
+# $(1): files to unzip
+# $(2): destination directory
+define unzip-jar-files
+ $(hide) for f in $(1); \
+ do \
+ if [ ! -f $$f ]; then \
+ echo Missing file $$f; \
+ exit 1; \
+ fi; \
+ unzip -q $$f -d $(2); \
+ (cd $(2) && rm -rf META-INF); \
+ done
+endef
+
+# below we write the list of java files to java-source-list to avoid argument list length problems with Cygwin
+# we filter out duplicate java file names because eclipse's compiler doesn't like them.
+define transform-java-to-classes.jar
+@echo "target Java: $(PRIVATE_MODULE) ($(PRIVATE_CLASS_INTERMEDIATES_DIR))"
+@rm -f $@
+@rm -rf $(PRIVATE_CLASS_INTERMEDIATES_DIR)
+@mkdir -p $(PRIVATE_CLASS_INTERMEDIATES_DIR)
+$(call unzip-jar-files,$(PRIVATE_STATIC_JAVA_LIBRARIES), \
+ $(PRIVATE_CLASS_INTERMEDIATES_DIR))
+$(call dump-words-to-file,$(PRIVATE_JAVA_SOURCES),$(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list)
+@if [ -d "$(PRIVATE_SOURCE_INTERMEDIATES_DIR)" ]; then \
+ find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list; \
+fi
+$(hide) tr ' ' '\n' < $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list \
+ | sort -u > $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list-uniq
+$(hide) $(TARGET_JAVAC) -encoding ascii $(PRIVATE_BOOTCLASSPATH) \
+ $(addprefix -classpath ,$(strip \
+ $(call normalize-path-list,$(PRIVATE_ALL_JAVA_LIBRARIES)))) \
+ $(strip $(PRIVATE_JAVAC_DEBUG_FLAGS)) $(xlint_unchecked) \
+ -extdirs "" -d $(PRIVATE_CLASS_INTERMEDIATES_DIR) \
+ \@$(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list-uniq \
+ || ( rm -rf $(PRIVATE_CLASS_INTERMEDIATES_DIR) ; exit 41 )
+@ rm -f $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list
+@ rm -f $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list-uniq
+@mkdir -p $(dir $@)
+$(hide) jar $(if $(strip $(PRIVATE_JAR_MANIFEST)),-cfm,-cf) \
+ $@ $(PRIVATE_JAR_MANIFEST) -C $(PRIVATE_CLASS_INTERMEDIATES_DIR) .
+@rm -rf $(PRIVATE_CLASS_INTERMEDIATES_DIR)
+endef
+
+define transform-classes.jar-to-emma
+$(hide) java -classpath $(EMMA_JAR) emma instr -outmode fullcopy -outfile \
+ $(PRIVATE_EMMA_COVERAGE_FILE) -ip $< -d $(PRIVATE_EMMA_INTERMEDIATES_DIR)
+endef
+
+#TODO: use a smaller -Xmx value for most libraries;
+# only core.jar and framework.jar need a heap this big.
+define transform-classes.jar-to-dex
+@echo "target Dex: $(PRIVATE_MODULE)"
+@mkdir -p $(dir $@)
+$(hide) $(DX) -JXms16M \
+ -JXmx1536M \
+ --dex --output=$@ \
+ $(if $(NO_OPTIMIZE_DX), \
+ --no-optimize) \
+ $(if $(GENERATE_DEX_DEBUG), \
+ --debug --verbose \
+ --dump-to=$(@:.dex=.lst) \
+ --dump-width=1000) \
+ $(PRIVATE_DX_FLAGS) \
+ $<
+endef
+
+# Create a mostly-empty .jar file that we'll add to later.
+# The MacOS jar tool doesn't like creating empty jar files,
+# so we need to give it something.
+define create-empty-package
+@mkdir -p $(dir $@)
+$(hide) touch $(dir $@)/dummy
+$(hide) (cd $(dir $@) && jar cf $(notdir $@) dummy)
+$(hide) zip -qd $@ dummy
+$(hide) rm $(dir $@)/dummy
+endef
+
+#TODO: we kinda want to build different asset packages for
+# different configurations, then combine them later (or something).
+# Per-locale, etc.
+# A list of dynamic and static parameters; build layers for
+# dynamic params that lay over the static ones.
+#TODO: update the manifest to point to the package file
+define add-assets-to-package
+$(hide) $(AAPT) package -z -u $(PRIVATE_AAPT_FLAGS) \
+ $(addprefix -c , $(PRODUCT_AAPT_CONFIG)) \
+ $(addprefix -M , $(PRIVATE_ANDROID_MANIFEST)) \
+ $(addprefix -S , $(PRIVATE_RESOURCE_DIR)) \
+ $(addprefix -A , $(PRIVATE_ASSET_DIR)) \
+ $(addprefix -I , $(PRIVATE_AAPT_INCLUDES)) \
+ -F $@
+endef
+
+#TODO: Allow library directory to be specified based on the target
+# CPU and ABI instead of being hard coded as armeabi.
+define add-jni-shared-libs-to-package
+$(hide) rm -rf $(dir $@)lib
+$(hide) mkdir -p $(dir $@)lib/armeabi
+$(hide) cp $(PRIVATE_JNI_SHARED_LIBRARIES) $(dir $@)lib/armeabi
+$(hide) (cd $(dir $@) && zip -r $(notdir $@) lib)
+$(hide) rm -rf $(dir $@)lib
+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
+define add-dex-to-package
+$(hide) zip -qj $@ $(PRIVATE_DEX_FILE)
+endef
+
+define add-java-resources-to-package
+$(hide) jar uf $@ $(PRIVATE_EXTRA_JAR_ARGS)
+endef
+
+# Sign a package using the specified key/cert.
+#
+define sign-package
+$(hide) mv $@ $@.unsigned
+$(hide) java -jar $(SIGNAPK_JAR) \
+ $(PRIVATE_CERTIFICATE) $(PRIVATE_PRIVATE_KEY) $@.unsigned $@.signed
+$(hide) mv $@.signed $@
+endef
+
+# Align STORED entries of a package on 4-byte boundaries
+# to make them easier to mmap.
+#
+define align-package
+$(hide) mv $@ $@.unaligned
+$(hide) $(ZIPALIGN) -f 4 $@.unaligned $@.aligned
+$(hide) mv $@.aligned $@
+endef
+
+define install-dex-debug
+$(hide) if [ -f "$(PRIVATE_INTERMEDIATES_DIR)/classes.dex" ]; then \
+ mkdir -p $(TOP)/dalvik/DEBUG-FILES; \
+ $(ACP) $(PRIVATE_INTERMEDIATES_DIR)/classes.dex \
+ $(TOP)/dalvik/DEBUG-FILES/$(PRIVATE_MODULE).dex; \
+ fi
+$(hide) if [ -f "$(PRIVATE_INTERMEDIATES_DIR)/classes.lst" ]; then \
+ mkdir -p $(TOP)/dalvik/DEBUG-FILES; \
+ $(ACP) $(PRIVATE_INTERMEDIATES_DIR)/classes.lst \
+ $(TOP)/dalvik/DEBUG-FILES/$(PRIVATE_MODULE).lst; \
+ fi
+endef
+
+# TODO(joeo): If we can ever upgrade to post 3.81 make and get the
+# new prebuilt rules to work, we should change this to copy the
+# resources to the out directory and then copy the resources.
+
+# Note: not using aapt tool for this because we aren't making
+# an android package for the host.
+define transform-host-java-to-package
+@echo "host Java: $(PRIVATE_MODULE) ($(PRIVATE_CLASS_INTERMEDIATES_DIR))"
+@rm -f $@
+@rm -rf $(PRIVATE_CLASS_INTERMEDIATES_DIR)
+@mkdir -p $(dir $@)
+@mkdir -p $(PRIVATE_CLASS_INTERMEDIATES_DIR)
+$(call unzip-jar-files,$(PRIVATE_STATIC_JAVA_LIBRARIES), \
+ $(PRIVATE_CLASS_INTERMEDIATES_DIR))
+$(call dump-words-to-file,$(sort\
+ $(PRIVATE_JAVA_SOURCES)),\
+ $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list-uniq)
+$(hide) $(HOST_JAVAC) -encoding ascii -g \
+ $(xlint_unchecked) \
+ $(addprefix -classpath ,$(strip \
+ $(call normalize-path-list,$(PRIVATE_ALL_JAVA_LIBRARIES)))) \
+ -extdirs "" -d $(PRIVATE_CLASS_INTERMEDIATES_DIR)\
+ \@$(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list-uniq || \
+ ( rm -rf $(PRIVATE_CLASS_INTERMEDIATES_DIR) ; exit 41 )
+$(hide) jar $(if $(strip $(PRIVATE_JAR_MANIFEST)),-cfm,-cf) \
+ $@ $(PRIVATE_JAR_MANIFEST) $(PRIVATE_EXTRA_JAR_ARGS) \
+ -C $(PRIVATE_CLASS_INTERMEDIATES_DIR) .
+endef
+
+###########################################################
+## Obfuscate a jar file
+###########################################################
+
+# PRIVATE_KEEP_FILE is a file containing a list of classes
+# PRIVATE_INTERMEDIATES_DIR is a directory we can use for temporary files
+# The module using this must depend on
+# $(HOST_OUT_JAVA_LIBRARIES)/proguard-4.0.1.jar
+define obfuscate-jar
+@echo "Obfuscate jar: $(notdir $@) ($@)"
+@mkdir -p $(dir $@)
+@rm -f $@
+@mkdir -p $(PRIVATE_INTERMEDIATES_DIR)
+$(hide) sed -e 's/^/-keep class /' < $(PRIVATE_KEEP_FILE) > \
+ $(PRIVATE_INTERMEDIATES_DIR)/keep.pro
+$(hide) java -Xmx512M -jar $(HOST_OUT_JAVA_LIBRARIES)/proguard-4.0.1.jar \
+ -injars $< \
+ -outjars $@ \
+ -target 1.5 \
+ -dontnote -dontwarn \
+ -printmapping $(PRIVATE_INTERMEDIATES_DIR)/out.map \
+ -forceprocessing \
+ -renamesourcefileattribute SourceFile \
+ -keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod \
+ -repackageclasses \
+ -keepclassmembers "class * { public protected *; }" \
+ @$(PRIVATE_INTERMEDIATES_DIR)/keep.pro
+endef
+
+###########################################################
+## Commands for copying files
+###########################################################
+
+# Define a rule to copy a header. Used via $(eval) by copy_headers.make.
+# $(1): source header
+# $(2): destination header
+define copy-one-header
+$(2): $(1)
+ @echo "Header: $$@"
+ $$(copy-file-to-new-target-with-cp)
+endef
+
+# Define a rule to copy a file. For use via $(eval).
+# $(1): source file
+# $(2): destination file
+define copy-one-file
+$(2): $(1) | $(ACP)
+ @echo "Copy: $$@"
+ $$(copy-file-to-target)
+endef
+
+# The -t option to acp and the -p option to cp is
+# required for OSX. OSX has a ridiculous restriction
+# where it's an error for a .a file's modification time
+# to disagree with an internal timestamp, and this
+# macro is used to install .a files (among other things).
+
+# Copy a single file from one place to another,
+# preserving permissions and overwriting any existing
+# file.
+define copy-file-to-target
+@mkdir -p $(dir $@)
+$(hide) $(ACP) -fpt $< $@
+endef
+
+# The same as copy-file-to-target, but use the local
+# cp command instead of acp.
+define copy-file-to-target-with-cp
+@mkdir -p $(dir $@)
+$(hide) cp -fp $< $@
+endef
+
+# The same as copy-file-to-target, but don't preserve
+# the old modification time.
+define copy-file-to-new-target
+@mkdir -p $(dir $@)
+$(hide) $(ACP) -fp $< $@
+endef
+
+# The same as copy-file-to-new-target, but use the local
+# cp command instead of acp.
+define copy-file-to-new-target-with-cp
+@mkdir -p $(dir $@)
+$(hide) cp -f $< $@
+endef
+
+# Copy a prebuilt file to a target location.
+define transform-prebuilt-to-target
+@echo "$(if $(PRIVATE_IS_HOST_MODULE),host,target) Prebuilt: $(PRIVATE_MODULE) ($@)"
+$(copy-file-to-target)
+endef
+
+
+###########################################################
+## On some platforms (MacOS), after copying a static
+## library, ranlib must be run to update an internal
+## timestamp!?!?!
+###########################################################
+
+ifeq ($(HOST_RUN_RANLIB_AFTER_COPYING),true)
+define transform-host-ranlib-copy-hack
+ $(hide) ranlib $@ || true
+endef
+else
+define transform-host-ranlib-copy-hack
+true
+endef
+endif
+
+ifeq ($(TARGET_RUN_RANLIB_AFTER_COPYING),true)
+define transform-ranlib-copy-hack
+ $(hide) ranlib $@
+endef
+else
+define transform-ranlib-copy-hack
+true
+endef
+endif
+
+
+###########################################################
+## Stuff source generated from one-off tools
+###########################################################
+
+define transform-generated-source
+@echo "target Generated: $(PRIVATE_MODULE) <= $<"
+@mkdir -p $(dir $@)
+$(hide) $(PRIVATE_CUSTOM_TOOL)
+endef
+
+
+###########################################################
+## Assertions about attributes of the target
+###########################################################
+
+# $(1): The file to check
+ifndef get-file-size
+$(error HOST_OS must define get-file-size)
+endif
+
+# $(1): The file to check (often $@)
+# $(2): The maximum size, in decimal bytes
+#
+# If $(2) is empty, evaluates to "true"
+#
+# Reserve bad blocks. Make sure that MAX(1% of partition size, 2 blocks)
+# is left over after the image has been flashed. Round the 1% up to the
+# next whole flash block size.
+define assert-max-file-size
+$(if $(2), \
+ fileSize=`$(call get-file-size,$(1))`; \
+ maxSize=$(2); \
+ onePct=`expr "(" $$maxSize + 99 ")" / 100`; \
+ onePct=`expr "(" "(" $$onePct + $(BOARD_FLASH_BLOCK_SIZE) - 1 ")" / \
+ $(BOARD_FLASH_BLOCK_SIZE) ")" "*" $(BOARD_FLASH_BLOCK_SIZE)`; \
+ reserve=`expr 2 "*" $(BOARD_FLASH_BLOCK_SIZE)`; \
+ if [ "$$onePct" -gt "$$reserve" ]; then \
+ reserve="$$onePct"; \
+ fi; \
+ maxSize=`expr $$maxSize - $$reserve`; \
+ if [ "$$fileSize" -gt "$$maxSize" ]; then \
+ echo "error: $(1) too large ($$fileSize > [$(2) - $$reserve])"; \
+ false; \
+ fi \
+ , \
+ true \
+ )
+endef
+
+###########################################################
+## Other includes
+###########################################################
+
+# -----------------------------------------------------------------
+# Rules and functions to help copy important files to DIST_DIR
+# when requested.
+include $(BUILD_SYSTEM)/distdir.mk
+
+
+# broken:
+# $(foreach file,$^,$(if $(findstring,.a,$(suffix $file)),-l$(file),$(file)))
+
+###########################################################
+## Misc notes
+###########################################################
+
+#DEPDIR = .deps
+#df = $(DEPDIR)/$(*F)
+
+#SRCS = foo.c bar.c ...
+
+#%.o : %.c
+# @$(MAKEDEPEND); \
+# cp $(df).d $(df).P; \
+# sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
+# -e '/^$$/ d' -e 's/$$/ :/' < $(df).d >> $(df).P; \
+# rm -f $(df).d
+# $(COMPILE.c) -o $@ $<
+
+#-include $(SRCS:%.c=$(DEPDIR)/%.P)
+
+
+#%.o : %.c
+# $(COMPILE.c) -MD -o $@ $<
+# @cp $*.d $*.P; \
+# sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
+# -e '/^$$/ d' -e 's/$$/ :/' < $*.d >> $*.P; \
+# rm -f $*.d
diff --git a/core/device.mk b/core/device.mk
new file mode 100644
index 0000000..20ff447
--- /dev/null
+++ b/core/device.mk
@@ -0,0 +1,76 @@
+#
+# Copyright (C) 2007 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.
+#
+
+_device_var_list := \
+ DEVICE_NAME \
+ DEVICE_BOARD \
+ DEVICE_REGION
+
+define dump-device
+$(info ==== $(1) ====)\
+$(foreach v,$(_device_var_list),\
+$(info DEVICES.$(1).$(v) := $(DEVICES.$(1).$(v))))\
+$(info --------)
+endef
+
+define dump-devices
+$(foreach p,$(DEVICES),$(call dump-device,$(p)))
+endef
+
+#
+# $(1): device to inherit
+#
+define inherit-device
+ $(foreach v,$(_device_var_list), \
+ $(eval $(v) := $($(v)) $(INHERIT_TAG)$(strip $(1))))
+endef
+
+#
+# $(1): device makefile list
+#
+#TODO: check to make sure that devices have all the necessary vars defined
+define import-devices
+$(call import-nodes,DEVICES,$(1),$(_device_var_list))
+endef
+
+
+#
+# $(1): short device name like "sooner"
+#
+define _resolve-short-device-name
+ $(eval dn := $(strip $(1)))
+ $(eval d := \
+ $(foreach d,$(DEVICES), \
+ $(if $(filter $(dn),$(DEVICES.$(d).DEVICE_NAME)), \
+ $(d) \
+ )) \
+ )
+ $(eval d := $(sort $(d)))
+ $(if $(filter 1,$(words $(d))), \
+ $(d), \
+ $(if $(filter 0,$(words $(d))), \
+ $(error No matches for device "$(dn)"), \
+ $(error Device "$(dn)" ambiguous: matches $(d)) \
+ ) \
+ )
+endef
+
+#
+# $(1): short device name like "sooner"
+#
+define resolve-short-device-name
+$(strip $(call _resolve-short-device-name,$(1)))
+endef
diff --git a/core/distdir.mk b/core/distdir.mk
new file mode 100644
index 0000000..e04938b
--- /dev/null
+++ b/core/distdir.mk
@@ -0,0 +1,75 @@
+#
+# Copyright (C) 2007 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.
+#
+
+# When specifying "dist", the user has asked that we copy the important
+# files from this build into DIST_DIR.
+
+.PHONY: dist
+dist: ;
+
+dist_goal := $(strip $(filter dist,$(MAKECMDGOALS)))
+MAKECMDGOALS := $(strip $(filter-out dist,$(MAKECMDGOALS)))
+ifeq (,$(strip $(filter-out $(INTERNAL_MODIFIER_TARGETS),$(MAKECMDGOALS))))
+# The commandline was something like "make dist" or "make dist showcommands".
+# Add a dependency on a real target.
+dist: $(DEFAULT_GOAL)
+endif
+
+ifdef dist_goal
+
+# $(1): source file
+# $(2): destination file
+# $(3): goals that should copy the file
+#
+define copy-one-dist-file
+$(3): $(2)
+$(2): $(1)
+ @echo "Dist: $$@"
+ $$(copy-file-to-new-target-with-cp)
+endef
+
+# Other parts of the system should use this function to associate
+# certain files with certain goals. When those goals are built
+# and "dist" is specified, the marked files will be copied to DIST_DIR.
+#
+# $(1): a list of goals (e.g. droid, sdk, pdk, ndk)
+# $(2): the dist files to add to those goals. If the file contains ':',
+# the text following the colon is the name that the file is copied
+# to under the dist directory. Subdirs are ok, and will be created
+# at copy time if necessary.
+define dist-for-goals
+$(foreach file,$(2), \
+ $(eval fw := $(subst :,$(space),$(file))) \
+ $(eval src := $(word 1,$(fw))) \
+ $(eval dst := $(word 2,$(fw))) \
+ $(eval dst := $(if $(dst),$(dst),$(notdir $(src)))) \
+ $(eval \
+ $(call copy-one-dist-file, \
+ $(src), \
+ $(DIST_DIR)/$(dst), \
+ $(1) \
+ ) \
+ ) \
+ )
+endef
+
+else # !dist_goal
+
+# empty definition when not building dist
+define dist-for-goals
+endef
+
+endif # !dist_goal
diff --git a/core/droiddoc.mk b/core/droiddoc.mk
new file mode 100644
index 0000000..a279c82
--- /dev/null
+++ b/core/droiddoc.mk
@@ -0,0 +1,158 @@
+###########################################################
+## Standard rules for building documentation
+###########################################################
+
+LOCAL_IS_HOST_MODULE := $(strip $(LOCAL_IS_HOST_MODULE))
+ifdef LOCAL_IS_HOST_MODULE
+my_prefix:=HOST_
+else
+my_prefix:=TARGET_
+endif
+
+LOCAL_MODULE_CLASS := $(strip $(LOCAL_MODULE_CLASS))
+ifndef LOCAL_MODULE_CLASS
+$(error $(LOCAL_PATH): LOCAL_MODULE_CLASS not defined)
+endif
+
+full_src_files := $(patsubst %,$(LOCAL_PATH)/%,$(LOCAL_SRC_FILES))
+out_dir := $(OUT_DOCS)/$(LOCAL_MODULE)
+full_target := $(OUT_DOCS)/$(LOCAL_MODULE)-timestamp
+
+ifeq ($(LOCAL_DROIDDOC_SOURCE_PATH),)
+LOCAL_DROIDDOC_SOURCE_PATH := $(LOCAL_PATH)
+endif
+
+ifeq ($(LOCAL_DROIDDOC_TEMPLATE_DIR),)
+LOCAL_DROIDDOC_TEMPLATE_DIR := $(SRC_DROIDDOC_DIR)/templates
+endif
+ifeq ($(LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR),)
+LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR := $(SRC_DROIDDOC_DIR)/templates
+endif
+
+ifeq ($(LOCAL_DROIDDOC_ASSET_DIR),)
+LOCAL_DROIDDOC_ASSET_DIR := assets
+endif
+ifeq ($(LOCAL_DROIDDOC_CUSTOM_ASSET_DIR),)
+LOCAL_DROIDDOC_CUSTOM_ASSET_DIR := assets
+endif
+
+droiddoc_templates := \
+ $(shell find $(LOCAL_DROIDDOC_TEMPLATE_DIR) -type f) \
+ $(shell find $(LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR) -type f)
+
+droiddoc := \
+ $(HOST_JDK_TOOLS_JAR) \
+ $(HOST_OUT_JAVA_LIBRARIES)/droiddoc$(COMMON_JAVA_PACKAGE_SUFFIX) \
+ $(HOST_OUT_JAVA_LIBRARIES)/clearsilver$(COMMON_JAVA_PACKAGE_SUFFIX) \
+ $(HOST_OUT_SHARED_LIBRARIES)/libclearsilver-jni$(HOST_JNILIB_SUFFIX)
+
+intermediates := $(call local-intermediates-dir)
+
+$(full_target): PRIVATE_CLASSPATH:=$(LOCAL_CLASSPATH)
+full_java_lib_deps :=
+
+ifndef LOCAL_IS_HOST_MODULE
+
+ifeq ($(LOCAL_JAVA_LIBRARIES),)
+LOCAL_JAVA_LIBRARIES := core ext framework
+endif
+full_java_libs := $(call java-lib-files,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
+full_java_lib_deps := $(call java-lib-deps,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
+
+# we're not going to generate docs from any of these classes, but we need them
+# to build properly.
+ifneq ($(strip $(LOCAL_STATIC_JAVA_LIBRARIES)),)
+full_java_libs += $(addprefix $(LOCAL_PATH)/,$(LOCAL_STATIC_JAVA_LIBRARIES)) $(LOCAL_CLASSPATH)
+full_java_lib_deps += $(addprefix $(LOCAL_PATH)/,$(LOCAL_STATIC_JAVA_LIBRARIES)) $(LOCAL_CLASSPATH)
+endif
+
+empty :=
+space := $(empty) $(empty)
+$(full_target): PRIVATE_CLASSPATH := $(subst $(space),:,$(full_java_libs))
+
+endif # !LOCAL_IS_HOST_MODULE
+
+$(full_target): PRIVATE_DOCLETPATH := $(HOST_OUT_JAVA_LIBRARIES)/clearsilver$(COMMON_JAVA_PACKAGE_SUFFIX):$(HOST_OUT_JAVA_LIBRARIES)/droiddoc$(COMMON_JAVA_PACKAGE_SUFFIX)
+$(full_target): PRIVATE_JAVA_FILES := $(filter %.java,$(full_src_files))
+$(full_target): PRIVATE_JAVA_FILES += $(addprefix $($(my_prefix)OUT_COMMON_INTERMEDIATES)/, $(filter %.java,$(LOCAL_INTERMEDIATE_SOURCES)))
+$(full_target): PRIVATE_CURRENT_BUILD := -hdf page.build $(BUILD_ID)-$(BUILD_NUMBER)
+$(full_target): PRIVATE_CURRENT_TIME := -hdf page.now "$(shell date "+%d %b %Y %k:%M")"
+$(full_target): PRIVATE_OUT_DIR := $(out_dir)
+$(full_target): PRIVATE_DROIDDOC_OPTIONS := $(LOCAL_DROIDDOC_OPTIONS)
+$(full_target): PRIVATE_TEMPLATE_DIR := $(LOCAL_DROIDDOC_TEMPLATE_DIR)
+$(full_target): PRIVATE_CUSTOM_TEMPLATE_DIR := $(LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR)
+$(full_target): PRIVATE_IN_ASSET_DIR := $(LOCAL_DROIDDOC_TEMPLATE_DIR)/$(LOCAL_DROIDDOC_ASSET_DIR)
+$(full_target): PRIVATE_IN_CUSTOM_ASSET_DIR := $(LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR)/$(LOCAL_DROIDDOC_CUSTOM_ASSET_DIR)
+$(full_target): PRIVATE_OUT_ASSET_DIR := $(out_dir)/$(LOCAL_DROIDDOC_ASSET_DIR)
+$(full_target): PRIVATE_OUT_CUSTOM_ASSET_DIR := $(out_dir)/$(LOCAL_DROIDDOC_CUSTOM_ASSET_DIR)
+ifneq ($(strip $(LOCAL_DROIDDOC_HTML_DIR)),)
+$(full_target): PRIVATE_DROIDDOC_HTML_DIR := -htmldir $(LOCAL_PATH)/$(LOCAL_DROIDDOC_HTML_DIR)
+else
+$(full_target): PRIVATE_DROIDDOC_HTML_DIR :=
+endif
+$(full_target): PRIVATE_LOCAL_PATH := $(LOCAL_PATH)
+$(full_target): PRIVATE_SOURCE_PATH := $(call normalize-path-list,$(LOCAL_DROIDDOC_SOURCE_PATH))
+$(full_target): PRIVATE_SOURCE_INTERMEDIATES_DIR := $(intermediates)/src
+$(full_target): PRIVATE_SRC_LIST_FILE := $(intermediates)/droiddoc-src-list
+
+ifneq ($(strip $(LOCAL_ADDITIONAL_JAVA_DIR)),)
+$(full_target): PRIVATE_ADDITIONAL_JAVA_DIR := $(LOCAL_ADDITIONAL_JAVA_DIR)
+endif
+
+html_dir_files := $(shell find $(LOCAL_PATH)/$(LOCAL_DROIDDOC_HTML_DIR) -type f)
+
+ifeq (a,b)
+$(full_target): PRIVATE_PROFILING_OPTIONS := \
+ -J-agentlib:jprofilerti=port=8849 -J-Xbootclasspath/a:/Applications/jprofiler5/bin/agent.jar
+endif
+
+$(full_target): $(full_src_files) $(droiddoc_templates) $(droiddoc) $(html_dir_files) $(full_java_lib_deps)
+ @echo Docs droiddoc: $(PRIVATE_OUT_DIR)
+ @mkdir -p $(dir $(full_target))
+ @mkdir -p $(dir $(PRIVATE_SRC_LIST_FILE))
+ $(call dump-words-to-file, $(PRIVATE_JAVA_FILES), $(PRIVATE_SRC_LIST_FILE))
+ $(hide) find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $(PRIVATE_SRC_LIST_FILE) 2> /dev/null || true
+ $(hide) if [ "$(PRIVATE_ADDITIONAL_JAVA_DIR)" != "" ] ; then ( find $(PRIVATE_ADDITIONAL_JAVA_DIR) -name '*.java' >> $(PRIVATE_SRC_LIST_FILE) 2> /dev/null || true ) fi
+ $(hide) ( \
+ \
+ LD_LIBRARY_PATH=$(HOST_OUT_SHARED_LIBRARIES) \
+ javadoc \
+ \@$(PRIVATE_SRC_LIST_FILE) \
+ -J-Xmx768m \
+ -J-Djava.library.path=$(HOST_OUT_SHARED_LIBRARIES) \
+ $(PRIVATE_PROFILING_OPTIONS) \
+ -quiet \
+ -doclet DroidDoc \
+ -docletpath $(PRIVATE_DOCLETPATH) \
+ -templatedir $(PRIVATE_CUSTOM_TEMPLATE_DIR) \
+ -templatedir $(PRIVATE_TEMPLATE_DIR) \
+ $(PRIVATE_DROIDDOC_HTML_DIR) \
+ $(addprefix -classpath ,$(PRIVATE_CLASSPATH)) \
+ -sourcepath $(PRIVATE_SOURCE_PATH)$(addprefix :,$(PRIVATE_CLASSPATH)) \
+ -d $(PRIVATE_OUT_DIR) \
+ $(PRIVATE_CURRENT_BUILD) $(PRIVATE_CURRENT_TIME) \
+ $(PRIVATE_DROIDDOC_OPTIONS) \
+ && rm -rf $(PRIVATE_OUT_ASSET_DIR) \
+ && rm -rf $(PRIVATE_OUT_CUSTOM_ASSET_DIR) \
+ && mkdir -p $(PRIVATE_OUT_ASSET_DIR) \
+ && mkdir -p $(PRIVATE_OUT_CUSTOM_ASSET_DIR) \
+ && cp -fr $(PRIVATE_IN_ASSET_DIR)/* $(PRIVATE_OUT_ASSET_DIR)/ \
+ && cp -fr $(PRIVATE_IN_CUSTOM_ASSET_DIR)/* $(PRIVATE_OUT_CUSTOM_ASSET_DIR)/ \
+ && touch -f $@ \
+ ) || (rm -rf $(PRIVATE_OUT_DIR) $(PRIVATE_SRC_LIST_FILE); exit 45)
+
+ALL_DOCS += $(full_target)
+
+.PHONY: $(LOCAL_MODULE)-docs
+$(LOCAL_MODULE)-docs : $(full_target)
+
+# Define a rule to create a zip of these docs.
+out_zip := $(OUT_DOCS)/$(LOCAL_MODULE)-docs.zip
+$(out_zip): PRIVATE_DOCS_DIR := $(out_dir)
+$(out_zip): $(full_target)
+ @echo Package docs: $@
+ @rm -f $@
+ @mkdir -p $(dir $@)
+ $(hide) ( F=$$(pwd)/$@ ; cd $(PRIVATE_DOCS_DIR) && zip -rq $$F * )
+
+$(call dist-for-goals,docs,$(out_zip))
diff --git a/core/dynamic_binary.mk b/core/dynamic_binary.mk
new file mode 100644
index 0000000..10027b8
--- /dev/null
+++ b/core/dynamic_binary.mk
@@ -0,0 +1,144 @@
+###########################################################
+## Standard rules for building any target-side binaries
+## with dynamic linkage (dynamic libraries or executables
+## that link with dynamic libraries)
+##
+## Files including this file must define a rule to build
+## the target $(linked_module).
+###########################################################
+
+# This constraint means that we can hard-code any $(TARGET_*) variables.
+ifdef LOCAL_IS_HOST_MODULE
+$(error This file should not be used to build host binaries. Included by (or near) $(lastword $(filter-out config/%,$(MAKEFILE_LIST))))
+endif
+
+LOCAL_UNSTRIPPED_PATH := $(strip $(LOCAL_UNSTRIPPED_PATH))
+ifeq ($(LOCAL_UNSTRIPPED_PATH),)
+ LOCAL_UNSTRIPPED_PATH := $(TARGET_OUT_$(LOCAL_MODULE_CLASS)_UNSTRIPPED)
+endif
+
+# The name of the target file, without any path prepended.
+LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX)
+
+# base_rules.make defines $(intermediates), but we need its value
+# before we include base_rules. Make a guess, and verify that
+# it's correct once the real value is defined.
+guessed_intermediates := $(call local-intermediates-dir)
+
+# Define the target that is the unmodified output of the linker.
+# The basename of this target must be the same as the final output
+# binary name, because it's used to set the "soname" in the binary.
+# The includer of this file will define a rule to build this target.
+linked_module := $(guessed_intermediates)/LINKED/$(LOCAL_BUILT_MODULE_STEM)
+
+ALL_ORIGINAL_DYNAMIC_BINARIES += $(linked_module)
+
+# Because TARGET_SYMBOL_FILTER_FILE depends on ALL_ORIGINAL_DYNAMIC_BINARIES,
+# the linked_module rules won't necessarily inherit the PRIVATE_
+# variables from LOCAL_BUILT_MODULE. This tells binary.make to explicitly
+# define the PRIVATE_ variables for linked_module as well as for
+# LOCAL_BUILT_MODULE.
+LOCAL_INTERMEDIATE_TARGETS := $(linked_module)
+
+###################################
+include $(BUILD_SYSTEM)/binary.mk
+###################################
+
+# Make sure that our guess at the value of intermediates was correct.
+ifneq ($(intermediates),$(guessed_intermediates))
+$(error Internal error: guessed path '$(guessed_intermediates)' doesn't match '$(intermediates))
+endif
+
+###########################################################
+## Compress
+###########################################################
+compress_input := $(linked_module)
+
+ifeq ($(strip $(LOCAL_COMPRESS_MODULE_SYMBOLS)),)
+ LOCAL_COMPRESS_MODULE_SYMBOLS := $(strip $(TARGET_COMPRESS_MODULE_SYMBOLS))
+endif
+
+ifeq ($(LOCAL_COMPRESS_MODULE_SYMBOLS),true)
+$(error Symbol compression not yet supported.)
+compress_output := $(intermediates)/COMPRESSED-$(LOCAL_BUILT_MODULE_STEM)
+
+#TODO: write the real $(SOSLIM) rule.
+#TODO: define a rule to build TARGET_SYMBOL_FILTER_FILE, and
+# make it depend on ALL_ORIGINAL_DYNAMIC_BINARIES.
+$(compress_output): $(compress_input) $(TARGET_SYMBOL_FILTER_FILE) | $(ACP)
+ @echo "target Compress Symbols: $(PRIVATE_MODULE) ($@)"
+ $(copy-file-to-target)
+else
+# Skip this step.
+compress_output := $(compress_input)
+endif
+
+
+###########################################################
+## Pre-link
+###########################################################
+prelink_input := $(compress_output)
+# The output of the prelink step is the binary we want to use
+# for symbolic debugging; the prelink step may move sections
+# around, so we have to use this version.
+prelink_output := $(LOCAL_UNSTRIPPED_PATH)/$(LOCAL_MODULE_SUBDIR)$(LOCAL_BUILT_MODULE_STEM)
+
+ifeq ($(LOCAL_PRELINK_MODULE),true)
+$(prelink_output): $(prelink_input) $(TARGET_PRELINKER_MAP) $(APRIORI)
+ $(transform-to-prelinked)
+else
+# Don't prelink the binary, just copy it. We can't skip this step
+# because people always expect a copy of the binary to appear
+# in the UNSTRIPPED directory.
+#
+# If the binary we're copying is acp or a prerequisite,
+# use cp(1) instead.
+ifneq ($(LOCAL_ACP_UNAVAILABLE),true)
+$(prelink_output): $(prelink_input) | $(ACP)
+ @echo "target Non-prelinked: $(PRIVATE_MODULE) ($@)"
+ $(copy-file-to-target)
+else
+$(prelink_output): $(prelink_input)
+ @echo "target Non-prelinked: $(PRIVATE_MODULE) ($@)"
+ $(copy-file-to-target-with-cp)
+endif
+endif
+
+
+###########################################################
+## Strip
+###########################################################
+strip_input := $(prelink_output)
+strip_output := $(LOCAL_BUILT_MODULE)
+
+ifeq ($(strip $(LOCAL_STRIP_MODULE)),)
+ LOCAL_STRIP_MODULE := $(strip $(TARGET_STRIP_MODULE))
+endif
+
+ifeq ($(LOCAL_STRIP_MODULE),true)
+# Strip the binary
+$(strip_output): $(strip_input) | $(SOSLIM)
+ $(transform-to-stripped)
+else
+# Don't strip the binary, just copy it. We can't skip this step
+# because a copy of the binary must appear at LOCAL_BUILT_MODULE.
+#
+# If the binary we're copying is acp or a prerequisite,
+# use cp(1) instead.
+ifneq ($(LOCAL_ACP_UNAVAILABLE),true)
+$(strip_output): $(strip_input) | $(ACP)
+ @echo "target Unstripped: $(PRIVATE_MODULE) ($@)"
+ $(copy-file-to-target)
+else
+$(strip_output): $(strip_input)
+ @echo "target Unstripped: $(PRIVATE_MODULE) ($@)"
+ $(copy-file-to-target-with-cp)
+endif
+endif # LOCAL_STRIP_MODULE
+
+
+$(cleantarget): PRIVATE_CLEAN_FILES := \
+ $(PRIVATE_CLEAN_FILES) \
+ $(linked_module) \
+ $(compress_output) \
+ $(prelink_output)
diff --git a/core/envsetup.mk b/core/envsetup.mk
new file mode 100644
index 0000000..0c24ea9
--- /dev/null
+++ b/core/envsetup.mk
@@ -0,0 +1,333 @@
+# Variables we check:
+# HOST_BUILD_TYPE = { release debug }
+# TARGET_SIMULATOR = { true <null> }
+# TARGET_BUILD_TYPE = { release debug }
+# and we output a bunch of variables, see the case statement at
+# the bottom for the full list
+# OUT_DIR is also set to "out" if it's not already set.
+# this allows you to set it to somewhere else if you like
+
+# ---------------------------------------------------------------
+# If you update the build system such that the environment setup
+# or buildspec.mk need to be updated, increment this number, and
+# people who haven't re-run those will have to do so before they
+# can build. Make sure to also update the corresponding value in
+# buildspec.mk.default and envsetup.sh.
+CORRECT_BUILD_ENV_SEQUENCE_NUMBER := 9
+
+# ---------------------------------------------------------------
+# The product defaults to generic on hardware and sim on sim
+# NOTE: This will be overridden in product_config.mk if make
+# was invoked with a PRODUCT-xxx-yyy goal.
+ifeq ($(TARGET_PRODUCT),)
+ifeq ($(TARGET_SIMULATOR),true)
+TARGET_PRODUCT := sim
+else
+TARGET_PRODUCT := generic
+endif
+endif
+
+
+# the variant -- the set of files that are included for a build
+ifeq ($(strip $(TARGET_BUILD_VARIANT)),)
+TARGET_BUILD_VARIANT := eng
+endif
+
+# Read the product specs so we an get TARGET_DEVICE and other
+# variables that we need in order to locate the output files.
+include $(BUILD_SYSTEM)/product_config.mk
+
+build_variant := $(filter-out eng user userdebug tests,$(TARGET_BUILD_VARIANT))
+ifneq ($(build_variant)-$(words $(TARGET_BUILD_VARIANT)),-1)
+$(warning bad TARGET_BUILD_VARIANT: $(TARGET_BUILD_VARIANT))
+$(error must be empty or one of: eng user userdebug tests)
+endif
+
+
+
+# ---------------------------------------------------------------
+# Set up configuration for host machine. We don't do cross-
+# compiles except for arm, so the HOST is whatever we are
+# running on
+
+UNAME := $(shell uname -sm)
+
+# HOST_OS
+ifneq (,$(findstring Linux,$(UNAME)))
+ HOST_OS := linux
+endif
+ifneq (,$(findstring Darwin,$(UNAME)))
+ HOST_OS := darwin
+endif
+ifneq (,$(findstring Macintosh,$(UNAME)))
+ HOST_OS := darwin
+endif
+ifneq (,$(findstring CYGWIN,$(UNAME)))
+ HOST_OS := windows
+endif
+ifneq ($(USE_MINGW),)
+ HOST_OS := windows
+endif
+
+ifeq ($(HOST_OS),)
+$(error Unable to determine HOST_OS from uname -sm: $(UNAME)!)
+endif
+
+
+# HOST_ARCH
+ifneq (,$(findstring 86,$(UNAME)))
+ HOST_ARCH := x86
+endif
+
+ifneq (,$(findstring Power,$(UNAME)))
+ HOST_ARCH := ppc
+endif
+
+ifeq ($(HOST_ARCH),)
+$(error Unable to determine HOST_ARCH from uname -sm: $(UNAME)!)
+endif
+
+# the host build defaults to release, and it must be release or debug
+ifeq ($(HOST_BUILD_TYPE),)
+HOST_BUILD_TYPE := release
+endif
+
+ifneq ($(HOST_BUILD_TYPE),release)
+ifneq ($(HOST_BUILD_TYPE),debug)
+$(error HOST_BUILD_TYPE must be either release or debug, not '$(HOST_BUILD_TYPE)')
+endif
+endif
+
+# This is the standard way to name a directory containing prebuilt host
+# objects. E.g., prebuilt/$(HOST_PREBUILT_TAG)/cc
+ifeq ($(HOST_OS),windows)
+ HOST_PREBUILT_TAG := windows
+else
+ HOST_PREBUILT_TAG := $(HOST_OS)-$(HOST_ARCH)
+endif
+
+
+# ---------------------------------------------------------------
+# Set up configuration for target machine.
+# The following must be set:
+# TARGET_OS = { linux }
+# TARGET_ARCH = { arm | x86 }
+
+
+# if we're build the simulator, HOST_* is TARGET_* (except for BUILD_TYPE)
+# otherwise it's <arch>-linux
+ifeq ($(TARGET_SIMULATOR),true)
+ifneq ($(HOST_OS),linux)
+$(error TARGET_SIMULATOR=true is only supported under Linux)
+endif
+TARGET_ARCH := $(HOST_ARCH)
+TARGET_OS := $(HOST_OS)
+else
+ifeq ($(TARGET_ARCH),)
+TARGET_ARCH := arm
+endif
+TARGET_OS := linux
+endif
+
+# the target build type defaults to release
+ifneq ($(TARGET_BUILD_TYPE),debug)
+TARGET_BUILD_TYPE := release
+endif
+
+# This is the standard way to name a directory containing prebuilt target
+# objects. E.g., prebuilt/$(TARGET_PREBUILT_TAG)/libc.so
+ifeq ($(TARGET_SIMULATOR),true)
+ TARGET_PREBUILT_TAG := $(TARGET_OS)-$(TARGET_ARCH)
+else
+ TARGET_PREBUILT_TAG := android-$(TARGET_ARCH)
+endif
+
+# ---------------------------------------------------------------
+# figure out the output directories
+
+ifeq (,$(strip $(OUT_DIR)))
+OUT_DIR := $(TOPDIR)out
+endif
+
+DEBUG_OUT_DIR := $(OUT_DIR)/debug
+
+# Move the host or target under the debug/ directory
+# if necessary.
+TARGET_OUT_ROOT_release := $(OUT_DIR)/target
+TARGET_OUT_ROOT_debug := $(DEBUG_OUT_DIR)/target
+TARGET_OUT_ROOT := $(TARGET_OUT_ROOT_$(TARGET_BUILD_TYPE))
+
+HOST_OUT_ROOT_release := $(OUT_DIR)/host
+HOST_OUT_ROOT_debug := $(DEBUG_OUT_DIR)/host
+HOST_OUT_ROOT := $(HOST_OUT_ROOT_$(HOST_BUILD_TYPE))
+
+HOST_OUT_release := $(HOST_OUT_ROOT_release)/$(HOST_OS)-$(HOST_ARCH)
+HOST_OUT_debug := $(HOST_OUT_ROOT_debug)/$(HOST_OS)-$(HOST_ARCH)
+HOST_OUT := $(HOST_OUT_$(HOST_BUILD_TYPE))
+
+ifeq ($(TARGET_SIMULATOR),true)
+ # Any arch- or os-specific parts of the simulator (everything
+ # under product/) are actually host-dependent.
+ # But, the debug type is controlled by TARGET_BUILD_TYPE and not
+ # HOST_BUILD_TYPE.
+ TARGET_PRODUCT_OUT_ROOT := $(HOST_OUT_$(TARGET_BUILD_TYPE))/product
+else
+ TARGET_PRODUCT_OUT_ROOT := $(TARGET_OUT_ROOT)/product
+endif
+
+TARGET_COMMON_OUT_ROOT := $(TARGET_OUT_ROOT)/common
+HOST_COMMON_OUT_ROOT := $(HOST_OUT_ROOT)/common
+
+PRODUCT_OUT := $(TARGET_PRODUCT_OUT_ROOT)/$(TARGET_DEVICE)
+
+OUT_DOCS := $(TARGET_COMMON_OUT_ROOT)/docs
+
+HOST_OUT_EXECUTABLES:= $(HOST_OUT)/bin
+HOST_OUT_SHARED_LIBRARIES:= $(HOST_OUT)/lib
+HOST_OUT_JAVA_LIBRARIES:= $(HOST_OUT)/framework
+
+HOST_OUT_INTERMEDIATES := $(HOST_OUT)/obj
+HOST_OUT_HEADERS:= $(HOST_OUT_INTERMEDIATES)/include
+HOST_OUT_INTERMEDIATE_LIBRARIES := $(HOST_OUT_INTERMEDIATES)/lib
+HOST_OUT_STATIC_LIBRARIES := $(HOST_OUT_INTERMEDIATE_LIBRARIES)
+HOST_OUT_NOTICE_FILES:=$(HOST_OUT_INTERMEDIATES)/NOTICE_FILES
+HOST_OUT_COMMON_INTERMEDIATES := $(HOST_COMMON_OUT_ROOT)/obj
+
+TARGET_OUT_INTERMEDIATES := $(PRODUCT_OUT)/obj
+TARGET_OUT_HEADERS:= $(TARGET_OUT_INTERMEDIATES)/include
+TARGET_OUT_INTERMEDIATE_LIBRARIES := $(TARGET_OUT_INTERMEDIATES)/lib
+TARGET_OUT_COMMON_INTERMEDIATES := $(TARGET_COMMON_OUT_ROOT)/obj
+
+TARGET_OUT := $(PRODUCT_OUT)/system
+TARGET_OUT_EXECUTABLES:= $(TARGET_OUT)/bin
+TARGET_OUT_OPTIONAL_EXECUTABLES:= $(TARGET_OUT)/xbin
+TARGET_OUT_SHARED_LIBRARIES:= $(TARGET_OUT)/lib
+TARGET_OUT_JAVA_LIBRARIES:= $(TARGET_OUT)/framework
+TARGET_OUT_APPS:= $(TARGET_OUT)/app
+TARGET_OUT_KEYLAYOUT := $(TARGET_OUT)/usr/keylayout
+TARGET_OUT_KEYCHARS := $(TARGET_OUT)/usr/keychars
+TARGET_OUT_ETC := $(TARGET_OUT)/etc
+TARGET_OUT_STATIC_LIBRARIES:= $(TARGET_OUT_INTERMEDIATES)/lib
+TARGET_OUT_NOTICE_FILES:=$(TARGET_OUT_INTERMEDIATES)/NOTICE_FILES
+
+TARGET_OUT_DATA := $(PRODUCT_OUT)/data
+TARGET_OUT_DATA_EXECUTABLES:= $(TARGET_OUT_EXECUTABLES)
+TARGET_OUT_DATA_SHARED_LIBRARIES:= $(TARGET_OUT_SHARED_LIBRARIES)
+TARGET_OUT_DATA_JAVA_LIBRARIES:= $(TARGET_OUT_JAVA_LIBRARIES)
+TARGET_OUT_DATA_APPS:= $(TARGET_OUT_DATA)/app
+TARGET_OUT_DATA_KEYLAYOUT := $(TARGET_OUT_KEYLAYOUT)
+TARGET_OUT_DATA_KEYCHARS := $(TARGET_OUT_KEYCHARS)
+TARGET_OUT_DATA_ETC := $(TARGET_OUT_ETC)
+TARGET_OUT_DATA_STATIC_LIBRARIES:= $(TARGET_OUT_STATIC_LIBRARIES)
+
+TARGET_OUT_UNSTRIPPED := $(PRODUCT_OUT)/symbols
+TARGET_OUT_EXECUTABLES_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/system/bin
+TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/system/lib
+TARGET_ROOT_OUT_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)
+TARGET_ROOT_OUT_SBIN_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/sbin
+TARGET_ROOT_OUT_BIN_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/bin
+
+TARGET_ROOT_OUT := $(PRODUCT_OUT)/root
+TARGET_ROOT_OUT_BIN := $(TARGET_ROOT_OUT)/bin
+TARGET_ROOT_OUT_SBIN := $(TARGET_ROOT_OUT)/sbin
+TARGET_ROOT_OUT_ETC := $(TARGET_ROOT_OUT)/etc
+TARGET_ROOT_OUT_USR := $(TARGET_ROOT_OUT)/usr
+
+TARGET_RECOVERY_OUT := $(PRODUCT_OUT)/recovery
+TARGET_RECOVERY_ROOT_OUT := $(TARGET_RECOVERY_OUT)/root
+
+TARGET_SYSLOADER_OUT := $(PRODUCT_OUT)/sysloader
+TARGET_SYSLOADER_ROOT_OUT := $(TARGET_SYSLOADER_OUT)/root
+TARGET_SYSLOADER_SYSTEM_OUT := $(TARGET_SYSLOADER_OUT)/root/system
+
+TARGET_INSTALLER_OUT := $(PRODUCT_OUT)/installer
+TARGET_INSTALLER_DATA_OUT := $(TARGET_INSTALLER_OUT)/data
+TARGET_INSTALLER_ROOT_OUT := $(TARGET_INSTALLER_OUT)/root
+TARGET_INSTALLER_SYSTEM_OUT := $(TARGET_INSTALLER_OUT)/root/system
+
+COMMON_MODULE_CLASSES := JAVA_LIBRARIES NOTICE_FILES
+
+ifeq (,$(strip $(DIST_DIR)))
+ DIST_DIR := $(OUT_DIR)/dist
+endif
+
+ifeq ($(PRINT_BUILD_CONFIG),)
+PRINT_BUILD_CONFIG := true
+endif
+
+# ---------------------------------------------------------------
+# the setpath shell function in envsetup.sh uses this to figure out
+# what to add to the path given the config we have chosen.
+ifeq ($(CALLED_FROM_SETUP),true)
+
+ABP:=$(PWD)/$(HOST_OUT_EXECUTABLES)
+
+ifeq ($(TARGET_SIMULATOR),true)
+ ABP:=$(ABP):$(TARGET_OUT_EXECUTABLES)
+else
+ # this should be copied to HOST_OUT_EXECUTABLES instead
+ ABP:=$(ABP):$(PWD)/prebuilt/$(HOST_PREBUILT_TAG)/toolchain/arm-eabi-4.2.1/bin
+endif
+ANDROID_BUILD_PATHS := $(ABP)
+ANDROID_PREBUILTS := prebuilt/$(HOST_PREBUILT_TAG)
+
+# The "dumpvar" stuff lets you say something like
+#
+# CALLED_FROM_SETUP=true \
+# make -f config/envsetup.make dumpvar-TARGET_OUT
+# or
+# CALLED_FROM_SETUP=true \
+# make -f config/envsetup.make dumpvar-abs-HOST_OUT_EXECUTABLES
+#
+# The plain (non-abs) version just dumps the value of the named variable.
+# The "abs" version will treat the variable as a path, and dumps an
+# absolute path to it.
+#
+dumpvar_goals := \
+ $(strip $(patsubst dumpvar-%,%,$(filter dumpvar-%,$(MAKECMDGOALS))))
+ifdef dumpvar_goals
+
+ ifneq ($(words $(dumpvar_goals)),1)
+ $(error Only one "dumpvar-" goal allowed. Saw "$(MAKECMDGOALS)")
+ endif
+
+ # If the goal is of the form "dumpvar-abs-VARNAME", then
+ # treat VARNAME as a path and return the absolute path to it.
+ absolute_dumpvar := $(strip $(filter abs-%,$(dumpvar_goals)))
+ ifdef absolute_dumpvar
+ dumpvar_goals := $(patsubst abs-%,%,$(dumpvar_goals))
+ DUMPVAR_VALUE := $(PWD)/$($(dumpvar_goals))
+ dumpvar_target := dumpvar-abs-$(dumpvar_goals)
+ else
+ DUMPVAR_VALUE := $($(dumpvar_goals))
+ dumpvar_target := dumpvar-$(dumpvar_goals)
+ endif
+
+.PHONY: $(dumpvar_target)
+$(dumpvar_target):
+ @echo $(DUMPVAR_VALUE)
+
+endif # dumpvar_goals
+
+ifneq ($(dumpvar_goals),report_config)
+PRINT_BUILD_CONFIG:=
+endif
+
+endif # CALLED_FROM_SETUP
+
+
+ifneq ($(PRINT_BUILD_CONFIG),)
+$(info ============================================)
+$(info TARGET_PRODUCT=$(TARGET_PRODUCT))
+$(info TARGET_BUILD_VARIANT=$(TARGET_BUILD_VARIANT))
+$(info TARGET_SIMULATOR=$(TARGET_SIMULATOR))
+$(info TARGET_BUILD_TYPE=$(TARGET_BUILD_TYPE))
+$(info TARGET_ARCH=$(TARGET_ARCH))
+$(info HOST_ARCH=$(HOST_ARCH))
+$(info HOST_OS=$(HOST_OS))
+$(info HOST_BUILD_TYPE=$(HOST_BUILD_TYPE))
+$(info BUILD_ID=$(BUILD_ID))
+$(info ============================================)
+endif
+
+
diff --git a/core/executable.mk b/core/executable.mk
new file mode 100644
index 0000000..623c766
--- /dev/null
+++ b/core/executable.mk
@@ -0,0 +1,28 @@
+###########################################################
+## Standard rules for building an executable file.
+##
+## Additional inputs from base_rules.make:
+## None.
+###########################################################
+
+ifeq ($(strip $(LOCAL_MODULE_CLASS)),)
+LOCAL_MODULE_CLASS := EXECUTABLES
+endif
+ifeq ($(strip $(LOCAL_MODULE_SUFFIX)),)
+LOCAL_MODULE_SUFFIX := $(TARGET_EXECUTABLE_SUFFIX)
+endif
+
+# Executables are not prelinked. If we decide to start prelinking
+# them, the LOCAL_PRELINK_MODULE definitions should be moved from
+# here and shared_library.make and consolidated in dynamic_binary.make.
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SYSTEM)/dynamic_binary.mk
+
+ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
+$(linked_module): $(TARGET_CRTBEGIN_STATIC_O) $(all_objects) $(all_libraries) $(TARGET_CRTEND_O)
+ $(transform-o-to-static-executable)
+else
+$(linked_module): $(TARGET_CRTBEGIN_DYNAMIC_O) $(all_objects) $(all_libraries) $(TARGET_CRTEND_O)
+ $(transform-o-to-executable)
+endif
diff --git a/core/filter_symbols.sh b/core/filter_symbols.sh
new file mode 100644
index 0000000..ba5057a
--- /dev/null
+++ b/core/filter_symbols.sh
@@ -0,0 +1,25 @@
+NM=$1
+
+shift
+
+PREFIX=$1
+
+shift
+
+SUFFIX=$1
+
+shift
+
+while test "$1" != ""
+do
+ $NM -g -fp $1 | while read -a line
+ do
+ type=${line[1]}
+ # if [[ "$type" != "V" && "$type" != "U" ]]; then
+ #if [[ "$type" != "W" && "$type" != "V" && "$type" != "U" ]]; then
+ echo "$PREFIX${line[0]}$SUFFIX # ${line[1]}"
+ #fi
+ done
+
+ shift
+done
diff --git a/core/find-jdk-tools-jar.sh b/core/find-jdk-tools-jar.sh
new file mode 100755
index 0000000..091eae4
--- /dev/null
+++ b/core/find-jdk-tools-jar.sh
@@ -0,0 +1,10 @@
+if [[ "x$ANDROID_JAVA_HOME" != x && -e $ANDROID_JAVA_HOME/lib/tools.jar ]] ; then
+ echo $ANDROID_JAVA_HOME/lib/tools.jar
+else
+ JAVAC=$(which javac)
+ while [ -L $JAVAC ] ; do
+ LSLINE=$(ls -l $JAVAC)
+ JAVAC=$(echo -n $LSLINE | sed -e "s/.* -> //")
+ done
+ echo $JAVAC | sed -e "s:\(.*\)/bin/javac.*:\\1/lib/tools.jar:"
+fi
diff --git a/core/host_executable.mk b/core/host_executable.mk
new file mode 100644
index 0000000..4d90e6d
--- /dev/null
+++ b/core/host_executable.mk
@@ -0,0 +1,20 @@
+###########################################################
+## Standard rules for building an executable file.
+##
+## Additional inputs from base_rules.make:
+## None.
+###########################################################
+
+LOCAL_IS_HOST_MODULE := true
+ifeq ($(strip $(LOCAL_MODULE_CLASS)),)
+LOCAL_MODULE_CLASS := EXECUTABLES
+endif
+ifeq ($(strip $(LOCAL_MODULE_SUFFIX)),)
+LOCAL_MODULE_SUFFIX := $(HOST_EXECUTABLE_SUFFIX)
+endif
+
+include $(BUILD_SYSTEM)/binary.mk
+
+$(LOCAL_BUILT_MODULE): $(all_objects) $(all_libraries)
+ $(transform-host-o-to-executable)
+ $(PRIVATE_POST_PROCESS_COMMAND)
diff --git a/core/host_java_library.mk b/core/host_java_library.mk
new file mode 100644
index 0000000..92b5ff6
--- /dev/null
+++ b/core/host_java_library.mk
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+#
+# Standard rules for building a host java library.
+#
+
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX)
+LOCAL_IS_HOST_MODULE := true
+LOCAL_BUILT_MODULE_STEM := javalib.jar
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(java_sources) $(java_resource_sources) $(full_java_lib_deps)
+ $(transform-host-java-to-package)
diff --git a/core/host_prebuilt.mk b/core/host_prebuilt.mk
new file mode 100644
index 0000000..7baab69
--- /dev/null
+++ b/core/host_prebuilt.mk
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+LOCAL_IS_HOST_MODULE := true
+include $(BUILD_MULTI_PREBUILT)
diff --git a/core/host_shared_library.mk b/core/host_shared_library.mk
new file mode 100644
index 0000000..f78b17b
--- /dev/null
+++ b/core/host_shared_library.mk
@@ -0,0 +1,29 @@
+###########################################################
+## Standard rules for building a normal shared library.
+##
+## Additional inputs from base_rules.make:
+## None.
+##
+## LOCAL_MODULE_SUFFIX will be set for you.
+###########################################################
+
+LOCAL_IS_HOST_MODULE := true
+
+ifeq ($(strip $(LOCAL_MODULE_CLASS)),)
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+endif
+ifeq ($(strip $(LOCAL_MODULE_SUFFIX)),)
+LOCAL_MODULE_SUFFIX := $(HOST_SHLIB_SUFFIX)
+endif
+ifneq ($(strip $(OVERRIDE_BUILT_MODULE_PATH)),)
+$(error $(LOCAL_PATH): Illegal use of OVERRIDE_BUILT_MODULE_PATH)
+endif
+
+# Put the built modules of all shared libraries in a common directory
+# to simplify the link line.
+OVERRIDE_BUILT_MODULE_PATH := $(HOST_OUT_INTERMEDIATE_LIBRARIES)
+
+include $(BUILD_SYSTEM)/binary.mk
+
+$(LOCAL_BUILT_MODULE): $(all_objects) $(all_libraries) $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(transform-host-o-to-shared-lib)
diff --git a/core/host_static_library.mk b/core/host_static_library.mk
new file mode 100644
index 0000000..237981f
--- /dev/null
+++ b/core/host_static_library.mk
@@ -0,0 +1,23 @@
+###########################################################
+## Standard rules for building a static library.
+##
+## Additional inputs from base_rules.make:
+## None.
+##
+## LOCAL_MODULE_SUFFIX will be set for you.
+###########################################################
+
+LOCAL_IS_HOST_MODULE := true
+
+ifeq ($(strip $(LOCAL_MODULE_CLASS)),)
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+endif
+ifeq ($(strip $(LOCAL_MODULE_SUFFIX)),)
+LOCAL_MODULE_SUFFIX := .a
+endif
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/binary.mk
+
+$(LOCAL_BUILT_MODULE): $(all_objects)
+ $(transform-host-o-to-static-lib)
diff --git a/core/java.mk b/core/java.mk
new file mode 100644
index 0000000..65c525d
--- /dev/null
+++ b/core/java.mk
@@ -0,0 +1,178 @@
+# Requires:
+# LOCAL_MODULE_SUFFIX
+# LOCAL_MODULE_CLASS
+# all_res_assets
+
+# Make sure there's something to build.
+# It's possible to build a package that doesn't contain any classes.
+ifeq (,$(strip $(LOCAL_SRC_FILES)$(all_res_assets)))
+$(error $(LOCAL_PATH): Target java module does not define any source or resource files)
+endif
+
+LOCAL_NO_STANDARD_LIBRARIES:=$(strip $(LOCAL_NO_STANDARD_LIBRARIES))
+LOCAL_SDK_VERSION:=$(strip $(LOCAL_SDK_VERSION))
+
+ifneq ($(LOCAL_SDK_VERSION),)
+ ifeq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
+ $(error $(LOCAL_PATH): Must not define both LOCAL_NO_STANDARD_LIBRARIES and LOCAL_SDK_VERSION)
+ else
+ ifeq ($(strip $(filter $(LOCAL_SDK_VERSION),$(TARGET_AVAILABLE_SDK_VERSIONS))),)
+ $(error $(LOCAL_PATH): Invalid LOCAL_SDK_VERSION '$(LOCAL_SDK_VERSION)' \
+ Choices are: $(TARGET_AVAILABLE_SDK_VERSIONS))
+ else
+ LOCAL_JAVA_LIBRARIES := android_stubs_$(LOCAL_SDK_VERSION) $(LOCAL_JAVA_LIBRARIES)
+ endif
+ endif
+else
+ ifneq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
+ LOCAL_JAVA_LIBRARIES := core ext framework $(LOCAL_JAVA_LIBRARIES)
+ endif
+endif
+
+LOCAL_BUILT_MODULE_STEM := $(strip $(LOCAL_BUILT_MODULE_STEM))
+ifeq ($(LOCAL_BUILT_MODULE_STEM),)
+$(error $(LOCAL_PATH): Target java template must define LOCAL_BUILT_MODULE_STEM)
+endif
+ifneq ($(filter classes-compiled.jar classes.jar,$(LOCAL_BUILT_MODULE_STEM)),)
+$(error LOCAL_BUILT_MODULE_STEM may not be "$(LOCAL_BUILT_MODULE_STEM)")
+endif
+
+#######################################
+include $(BUILD_SYSTEM)/base_rules.mk
+#######################################
+
+# We use intermediates.COMMON because the classes.jar/.dex files will be
+# common even if LOCAL_BUILT_MODULE isn't.
+#
+# Override some target variables that base_rules set up for us.
+$(LOCAL_INTERMEDIATE_TARGETS): \
+ PRIVATE_CLASS_INTERMEDIATES_DIR := $(intermediates.COMMON)/classes
+$(LOCAL_INTERMEDIATE_TARGETS): \
+ PRIVATE_SOURCE_INTERMEDIATES_DIR := $(intermediates.COMMON)/src
+
+# Since we're using intermediates.COMMON, make sure that it gets cleaned
+# properly.
+$(cleantarget): PRIVATE_CLEAN_FILES += $(intermediates.COMMON)
+
+# If the module includes java code (i.e., it's not framework-res), compile it.
+full_classes_jar :=
+built_dex :=
+ifneq (,$(strip $(all_java_sources)))
+
+# If LOCAL_BUILT_MODULE_STEM wasn't overridden by our caller,
+# full_classes_jar will be the same module as LOCAL_BUILT_MODULE.
+# Otherwise, the caller will define it as a prerequisite of
+# LOCAL_BUILT_MODULE, so it will inherit the necessary PRIVATE_*
+# variable definitions.
+full_classes_jar := $(intermediates.COMMON)/classes.jar
+
+# Emma source code coverage
+ifneq ($(EMMA_INSTRUMENT),true)
+LOCAL_NO_EMMA_INSTRUMENT := true
+LOCAL_NO_EMMA_COMPILE := true
+endif
+
+ifneq ($(LOCAL_NO_EMMA_COMPILE),true)
+# If you instrument class files that have local variable debug information in
+# them emma does not correctly maintain the local variable table.
+# This will cause an error when you try to convert the class files for Android.
+# The workaround for this to compile the java classes with only
+# line and source debug information, not local information.
+full_classes_compiled_name_jar := classes-no-debug-var.jar
+$(full_classes_compiled_jar): PRIVATE_JAVAC_DEBUG_FLAGS := -g:{lines,source}
+else
+# when emma is off, compile with the default flags, which contain full debug
+# info
+full_classes_compiled_name_jar := classes-full-debug.jar
+$(full_classes_compiled_jar): PRIVATE_JAVAC_DEBUG_FLAGS := -g
+endif
+
+# Compile the java files to a .jar file.
+# This intentionally depends on java_sources, not all_java_sources.
+# Deps for generated source files must be handled separately,
+# via deps on the target that generates the sources.
+full_classes_compiled_jar := $(intermediates.COMMON)/$(full_classes_compiled_name_jar)
+$(full_classes_compiled_jar): $(java_sources) $(full_java_lib_deps)
+ $(transform-java-to-classes.jar)
+
+emma_intermediates_dir := $(intermediates.COMMON)/emma_out
+# the 'lib/$(full_classes_compiled_name_jar)' portion of this path is fixed in
+# the emma tool
+full_classes_emma_jar := $(emma_intermediates_dir)/lib/$(full_classes_compiled_name_jar)
+
+ifeq ($(LOCAL_IS_STATIC_JAVA_LIBRARY),true)
+# Skip adding emma instrumentation to class files if this is a static library,
+# since it will be instrumented by the package that includes it
+LOCAL_NO_EMMA_INSTRUMENT:= true
+endif
+
+ifneq ($(LOCAL_NO_EMMA_INSTRUMENT),true)
+$(full_classes_emma_jar): PRIVATE_EMMA_COVERAGE_FILE := $(intermediates.COMMON)/coverage.em
+$(full_classes_emma_jar): PRIVATE_EMMA_INTERMEDIATES_DIR := $(emma_intermediates_dir)
+# this rule will generate both $(PRIVATE_EMMA_COVERAGE_FILE) and
+# $(full_classes_emma_jar)
+$(full_classes_emma_jar): $(full_classes_compiled_jar)
+ $(transform-classes.jar-to-emma)
+$(PRIVATE_EMMA_COVERAGE_FILE): $(full_classes_emma_jar)
+else
+$(full_classes_emma_jar): $(full_classes_compiled_jar) | $(ACP)
+ @echo Copying $<
+ $(copy-file-to-target)
+endif
+
+# Run jarjar 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.
+full_classes_jarjar_jar := $(full_classes_jar)
+ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
+$(full_classes_jarjar_jar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
+$(full_classes_jarjar_jar): $(full_classes_emma_jar) | jarjar
+ @echo JarJar: $@
+ $(hide) $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
+else
+$(full_classes_jarjar_jar): $(full_classes_emma_jar) | $(ACP)
+ @echo Copying: $@
+ $(hide) $(ACP) $< $@
+endif
+
+
+built_dex := $(intermediates.COMMON)/classes.dex
+
+# Override PRIVATE_INTERMEDIATES_DIR so that install-dex-debug
+# will work even when intermediates != intermediates.COMMON.
+$(built_dex): PRIVATE_INTERMEDIATES_DIR := $(intermediates.COMMON)
+$(built_dex): PRIVATE_DX_FLAGS := $(LOCAL_DX_FLAGS)
+$(built_dex): $(full_classes_jar) $(DX)
+ $(transform-classes.jar-to-dex)
+ifneq ($(GENERATE_DEX_DEBUG),)
+ $(install-dex-debug)
+endif
+
+findbugs_xml := $(intermediates.COMMON)/findbugs.xml
+$(findbugs_xml) : PRIVATE_JAR_FILE := $(full_classes_jar)
+$(findbugs_xml) : PRIVATE_AUXCLASSPATH := $(addprefix -auxclasspath ,$(strip \
+ $(call normalize-path-list,$(filter %.jar,\
+ $(full_java_libs)))))
+# We can't depend directly on full_classes_jar because the PRIVATE_
+# vars won't be set up correctly.
+$(findbugs_xml) : $(LOCAL_BUILT_MODULE)
+ @echo Findbugs: $@
+ $(hide) $(FINDBUGS) -textui -effort:min -xml:withMessages \
+ $(PRIVATE_AUXCLASSPATH) \
+ $(PRIVATE_JAR_FILE) \
+ > $@
+
+ALL_FINDBUGS_FILES += $(findbugs_xml)
+
+findbugs_html := $(PRODUCT_OUT)/findbugs/$(LOCAL_MODULE).html
+$(findbugs_html) : PRIVATE_XML_FILE := $(findbugs_xml)
+$(LOCAL_MODULE)-findbugs : $(findbugs_html)
+$(findbugs_html) : $(findbugs_xml)
+ @mkdir -p $(dir $@)
+ @echo UnionBugs: $@
+ $(hide) prebuilt/common/findbugs/bin/unionBugs $(PRIVATE_XML_FILE) \
+ | prebuilt/common/findbugs/bin/convertXmlToText -html:fancy.xsl \
+ > $@
+
+$(LOCAL_MODULE)-findbugs : $(findbugs_html)
+
+endif
diff --git a/core/java_library.mk b/core/java_library.mk
new file mode 100644
index 0000000..a33bf2e
--- /dev/null
+++ b/core/java_library.mk
@@ -0,0 +1,47 @@
+###########################################################
+## Standard rules for building a java library.
+##
+###########################################################
+
+ifdef LOCAL_IS_HOST_MODULE
+$(error $(LOCAL_PATH): Host java libraries must use BUILD_HOST_JAVA_LIBRARY)
+endif
+
+LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX)
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+ifneq (,$(LOCAL_ASSET_DIR))
+$(error $(LOCAL_PATH): Target java libraries may not set LOCAL_ASSET_DIR)
+endif
+
+ifneq (,$(LOCAL_RESOURCE_DIR))
+$(error $(LOCAL_PATH): Target java libraries may not set LOCAL_RESOURCE_DIR)
+endif
+
+#xxx base_rules.mk looks at this
+all_res_assets :=
+
+LOCAL_BUILT_MODULE_STEM := javalib.jar
+
+#################################
+include $(BUILD_SYSTEM)/java.mk
+#################################
+
+ifeq ($(LOCAL_IS_STATIC_JAVA_LIBRARY),true)
+# No dex or resources; all we want are the .class files.
+$(LOCAL_BUILT_MODULE): $(full_classes_jar)
+ @echo "target Static Jar: $(PRIVATE_MODULE) ($@)"
+ $(copy-file-to-target)
+
+else # !LOCAL_IS_STATIC_JAVA_LIBRARY
+
+$(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE := $(built_dex)
+$(LOCAL_BUILT_MODULE): $(built_dex) $(java_resource_sources) | $(AAPT)
+ @echo "target Jar: $(PRIVATE_MODULE) ($@)"
+ $(create-empty-package)
+ $(add-dex-to-package)
+ifneq ($(extra_jar_args),)
+ $(add-java-resources-to-package)
+endif
+
+endif # !LOCAL_IS_STATIC_JAVA_LIBRARY
diff --git a/core/key_char_map.mk b/core/key_char_map.mk
new file mode 100644
index 0000000..0f112f2
--- /dev/null
+++ b/core/key_char_map.mk
@@ -0,0 +1,27 @@
+###########################################################
+## Standard rules for building an executable file.
+##
+## Additional inputs from base_rules.make:
+## None.
+###########################################################
+
+ifeq ($(strip $(LOCAL_MODULE_CLASS)),)
+LOCAL_MODULE_CLASS := KEYCHARS
+endif
+ifeq ($(strip $(LOCAL_MODULE_SUFFIX)),)
+LOCAL_MODULE_SUFFIX := .bin
+endif
+
+LOCAL_MODULE := $(LOCAL_SRC_FILES)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+full_src_files := $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES))
+
+$(LOCAL_BUILT_MODULE) : PRIVATE_SRC_FILES := $(full_src_files)
+
+$(LOCAL_BUILT_MODULE) : $(full_src_files) $(KCM)
+ @echo KeyCharMap: $@
+ @mkdir -p $(dir $@)
+ $(hide) $(KCM) $(PRIVATE_SRC_FILES) $@
+
diff --git a/core/main.mk b/core/main.mk
new file mode 100644
index 0000000..1f3412f
--- /dev/null
+++ b/core/main.mk
@@ -0,0 +1,656 @@
+
+# Use bash, not whatever shell somebody has installed as /bin/sh
+# This is repeated in config.mk, since envsetup.sh runs that file
+# directly.
+SHELL := /bin/bash
+
+# this turns off the suffix rules built into make
+.SUFFIXES:
+
+# If a rule fails, delete $@.
+.DELETE_ON_ERROR:
+
+# Figure out where we are.
+#TOP := $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
+#TOP := $(patsubst %/,%,$(TOP))
+
+# TOPDIR is the normal variable you should use, because
+# if we are executing relative to the current directory
+# it can be "", whereas TOP must be "." which causes
+# pattern matching probles when make strips off the
+# trailing "./" from paths in various places.
+#ifeq ($(TOP),.)
+#TOPDIR :=
+#else
+#TOPDIR := $(TOP)/
+#endif
+
+# check for broken versions of make
+ifeq (0,$(shell expr $$(echo $(MAKE_VERSION) | sed "s/[^0-9\.].*//") \>= 3.81))
+$(warning ********************************************************************************)
+$(warning * You are using version $(MAKE_VERSION) of make.)
+$(warning * You must upgrade to version 3.81 or greater.)
+$(warning * see file://$(shell pwd)/docs/development-environment/machine-setup.html)
+$(warning ********************************************************************************)
+$(error stopping)
+endif
+
+TOP := .
+TOPDIR :=
+
+BUILD_SYSTEM := $(TOPDIR)build/core
+
+# This is the default target. It must be the first declared target.
+DEFAULT_GOAL := droid
+$(DEFAULT_GOAL):
+
+# Set up various standard variables based on configuration
+# and host information.
+include $(BUILD_SYSTEM)/config.mk
+
+# This allows us to force a clean build - included after the config.make
+# environment setup is done, but before we generate any dependencies. This
+# file does the rm -rf inline so the deps which are all done below will
+# be generated correctly
+include $(BUILD_SYSTEM)/cleanbuild.mk
+
+ifneq ($(HOST_OS),windows)
+ifneq ($(HOST_OS)-$(HOST_ARCH),darwin-ppc)
+# check for a case sensitive file system
+ifneq (a,$(shell mkdir -p $(OUT_DIR) ; \
+ echo a > $(OUT_DIR)/casecheck.txt; \
+ echo B > $(OUT_DIR)/CaseCheck.txt; \
+ cat $(OUT_DIR)/casecheck.txt))
+$(warning ************************************************************)
+$(warning You are building on a case-insensitive filesystem.)
+$(warning Please move your source tree to a case-sensitive filesystem.)
+$(warning ************************************************************)
+$(error Case-insensitive filesystems not supported)
+endif
+endif
+endif
+
+# Make sure that there are no spaces in the absolute path; the
+# build system can't deal with them.
+ifneq ($(words $(shell pwd)),1)
+$(warning ************************************************************)
+$(warning You are building in a directory whose absolute path contains)
+$(warning a space character:)
+$(warning $(space))
+$(warning "$(shell pwd)")
+$(warning $(space))
+$(warning Please move your source tree to a path that does not contain)
+$(warning any spaces.)
+$(warning ************************************************************)
+$(error Directory names containing spaces not supported)
+endif
+
+# Set up version information.
+include $(BUILD_SYSTEM)/version_defaults.mk
+
+# These are the modifier targets that don't do anything themselves, but
+# change the behavior of the build.
+# (must be defined before including definitions.make)
+INTERNAL_MODIFIER_TARGETS := showcommands
+
+# Bring in standard build system definitions.
+include $(BUILD_SYSTEM)/definitions.mk
+
+ifneq ($(filter eng user userdebug tests,$(MAKECMDGOALS)),)
+$(info ***************************************************************)
+$(info ***************************************************************)
+$(info Don't pass '$(filter eng user userdebug tests,$(MAKECMDGOALS))' on \
+ the make command line.)
+$(info Set TARGET_BUILD_VARIANT in buildspec.mk, or use lunch or)
+$(info choosecombo.)
+$(info ***************************************************************)
+$(info ***************************************************************)
+$(error stopping)
+endif
+
+
+###
+### In this section we set up the things that are different
+### between the build variants
+###
+
+## user/userdebug ##
+
+user_variant := $(filter userdebug user,$(TARGET_BUILD_VARIANT))
+enable_target_debugging := true
+ifneq (,$(user_variant))
+ # Target is secure in user builds.
+ ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=1
+
+ override_build_tags := user
+ ifeq ($(user_variant),userdebug)
+ # Pick up some extra useful tools
+ override_build_tags += debug
+ else
+ # Disable debugging in plain user builds.
+ enable_target_debugging :=
+ endif
+
+ # TODO: Always set WITH_DEXPREOPT (for user builds) once it works on OSX.
+ # Also, remove the corresponding block in config/product_config.make.
+ ifeq ($(HOST_OS)-$(WITH_DEXPREOPT_buildbot),linux-true)
+ WITH_DEXPREOPT := true
+ endif
+
+ # Disallow mock locations by default for user builds
+ ADDITIONAL_DEFAULT_PROPERTIES += ro.allow.mock.location=0
+
+else # !user_variant
+ # Turn on checkjni for non-user builds.
+ ADDITIONAL_BUILD_PROPERTIES += ro.kernel.android.checkjni=1
+ # Set device insecure for non-user builds.
+ ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=0
+ # Allow mock locations by default for non user builds
+ ADDITIONAL_DEFAULT_PROPERTIES += ro.allow.mock.location=1
+endif # !user_variant
+
+ifeq (true,$(strip $(enable_target_debugging)))
+ # Target is more debuggable and adbd is on by default
+ ADDITIONAL_DEFAULT_PROPERTIES += ro.debuggable=1 persist.service.adb.enable=1
+ # Include the debugging/testing OTA keys in this build.
+ INCLUDE_TEST_OTA_KEYS := true
+else # !enable_target_debugging
+ # Target is less debuggable and adbd is off by default
+ ADDITIONAL_DEFAULT_PROPERTIES += ro.debuggable=0 persist.service.adb.enable=0
+endif # !enable_target_debugging
+
+## tests ##
+
+ifeq ($(TARGET_BUILD_VARIANT),tests)
+override_build_tags := eng debug user development tests
+endif
+
+## sdk ##
+
+ifneq ($(filter sdk,$(MAKECMDGOALS)),)
+ifneq ($(words $(filter-out $(INTERNAL_MODIFIER_TARGETS),$(MAKECMDGOALS))),1)
+$(error The 'sdk' target may not be specified with any other targets)
+endif
+override_build_tags := user
+ADDITIONAL_BUILD_PROPERTIES += xmpp.auto-presence=true
+ADDITIONAL_BUILD_PROPERTIES += ro.config.nocheckin=yes
+else # !sdk
+# Enable sync for non-sdk builds only (sdk builds lack SubscribedFeedsProvider).
+ADDITIONAL_BUILD_PROPERTIES += ro.config.sync=yes
+endif
+
+ifeq "" "$(filter %:system/etc/apns-conf.xml, $(PRODUCT_COPY_FILES))"
+ # Install an apns-conf.xml file if one's not already being installed.
+ PRODUCT_COPY_FILES += development/data/etc/apns-conf_sdk.xml:system/etc/apns-conf.xml
+ ifeq ($(filter sdk,$(MAKECMDGOALS)),)
+ $(warning implicitly installing apns-conf_sdk.xml)
+ endif
+endif
+
+ADDITIONAL_BUILD_PROPERTIES += net.bt.name=Android
+
+# enable vm tracing in files for now to help track
+# the cause of ANRs in the content process
+ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.stack-trace-file=/data/anr/traces.txt
+
+
+# ------------------------------------------------------------
+# Define a function that, given a list of module tags, returns
+# non-empty if that module should be installed in /system.
+
+# For most goals, anything tagged with "eng"/"debug"/"user" should
+# be installed in /system.
+define should-install-to-system
+$(filter eng debug user,$(1))
+endef
+
+ifneq (,$(filter sdk,$(MAKECMDGOALS)))
+# For the sdk goal, anything with the "samples" tag should be
+# installed in /data even if that module also has "eng"/"debug"/"user".
+define should-install-to-system
+$(if $(filter samples,$(1)),,$(filter eng debug user development,$(1)))
+endef
+endif
+
+ifeq ($(TARGET_BUILD_VARIANT),)
+# For the default goal, everything should be installed in /system.
+define should-install-to-system
+true
+endef
+endif
+
+
+# If all they typed was make showcommands, we'll actually build
+# the default target.
+ifeq ($(MAKECMDGOALS),showcommands)
+.PHONY: showcommands
+showcommands: $(DEFAULT_GOAL)
+endif
+
+# These targets are going to delete stuff, don't bother including
+# the whole directory tree if that's all we're going to do
+ifeq ($(MAKECMDGOALS),clean)
+dont_bother := true
+endif
+ifeq ($(MAKECMDGOALS),clobber)
+dont_bother := true
+endif
+ifeq ($(MAKECMDGOALS),dataclean)
+dont_bother := true
+endif
+ifeq ($(MAKECMDGOALS),installclean)
+dont_bother := true
+endif
+
+# Bring in all modules that need to be built.
+ifneq ($(dont_bother),true)
+
+subdir_makefiles :=
+
+ifeq ($(HOST_OS),windows)
+SDK_ONLY := true
+endif
+ifeq ($(HOST_OS)-$(HOST_ARCH),darwin-ppc)
+SDK_ONLY := true
+endif
+
+ifeq ($(SDK_ONLY),true)
+
+subdirs := \
+ prebuilt \
+ build/libs/host \
+ dalvik/dexdump \
+ dalvik/libdex \
+ dalvik/tools/dmtracedump \
+ development/emulator/mksdcard \
+ development/tools/activitycreator \
+ development/tools/line_endings \
+ development/host \
+ external/expat \
+ external/libpng \
+ external/qemu \
+ external/sqlite/dist \
+ external/zlib \
+ frameworks/base/libs/utils \
+ frameworks/base/tools/aapt \
+ frameworks/base/tools/aidl \
+ system/core/adb \
+ system/core/fastboot \
+ system/core/libcutils \
+ system/core/liblog \
+ system/core/libzipfile
+
+# The following can only be built if "javac" is available.
+# This check is used when building parts of the SDK under Cygwin.
+ifneq (,$(shell which javac 2>/dev/null))
+$(warning sdk-only: javac available.)
+subdirs += \
+ build/tools/signapk \
+ build/tools/zipalign \
+ dalvik/dx \
+ dalvik/libcore \
+ development/apps \
+ development/tools/androidprefs \
+ development/tools/apkbuilder \
+ development/tools/jarutils \
+ development/tools/layoutlib_utils \
+ development/tools/ninepatch \
+ development/tools/sdkstats \
+ development/tools/sdkmanager \
+ frameworks/base \
+ frameworks/base/tools/layoutlib \
+ external/googleclient \
+ packages
+else
+$(warning sdk-only: javac not available.)
+endif
+
+# Exclude tools/acp when cross-compiling windows under linux
+ifeq ($(findstring Linux,$(UNAME)),)
+subdirs += build/tools/acp
+endif
+
+else # !SDK_ONLY
+ifeq ($(BUILD_TINY_ANDROID), true)
+
+# TINY_ANDROID is a super-minimal build configuration, handy for board
+# bringup and very low level debugging
+
+INTERNAL_DEFAULT_DOCS_TARGETS :=
+
+subdirs := \
+ bionic \
+ system/core \
+ build/libs \
+ build/target \
+ build/tools/acp \
+ build/tools/apriori \
+ build/tools/kcm \
+ build/tools/soslim \
+ external/elfcopy \
+ external/elfutils \
+ external/yaffs2 \
+ external/zlib
+else # !BUILD_TINY_ANDROID
+
+#
+# Typical build; include any Android.mk files we can find.
+#
+INTERNAL_DEFAULT_DOCS_TARGETS := offline-sdk-docs
+subdirs := $(TOP)
+
+FULL_BUILD := true
+
+endif # !BUILD_TINY_ANDROID
+
+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))
+
+#
+# Include all of the makefiles in the system
+#
+
+ifneq ($(ONE_SHOT_MAKEFILE),)
+# We've probably been invoked by the "mm" shell function
+# with a subdirectory's makefile.
+include $(ONE_SHOT_MAKEFILE)
+# Change CUSTOM_MODULES to include only modules that were
+# defined by this makefile; this will install all of those
+# modules as a side-effect. Do this after including ONE_SHOT_MAKEFILE
+# so that the modules will be installed in the same place they
+# would have been with a normal make.
+CUSTOM_MODULES := $(sort $(call get-tagged-modules,$(ALL_MODULE_TAGS),))
+FULL_BUILD :=
+INTERNAL_DEFAULT_DOCS_TARGETS :=
+# Stub out the notice targets, which probably aren't defined
+# when using ONE_SHOT_MAKEFILE.
+NOTICE-HOST-%: ;
+NOTICE-TARGET-%: ;
+else
+include $(subdir_makefiles)
+endif
+# -------------------------------------------------------------------
+# All module makefiles have been included at this point.
+# -------------------------------------------------------------------
+
+# -------------------------------------------------------------------
+# Include any makefiles that must happen after the module makefiles
+# have been included.
+# TODO: have these files register themselves via a global var rather
+# than hard-coding the list here.
+ifdef FULL_BUILD
+ # Only include this during a full build, otherwise we can't be
+ # guaranteed that any policies were included.
+ -include frameworks/policies/base/PolicyConfig.mk
+endif
+
+# -------------------------------------------------------------------
+# Fix up CUSTOM_MODULES to refer to installed files rather than
+# just bare module names. Leave unknown modules alone in case
+# they're actually full paths to a particular file.
+known_custom_modules := $(filter $(ALL_MODULES),$(CUSTOM_MODULES))
+unknown_custom_modules := $(filter-out $(ALL_MODULES),$(CUSTOM_MODULES))
+CUSTOM_MODULES := \
+ $(call module-installed-files,$(known_custom_modules)) \
+ $(unknown_custom_modules)
+
+# -------------------------------------------------------------------
+# Define dependencies for modules that require other modules.
+# This can only happen now, after we've read in all module makefiles.
+#
+# TODO: deal with the fact that a bare module name isn't
+# unambiguous enough. Maybe declare short targets like
+# APPS:Quake or HOST:SHARED_LIBRARIES:libutils.
+# BUG: the system image won't know to depend on modules that are
+# brought in as requirements of other modules.
+define add-required-deps
+$(1): $(2)
+endef
+$(foreach m,$(ALL_MODULES), \
+ $(eval r := $(ALL_MODULES.$(m).REQUIRED)) \
+ $(if $(r), \
+ $(eval r := $(call module-installed-files,$(r))) \
+ $(eval $(call add-required-deps,$(ALL_MODULES.$(m).INSTALLED),$(r))) \
+ ) \
+ )
+m :=
+r :=
+add-required-deps :=
+
+# -------------------------------------------------------------------
+# Figure out our module sets.
+
+# Of the modules defined by the component makefiles,
+# determine what we actually want to build.
+# If a module has the "restricted" tag on it, it
+# poisons the rest of the tags and shouldn't appear
+# on any list.
+Default_MODULES := $(sort $(ALL_DEFAULT_INSTALLED_MODULES) \
+ $(ALL_BUILT_MODULES) \
+ $(CUSTOM_MODULES))
+
+ifdef FULL_BUILD
+ # The base list of modules to build for this product is specified
+ # by the appropriate product definition file, which was included
+ # by product_config.make.
+ user_PACKAGES := $(call module-installed-files, \
+ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES))
+ ifeq (0,1)
+ $(info user packages for $(TARGET_DEVICE) ($(INTERNAL_PRODUCT)):)
+ $(foreach p,$(user_PACKAGES),$(info : $(p)))
+ $(error done)
+ endif
+else
+ # We're not doing a full build, and are probably only including
+ # a subset of the module makefiles. Don't try to build any modules
+ # requested by the product, because we probably won't have rules
+ # to build them.
+ user_PACKAGES :=
+endif
+# Use tags to get the non-APPS user modules. Use the product
+# definition files to get the APPS user modules.
+user_MODULES := $(sort $(call get-tagged-modules,user,_class@APPS restricted))
+user_MODULES := $(user_MODULES) $(user_PACKAGES)
+
+eng_MODULES := $(sort $(call get-tagged-modules,eng,restricted))
+debug_MODULES := $(sort $(call get-tagged-modules,debug,restricted))
+tests_MODULES := $(sort $(call get-tagged-modules,tests,restricted))
+
+droid_MODULES := $(sort $(Default_MODULES) \
+ $(eng_MODULES) \
+ $(debug_MODULES) \
+ $(user_MODULES) \
+ $(all_development_MODULES))
+
+# THIS IS A TOTAL HACK AND SHOULD NOT BE USED AS AN EXAMPLE
+modules_to_build := $(droid_MODULES)
+ifneq ($(override_build_tags),)
+ modules_to_build := $(sort $(Default_MODULES) \
+ $(foreach tag,$(override_build_tags),$($(tag)_MODULES)))
+#$(error skipping modules $(filter-out $(modules_to_build),$(Default_MODULES) $(droid_MODULES)))
+endif
+
+# Some packages may override others using LOCAL_OVERRIDES_PACKAGES.
+# Filter out (do not install) any overridden packages.
+overridden_packages := $(call get-package-overrides,$(modules_to_build))
+ifdef overridden_packages
+# old_modules_to_build := $(modules_to_build)
+ modules_to_build := \
+ $(filter-out $(foreach p,$(overridden_packages),$(p) %/$(p).apk), \
+ $(modules_to_build))
+endif
+#$(error filtered out $(filter-out $(modules_to_build),$(old_modules_to_build)))
+
+# Don't include any GNU targets in the SDK. It's ok (and necessary)
+# to build the host tools, but nothing that's going to be installed
+# on the target (including static libraries).
+ifneq ($(filter sdk,$(MAKECMDGOALS)),)
+ target_gnu_MODULES := \
+ $(filter \
+ $(TARGET_OUT_INTERMEDIATES)/% \
+ $(TARGET_OUT)/% \
+ $(TARGET_OUT_DATA)/%, \
+ $(sort $(call get-tagged-modules,gnu)))
+ $(info Removing from sdk:)$(foreach d,$(target_gnu_MODULES),$(info : $(d)))
+ modules_to_build := \
+ $(filter-out $(target_gnu_MODULES),$(modules_to_build))
+endif
+
+
+# config/Makefile contains extra stuff that we don't want to pollute this
+# top-level makefile with. It expects that ALL_DEFAULT_INSTALLED_MODULES
+# contains everything that's built during the current make, but it also further
+# extends ALL_DEFAULT_INSTALLED_MODULES.
+ALL_DEFAULT_INSTALLED_MODULES := $(modules_to_build)
+include $(BUILD_SYSTEM)/Makefile
+modules_to_build := $(sort $(ALL_DEFAULT_INSTALLED_MODULES))
+ALL_DEFAULT_INSTALLED_MODULES :=
+
+endif # dont_bother
+
+# -------------------------------------------------------------------
+# This is used to to get the ordering right, you can also use these,
+# but they're considered undocumented, so don't complain if their
+# behavior changes.
+.PHONY: prebuilt
+prebuilt: $(ALL_PREBUILT)
+
+# An internal target that depends on all copied headers
+# (see copy_headers.make). Other targets that need the
+# headers to be copied first can depend on this target.
+.PHONY: all_copied_headers
+all_copied_headers: ;
+
+$(ALL_C_CPP_ETC_OBJECTS): | all_copied_headers
+
+# All the droid stuff, in directories
+.PHONY: files
+files: prebuilt $(modules_to_build) $(INSTALLED_ANDROID_INFO_TXT_TARGET)
+
+# -------------------------------------------------------------------
+
+.PHONY: ramdisk
+ramdisk: $(INSTALLED_RAMDISK_TARGET)
+
+.PHONY: systemtarball
+systemtarball: $(INSTALLED_SYSTEMTARBALL_TARGET)
+
+.PHONY: userdataimage
+userdataimage: $(INSTALLED_USERDATAIMAGE_TARGET)
+
+.PHONY: userdatatarball
+userdatatarball: $(INSTALLED_USERDATATARBALL_TARGET)
+
+.PHONY: bootimage
+bootimage: $(INSTALLED_BOOTIMAGE_TARGET)
+
+ifeq ($(BUILD_TINY_ANDROID), true)
+INSTALLED_RECOVERYIMAGE_TARGET :=
+endif
+
+# Build files and then package it into the rom formats
+.PHONY: droidcore
+droidcore: files \
+ systemimage \
+ $(INSTALLED_BOOTIMAGE_TARGET) \
+ $(INSTALLED_RECOVERYIMAGE_TARGET) \
+ $(INSTALLED_USERDATAIMAGE_TARGET) \
+ $(INTERNAL_DEFAULT_DOCS_TARGETS) \
+ $(INSTALLED_FILES_FILE)
+
+# The actual files built by the droidcore target changes depending
+# on the build variant.
+.PHONY: droid tests
+droid tests: droidcore
+
+$(call dist-for-goals, droid, \
+ $(INTERNAL_UPDATE_PACKAGE_TARGET) \
+ $(INTERNAL_OTA_PACKAGE_TARGET) \
+ $(SYMBOLS_ZIP) \
+ $(APPS_ZIP) \
+ $(INTERNAL_EMULATOR_PACKAGE_TARGET) \
+ $(PACKAGE_STATS_FILE) \
+ $(INSTALLED_FILES_FILE) \
+ $(INSTALLED_BUILD_PROP_TARGET) \
+ $(BUILT_TARGET_FILES_PACKAGE) \
+ )
+
+# Tests are installed in userdata.img. If we're building the tests
+# variant, copy it for "make tests dist". Also copy a zip of the
+# contents of userdata.img, so that people can easily extract a
+# single .apk.
+ifeq ($(TARGET_BUILD_VARIANT),tests)
+$(call dist-for-goals, droid, \
+ $(INSTALLED_USERDATAIMAGE_TARGET) \
+ $(BUILT_TESTS_ZIP_PACKAGE) \
+ )
+endif
+
+.PHONY: docs
+docs: $(ALL_DOCS)
+
+.PHONY: sdk
+ALL_SDK_TARGETS := $(INTERNAL_SDK_TARGET)
+sdk: $(ALL_SDK_TARGETS)
+$(call dist-for-goals,sdk,$(ALL_SDK_TARGETS))
+
+.PHONY: findbugs
+findbugs: $(INTERNAL_FINDBUGS_HTML_TARGET) $(INTERNAL_FINDBUGS_XML_TARGET)
+
+.PHONY: clean
+dirs_to_clean := \
+ $(PRODUCT_OUT) \
+ $(TARGET_COMMON_OUT_ROOT) \
+ $(HOST_OUT) \
+ $(HOST_COMMON_OUT_ROOT)
+clean:
+ @for dir in $(dirs_to_clean) ; do \
+ echo "Cleaning $$dir..."; \
+ rm -rf $$dir; \
+ done
+ @echo "Clean."; \
+
+.PHONY: clobber
+clobber:
+ @rm -rf $(OUT_DIR)
+ @echo "Entire build directory removed."
+
+# The rules for dataclean and installclean are defined in cleanbuild.mk.
+
+#xxx scrape this from ALL_MODULE_NAME_TAGS
+.PHONY: modules
+modules:
+ @echo "Available sub-modules:"
+ @echo "$(call module-names-for-tag-list,$(ALL_MODULE_TAGS))" | \
+ sed -e 's/ */\n/g' | sort -u | $(COLUMN)
+
+.PHONY: showcommands
+showcommands:
+ @echo >/dev/null
+
diff --git a/core/multi_prebuilt.mk b/core/multi_prebuilt.mk
new file mode 100644
index 0000000..707af10
--- /dev/null
+++ b/core/multi_prebuilt.mk
@@ -0,0 +1,111 @@
+#
+# 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.
+#
+
+# Save these before they get cleared by CLEAR_VARS.
+prebuilt_static_libs := $(filter %.a,$(LOCAL_PREBUILT_LIBS))
+prebuilt_shared_libs := $(filter-out %.a,$(LOCAL_PREBUILT_LIBS))
+prebuilt_executables := $(LOCAL_PREBUILT_EXECUTABLES)
+prebuilt_java_libraries := $(LOCAL_PREBUILT_JAVA_LIBRARIES)
+prebuilt_static_java_libraries := $(LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES)
+prebuilt_is_host := $(LOCAL_IS_HOST_MODULE)
+
+
+ifndef multi_prebuilt_once
+multi_prebuilt_once := true
+
+# $(1): file list
+# $(2): IS_HOST_MODULE
+# $(3): MODULE_CLASS
+# $(4): OVERRIDE_BUILT_MODULE_PATH
+# $(5): UNINSTALLABLE_MODULE
+# $(6): BUILT_MODULE_STEM
+#
+# Elements in the file list may be bare filenames,
+# or of the form "<modulename>:<filename>".
+# If the module name is not specified, the module
+# name will be the filename with the suffix removed.
+#
+define auto-prebuilt-boilerplate
+$(if $(filter %: :%,$(1)), \
+ $(error $(LOCAL_PATH): Leading or trailing colons in "$(1)")) \
+$(foreach t,$(1), \
+ $(eval include $(CLEAR_VARS)) \
+ $(eval LOCAL_IS_HOST_MODULE := $(2)) \
+ $(eval LOCAL_MODULE_CLASS := $(3)) \
+ $(eval OVERRIDE_BUILT_MODULE_PATH := $(4)) \
+ $(eval LOCAL_UNINSTALLABLE_MODULE := $(5)) \
+ $(eval tw := $(subst :, ,$(strip $(t)))) \
+ $(if $(word 3,$(tw)),$(error $(LOCAL_PATH): Bad prebuilt filename '$(t)')) \
+ $(if $(word 2,$(tw)), \
+ $(eval LOCAL_MODULE := $(word 1,$(tw))) \
+ $(eval LOCAL_SRC_FILES := $(word 2,$(tw))) \
+ , \
+ $(eval LOCAL_MODULE := $(basename $(t))) \
+ $(eval LOCAL_SRC_FILES := $(t)) \
+ ) \
+ $(if $(6), \
+ $(eval LOCAL_BUILT_MODULE_STEM := $(6)) \
+ , \
+ $(eval LOCAL_BUILT_MODULE_STEM := $(LOCAL_SRC_FILES)) \
+ ) \
+ $(eval LOCAL_MODULE_SUFFIX := $(suffix $(LOCAL_SRC_FILES))) \
+ $(eval include $(BUILD_PREBUILT)) \
+ )
+endef
+
+endif # multi_prebuilt_once
+
+
+$(call auto-prebuilt-boilerplate, \
+ $(prebuilt_static_libs), \
+ $(prebuilt_is_host), \
+ STATIC_LIBRARIES, \
+ , \
+ true)
+
+$(call auto-prebuilt-boilerplate, \
+ $(prebuilt_shared_libs), \
+ $(prebuilt_is_host), \
+ SHARED_LIBRARIES, \
+ $($(if $(prebuilt_is_host),HOST,TARGET)_OUT_INTERMEDIATE_LIBRARIES))
+
+$(call auto-prebuilt-boilerplate, \
+ $(prebuilt_executables), \
+ $(prebuilt_is_host), \
+ EXECUTABLES)
+
+$(call auto-prebuilt-boilerplate, \
+ $(prebuilt_java_libraries), \
+ $(prebuilt_is_host), \
+ JAVA_LIBRARIES, \
+ , \
+ , \
+ javalib.jar)
+
+$(call auto-prebuilt-boilerplate, \
+ $(prebuilt_static_java_libraries), \
+ $(prebuilt_is_host), \
+ JAVA_LIBRARIES, \
+ , \
+ true, \
+ javalib.jar)
+
+prebuilt_static_libs :=
+prebuilt_shared_libs :=
+prebuilt_executables :=
+prebuilt_java_libraries :=
+prebuilt_static_java_libraries :=
+prebuilt_is_host :=
diff --git a/core/node_fns.mk b/core/node_fns.mk
new file mode 100644
index 0000000..202bb0d
--- /dev/null
+++ b/core/node_fns.mk
@@ -0,0 +1,238 @@
+#
+# Copyright (C) 2007 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.
+#
+
+#
+# Clears a list of variables using ":=".
+#
+# E.g.,
+# $(call clear-var-list,A B C)
+# would be the same as:
+# A :=
+# B :=
+# C :=
+#
+# $(1): list of variable names to clear
+#
+define clear-var-list
+$(foreach v,$(1),$(eval $(v):=))
+endef
+
+#
+# Copies a list of variables into another list of variables.
+# The target list is the same as the source list, but has
+# a dotted prefix affixed to it.
+#
+# E.g.,
+# $(call copy-var-list, PREFIX, A B)
+# would be the same as:
+# PREFIX.A := $(A)
+# PREFIX.B := $(B)
+#
+# $(1): destination prefix
+# $(2): list of variable names to copy
+#
+define copy-var-list
+$(foreach v,$(2),$(eval $(strip $(1)).$(v):=$($(v))))
+endef
+
+#
+# Moves a list of variables into another list of variables.
+# The variable names differ by a prefix. After moving, the
+# source variable is cleared.
+#
+# NOTE: Spaces are not allowed around the prefixes.
+#
+# E.g.,
+# $(call move-var-list,SRC,DST,A B)
+# would be the same as:
+# DST.A := $(SRC.A)
+# SRC.A :=
+# DST.B := $(SRC.B)
+# SRC.B :=
+#
+# $(1): source prefix
+# $(2): destination prefix
+# $(3): list of variable names to move
+#
+define move-var-list
+$(foreach v,$(3), \
+ $(eval $(2).$(v) := $($(1).$(v))) \
+ $(eval $(1).$(v) :=) \
+ )
+endef
+
+#
+# $(1): haystack
+# $(2): needle
+#
+# Guarantees that needle appears at most once in haystack,
+# without changing the order of other elements in haystack.
+# If needle appears multiple times, only the first occurrance
+# will survive.
+#
+# How it works:
+#
+# - Stick everything in haystack into a single word,
+# with "|||" separating the words.
+# - Replace occurrances of "|||$(needle)|||" with "||| |||",
+# breaking haystack back into multiple words, with spaces
+# where needle appeared.
+# - Add needle between the first and second words of haystack.
+# - Replace "|||" with spaces, breaking haystack back into
+# individual words.
+#
+empty :=
+space := $(empty) $(empty)
+define uniq-word
+$(strip \
+ $(if $(filter $(2),$(1)), \
+ $(eval h := |||$(subst $(space),|||,$(strip $(1)))|||) \
+ $(eval h := $(subst |||$(strip $(2))|||,|||$(space)|||,$(h))) \
+ $(eval h := $(word 1,$(h)) $(2) $(wordlist 2,9999,$(h))) \
+ $(subst |||,$(space),$(h)) \
+ , \
+ $(1) \
+ ))
+endef
+
+INHERIT_TAG := @inherit:
+
+#
+# Walks through the list of variables, each qualified by the prefix,
+# and finds instances of words beginning with INHERIT_TAG. Scrape
+# off INHERIT_TAG from each matching word, and return the sorted,
+# unique set of those words.
+#
+# E.g., given
+# PREFIX.A := A $(INHERIT_TAG)aaa B C
+# PREFIX.B := B $(INHERIT_TAG)aaa C $(INHERIT_TAG)bbb D E
+# Then
+# $(call get-inherited-nodes,PREFIX,A B)
+# returns
+# aaa bbb
+#
+# $(1): variable prefix
+# $(2): list of variables to check
+#
+define get-inherited-nodes
+$(sort \
+ $(subst $(INHERIT_TAG),, \
+ $(filter $(INHERIT_TAG)%, \
+ $(foreach v,$(2),$($(1).$(v))) \
+ )))
+endef
+
+#
+# for each variable ( (prefix + name) * vars ):
+# get list of inherited words; if not empty:
+# for each inherit:
+# replace the first occurrence with (prefix + inherited + var)
+# clear the source var so we can't inherit the value twice
+#
+# $(1): context prefix
+# $(2): name of this node
+# $(3): list of variable names
+#
+define _expand-inherited-values
+ $(foreach v,$(3), \
+ $(eval ### "Shorthand for the name of the target variable") \
+ $(eval _eiv_tv := $(1).$(2).$(v)) \
+ $(eval ### "Get the list of nodes that this variable inherits") \
+ $(eval _eiv_i := \
+ $(sort \
+ $(patsubst $(INHERIT_TAG)%,%, \
+ $(filter $(INHERIT_TAG)%, $($(_eiv_tv)) \
+ )))) \
+ $(foreach i,$(_eiv_i), \
+ $(eval ### "Make sure that this inherit appears only once") \
+ $(eval $(_eiv_tv) := \
+ $(call uniq-word,$($(_eiv_tv)),$(INHERIT_TAG)$(i))) \
+ $(eval ### "Expand the inherit tag") \
+ $(eval $(_eiv_tv) := \
+ $(patsubst $(INHERIT_TAG)$(i),$($(1).$(i).$(v)), \
+ $($(_eiv_tv)))) \
+ $(eval ### "Clear the child so DAGs don't create duplicate entries" ) \
+ $(eval $(1).$(i).$(v) :=) \
+ $(eval ### "If we just inherited ourselves, it's a cycle.") \
+ $(if $(filter $(INHERIT_TAG)$(2),$($(_eiv_tv))), \
+ $(warning Cycle detected between "$(2)" and "$(i)" for context "$(1)") \
+ $(error import of "$(2)" failed) \
+ ) \
+ ) \
+ ) \
+ $(eval _eiv_tv :=) \
+ $(eval _eiv_i :=)
+endef
+
+#
+# $(1): context prefix
+# $(2): makefile representing this node
+# $(3): list of node variable names
+#
+#TODO: keep a debug stack to make error messages more helpful
+define _import-node
+ $(call clear-var-list, $(3))
+ $(eval include $(2))
+ $(call copy-var-list, $(1).$(2), $(3))
+ $(call clear-var-list, $(3))
+
+ $(eval $(1).$(2).inherited := \
+ $(call get-inherited-nodes,$(1).$(2),$(3)))
+ $(call _import-nodes-inner,$(1),$($(1).$(2).inherited),$(3))
+
+ $(call _expand-inherited-values,$(1),$(2),$(3))
+
+ $(eval $(1).$(2).inherited :=)
+endef
+
+#
+# $(1): context prefix
+# $(2): list of makefiles representing nodes to import
+# $(3): list of node variable names
+#
+#TODO: Make the "does not exist" message more helpful;
+# should print out the name of the file trying to include it.
+define _import-nodes-inner
+ $(foreach _in,$(2), \
+ $(if $(wildcard $(_in)), \
+ $(if $($(1).$(_in).seen), \
+ $(eval ### "skipping already-imported $(_in)") \
+ , \
+ $(eval $(1).$(_in).seen := true) \
+ $(call _import-node,$(1),$(strip $(_in)),$(3)) \
+ ) \
+ , \
+ $(error $(1): "$(_in)" does not exist) \
+ ) \
+ )
+endef
+
+#
+# $(1): output list variable name, like "PRODUCTS" or "DEVICES"
+# $(2): list of makefiles representing nodes to import
+# $(3): list of node variable names
+#
+define import-nodes
+$(if \
+ $(foreach _in,$(2), \
+ $(eval _node_import_context := _nic.$(1).[[$(_in)]]) \
+ $(call _import-nodes-inner,$(_node_import_context),$(_in),$(3)) \
+ $(call move-var-list,$(_node_import_context).$(_in),$(1).$(_in),$(3)) \
+ $(eval _node_import_context :=) \
+ $(eval $(1) := $($(1)) $(_in)) \
+ ) \
+,)
+endef
diff --git a/core/notice_files.mk b/core/notice_files.mk
new file mode 100644
index 0000000..24295c7
--- /dev/null
+++ b/core/notice_files.mk
@@ -0,0 +1,65 @@
+###########################################################
+## Track NOTICE files
+###########################################################
+
+notice_file:=$(shell find $(LOCAL_PATH) -maxdepth 1 -name NOTICE)
+
+ifneq ($(strip $(notice_file)),)
+
+# This relies on the name of the directory in PRODUCT_OUT matching where
+# it's installed on the target - i.e. system, data, etc. This does
+# not work for root and isn't exact, but it's probably good enough for
+# compliance.
+# Includes the leading slash
+ifdef LOCAL_INSTALLED_MODULE
+ module_installed_filename := $(patsubst $(PRODUCT_OUT)%,%,$(LOCAL_INSTALLED_MODULE))
+else
+ # This module isn't installable
+ ifeq ($(LOCAL_MODULE_CLASS),STATIC_LIBRARIES)
+ # Stick the static libraries with the dynamic libraries.
+ # We can't use xxx_OUT_STATIC_LIBRARIES because it points into
+ # device-obj or host-obj.
+ module_installed_filename := \
+ $(patsubst $(PRODUCT_OUT)%,%,$($(my_prefix)OUT_SHARED_LIBRARIES))/$(notdir $(LOCAL_BUILT_MODULE))
+ else
+ ifeq ($(LOCAL_MODULE_CLASS),JAVA_LIBRARIES)
+ # Stick the static java libraries with the regular java libraries.
+ module_installed_filename := \
+ $(patsubst $(PRODUCT_OUT)%,%,$($(my_prefix)OUT_JAVA_LIBRARIES))/$(notdir $(LOCAL_BUILT_MODULE))
+ else
+ $(error Cannot determine where to install NOTICE file for $(LOCAL_MODULE))
+ endif # JAVA_LIBRARIES
+ endif # STATIC_LIBRARIES
+endif
+
+# In case it's actually a host file
+module_installed_filename := $(patsubst $(HOST_OUT)%,%,$(module_installed_filename))
+
+installed_notice_file := $($(my_prefix)OUT_NOTICE_FILES)/src/$(module_installed_filename).txt
+
+$(installed_notice_file): PRIVATE_INSTALLED_MODULE := $(module_installed_filename)
+
+$(installed_notice_file): $(notice_file)
+ @echo Notice file: $< -- $@
+ $(hide) mkdir -p $(dir $@)
+ $(hide) cat $< >> $@
+
+ifdef LOCAL_INSTALLED_MODULE
+# Make LOCAL_INSTALLED_MODULE depend on NOTICE files if they exist
+# libraries so they get installed along with it. Make it an order-only
+# dependency so we don't re-install a module when the NOTICE changes.
+$(LOCAL_INSTALLED_MODULE): | $(installed_notice_file)
+endif
+
+else
+# NOTICE file does not exist
+installed_notice_file :=
+endif
+
+# Create a predictable, phony target to build this notice file.
+# Define it even if the notice file doesn't exist so that other
+# modules can depend on it.
+notice_target := NOTICE-$(if \
+ $(LOCAL_IS_HOST_MODULE),HOST,TARGET)-$(LOCAL_MODULE_CLASS)-$(LOCAL_MODULE)
+.PHONY: $(notice_target)
+$(notice_target): $(installed_notice_file)
diff --git a/core/package.mk b/core/package.mk
new file mode 100644
index 0000000..a212553
--- /dev/null
+++ b/core/package.mk
@@ -0,0 +1,273 @@
+#
+# 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.
+#
+
+###########################################################
+## Standard rules for building an application package.
+##
+## Additional inputs from base_rules.make:
+## LOCAL_PACKAGE_NAME: The name of the package; the directory
+## will be called this.
+##
+## MODULE, MODULE_PATH, and MODULE_SUFFIX will
+## be set for you.
+###########################################################
+
+LOCAL_PACKAGE_NAME := $(strip $(LOCAL_PACKAGE_NAME))
+ifeq ($(LOCAL_PACKAGE_NAME),)
+$(error $(LOCAL_PATH): Package modules must define LOCAL_PACKAGE_NAME)
+endif
+
+LOCAL_MODULE_TAGS := $(strip $(LOCAL_MODULE_TAGS))
+ifeq ($(LOCAL_MODULE_TAGS),)
+$(error $(LOCAL_PATH): Package modules must define LOCAL_MODULE_TAGS)
+endif
+
+#$(warning $(LOCAL_PATH) $(LOCAL_PACKAGE_NAME) $(sort $(LOCAL_MODULE_TAGS)))
+
+ifneq ($(strip $(LOCAL_MODULE_SUFFIX)),)
+$(error $(LOCAL_PATH): Package modules may not define LOCAL_MODULE_SUFFIX)
+endif
+LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
+
+ifneq ($(strip $(LOCAL_MODULE)),)
+$(error $(LOCAL_PATH): Package modules may not define LOCAL_MODULE)
+endif
+LOCAL_MODULE := $(LOCAL_PACKAGE_NAME)
+
+# Android packages should use Android resources or assets.
+ifneq (,$(LOCAL_JAVA_RESOURCE_DIRS))
+$(error $(LOCAL_PATH): Package modules may not set LOCAL_JAVA_RESOURCE_DIRS)
+endif
+ifneq (,$(LOCAL_JAVA_RESOURCE_FILES))
+$(error $(LOCAL_PATH): Package modules may not set LOCAL_JAVA_RESOURCE_FILES)
+endif
+
+ifneq ($(strip $(LOCAL_MODULE_CLASS)),)
+$(error $(LOCAL_PATH): Package modules may not set LOCAL_MODULE_CLASS)
+endif
+LOCAL_MODULE_CLASS := APPS
+
+ifeq (,$(LOCAL_ASSET_DIR))
+LOCAL_ASSET_DIR := $(LOCAL_PATH)/assets
+endif
+
+ifeq (,$(LOCAL_RESOURCE_DIR))
+ LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+endif
+LOCAL_RESOURCE_DIR := \
+ $(wildcard $(addsuffix /$(LOCAL_RESOURCE_DIR), $(PRODUCT_PACKAGE_OVERLAYS))) \
+ $(wildcard $(addsuffix /$(LOCAL_RESOURCE_DIR), $(DEVICE_PACKAGE_OVERLAYS))) \
+ $(LOCAL_RESOURCE_DIR)
+
+# this is an app, so add the system libraries to the search path
+LOCAL_AIDL_INCLUDES += $(FRAMEWORKS_BASE_JAVA_SRC_DIRS)
+
+#$(warning Finding assets for $(LOCAL_ASSET_DIR))
+
+all_assets := $(call find-subdir-assets,$(LOCAL_ASSET_DIR))
+all_assets := $(addprefix $(LOCAL_ASSET_DIR)/,$(patsubst assets/%,%,$(all_assets)))
+
+all_resources := $(strip \
+ $(foreach dir, $(LOCAL_RESOURCE_DIR), \
+ $(addprefix $(dir)/, \
+ $(patsubst res/%,%, \
+ $(call find-subdir-assets,$(dir)) \
+ ) \
+ ) \
+ ))
+
+all_res_assets := $(strip $(all_assets) $(all_resources))
+
+# If no assets or resources were found, clear the directory variables so
+# we don't try to build them.
+ifeq (,$(all_assets))
+LOCAL_ASSET_DIR:=
+endif
+ifeq (,$(all_resources))
+LOCAL_RESOURCE_DIR:=
+R_file_stamp :=
+else
+# Make sure that R_file_stamp inherits the proper PRIVATE vars.
+# If R.stamp moves, be sure to update the framework makefile,
+# which has intimate knowledge of its location.
+package_expected_intermediates_COMMON := $(call local-intermediates-dir,COMMON)
+R_file_stamp := $(package_expected_intermediates_COMMON)/src/R.stamp
+LOCAL_INTERMEDIATE_TARGETS += $(R_file_stamp)
+endif
+
+LOCAL_BUILT_MODULE_STEM := package.apk
+
+# The dex files go in the package, so we don't
+# want to install them separately for this module.
+old_DONT_INSTALL_DEX_FILES := $(DONT_INSTALL_DEX_FILES)
+DONT_INSTALL_DEX_FILES := true
+#################################
+include $(BUILD_SYSTEM)/java.mk
+#################################
+DONT_INSTALL_DEX_FILES := $(old_DONT_INSTALL_DEX_FILES)
+old_DONT_INSTALL_DEX_FILES =
+
+full_android_manifest := $(LOCAL_PATH)/AndroidManifest.xml
+$(LOCAL_INTERMEDIATE_TARGETS): \
+ PRIVATE_ANDROID_MANIFEST := $(full_android_manifest)
+
+ifneq ($(all_resources),)
+
+# Since we don't know where the real R.java file is going to end up,
+# we need to use another file to stand in its place. We'll just
+# copy the generated file to src/R.stamp, which means it will
+# have the same contents and timestamp as the actual file.
+#
+# At the same time, this will copy the R.java file to a central
+# 'R' directory to make it easier to add the files to an IDE.
+#
+#TODO: use PRIVATE_SOURCE_INTERMEDIATES_DIR instead of
+# $(intermediates.COMMON)/src
+ifneq ($(package_expected_intermediates_COMMON),$(intermediates.COMMON))
+ $(error $(LOCAL_MODULE): internal error: expected intermediates.COMMON "$(package_expected_intermediates_COMMON)" != intermediates.COMMON "$(intermediates.COMMON)")
+endif
+
+$(R_file_stamp): PRIVATE_RESOURCE_PUBLICS_OUTPUT := \
+ $(intermediates.COMMON)/public_resources.xml
+$(R_file_stamp): $(all_res_assets) $(full_android_manifest) $(AAPT) | $(ACP)
+ @echo "target R.java/Manifest.java: $(PRIVATE_MODULE) ($@)"
+ @rm -f $@
+ $(create-resource-java-files)
+ $(hide) for GENERATED_MANIFEST_FILE in `find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) \
+ -name Manifest.java 2> /dev/null`; do \
+ dir=`grep package $$GENERATED_MANIFEST_FILE | head -n1 | \
+ awk '{print $$2}' | tr -d ";" | tr . /`; \
+ mkdir -p $(TARGET_COMMON_OUT_ROOT)/R/$$dir; \
+ $(ACP) -fpt $$GENERATED_MANIFEST_FILE $(TARGET_COMMON_OUT_ROOT)/R/$$dir; \
+ done;
+ $(hide) for GENERATED_R_FILE in `find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) \
+ -name R.java 2> /dev/null`; do \
+ dir=`grep package $$GENERATED_R_FILE | head -n1 | \
+ awk '{print $$2}' | tr -d ";" | tr . /`; \
+ mkdir -p $(TARGET_COMMON_OUT_ROOT)/R/$$dir; \
+ $(ACP) -fpt $$GENERATED_R_FILE $(TARGET_COMMON_OUT_ROOT)/R/$$dir \
+ || exit 31; \
+ $(ACP) -fpt $$GENERATED_R_FILE $@ || exit 32; \
+ done; \
+
+ifdef LOCAL_EXPORT_PACKAGE_RESOURCES
+# Put this module's resources into a PRODUCT-agnositc package that
+# other packages can use to build their own PRODUCT-agnostic R.java (etc.)
+# files.
+resource_export_package := $(intermediates.COMMON)/package-export.apk
+$(R_file_stamp): $(resource_export_package)
+
+# add-assets-to-package looks at PRODUCT_AAPT_CONFIG, but this target
+# can't know anything about PRODUCT. Clear it out just for this target.
+$(resource_export_package): PRODUCT_AAPT_CONFIG :=
+$(resource_export_package): $(all_res_assets) $(full_android_manifest) $(AAPT)
+ @echo "target Export Resources: $(PRIVATE_MODULE) ($@)"
+ $(create-empty-package)
+ $(add-assets-to-package)
+endif
+
+# Other modules should depend on the BUILT module if
+# they want to use this module's R.java file.
+$(LOCAL_BUILT_MODULE): $(R_file_stamp)
+
+ifneq ($(full_classes_jar),)
+# If full_classes_jar is non-empty, we're building sources.
+# If we're building sources, the initial javac step (which
+# produces full_classes_compiled_jar) needs to ensure the
+# R.java and Manifest.java files have been generated first.
+$(full_classes_compiled_jar): $(R_file_stamp)
+endif
+
+endif # all_resources
+
+ifeq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
+# We need to explicitly clear this var so that we don't
+# inherit the value from whomever caused us to be built.
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_INCLUDES :=
+else
+# Most packages should link against the resources defined by framework-res.
+# Even if they don't have their own resources, they may use framework
+# resources.
+framework_res_package_export := \
+ $(call intermediates-dir-for,APPS,framework-res,,COMMON)/package-export.apk
+$(LOCAL_INTERMEDIATE_TARGETS): \
+ PRIVATE_AAPT_INCLUDES := $(framework_res_package_export)
+# We can't depend directly on the export.apk file; it won't get its
+# PRIVATE_ vars set up correctly if we do. Instead, depend on the
+# corresponding R.stamp file, which lists the export.apk as a dependency.
+framework_res_package_export_deps := \
+ $(dir $(framework_res_package_export))src/R.stamp
+$(R_file_stamp): $(framework_res_package_export_deps)
+endif
+
+ifneq ($(full_classes_jar),)
+$(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE := $(built_dex)
+$(LOCAL_BUILT_MODULE): $(built_dex)
+endif # full_classes_jar
+
+
+# Get the list of jni libraries to be included in the apk file.
+
+so_suffix := $($(my_prefix)SHLIB_SUFFIX)
+
+jni_shared_libraries := \
+ $(addprefix $($(my_prefix)OUT_INTERMEDIATE_LIBRARIES)/, \
+ $(addsuffix $(so_suffix), \
+ $(LOCAL_JNI_SHARED_LIBRARIES)))
+
+# Pick a key to sign the package with. If this package hasn't specified
+# an explicit certificate, use the default.
+# Secure release builds will have their packages signed after the fact,
+# so it's ok for these private keys to be in the clear.
+ifeq ($(LOCAL_CERTIFICATE),)
+ LOCAL_CERTIFICATE := testkey
+endif
+# If this is not an absolute certificate, assign it to a generic one.
+ifeq ($(dir $(strip $(LOCAL_CERTIFICATE))),./)
+ LOCAL_CERTIFICATE := $(SRC_TARGET_DIR)/product/security/$(LOCAL_CERTIFICATE)
+endif
+private_key := $(LOCAL_CERTIFICATE).pk8
+certificate := $(LOCAL_CERTIFICATE).x509.pem
+
+$(LOCAL_BUILT_MODULE): $(private_key) $(certificate) $(SIGNAPK_JAR)
+$(LOCAL_BUILT_MODULE): PRIVATE_PRIVATE_KEY := $(private_key)
+$(LOCAL_BUILT_MODULE): PRIVATE_CERTIFICATE := $(certificate)
+
+PACKAGES.$(LOCAL_PACKAGE_NAME).PRIVATE_KEY := $(private_key)
+PACKAGES.$(LOCAL_PACKAGE_NAME).CERTIFICATE := $(certificate)
+
+# Define the rule to build the actual package.
+$(LOCAL_BUILT_MODULE): $(AAPT) | $(ZIPALIGN)
+$(LOCAL_BUILT_MODULE): PRIVATE_JNI_SHARED_LIBRARIES := $(jni_shared_libraries)
+$(LOCAL_BUILT_MODULE): $(all_res_assets) $(jni_shared_libraries) $(full_android_manifest)
+ @echo "target Package: $(PRIVATE_MODULE) ($@)"
+ $(create-empty-package)
+ $(add-assets-to-package)
+ifneq ($(jni_shared_libraries),)
+ $(add-jni-shared-libs-to-package)
+endif
+ifneq ($(full_classes_jar),)
+ $(add-dex-to-package)
+endif
+ $(sign-package)
+ @# Alignment must happen after all other zip operations.
+ $(align-package)
+
+# Save information about this package
+PACKAGES.$(LOCAL_PACKAGE_NAME).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
+PACKAGES.$(LOCAL_PACKAGE_NAME).RESOURCE_FILES := $(all_resources)
+
+PACKAGES := $(PACKAGES) $(LOCAL_PACKAGE_NAME)
diff --git a/core/pathmap.mk b/core/pathmap.mk
new file mode 100644
index 0000000..13cb80d
--- /dev/null
+++ b/core/pathmap.mk
@@ -0,0 +1,95 @@
+#
+# 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.
+#
+
+#
+# A central place to define mappings to paths, to avoid hard-coding
+# them in Android.mk files.
+#
+# TODO: Allow each project to define stuff like this before the per-module
+# Android.mk files are included, so we don't need to have a big central
+# list.
+#
+
+#
+# A mapping from shorthand names to include directories.
+#
+pathmap_INCL := \
+ bluedroid:system/bluetooth/bluedroid/include \
+ bluez-libs:external/bluez/libs/include \
+ bluez-utils:external/bluez/utils \
+ bootloader:bootable/bootloader/legacy/include \
+ corecg:external/skia/include/core \
+ dbus:external/dbus \
+ frameworks-base:frameworks/base/include \
+ graphics:external/skia/include/core \
+ libc:bionic/libc/include \
+ libdrm1:frameworks/base/media/libdrm/mobile1/include \
+ libdrm2:frameworks/base/media/libdrm/mobile2/include \
+ libhardware:hardware/libhardware/include \
+ libhardware_legacy:hardware/libhardware_legacy/include \
+ libhost:build/libs/host/include \
+ libm:bionic/libm/include \
+ libnativehelper:dalvik/libnativehelper/include \
+ libpagemap:system/extras/libpagemap/include \
+ libril:hardware/ril/include \
+ libstdc++:bionic/libstdc++/include \
+ libthread_db:bionic/libthread_db/include \
+ mkbootimg:system/core/mkbootimg \
+ recovery:bootable/recovery \
+ system-core:system/core/include
+
+#
+# Returns the path to the requested module's include directory,
+# relative to the root of the source tree. Does not handle external
+# modules.
+#
+# $(1): a list of modules (or other named entities) to find the includes for
+#
+define include-path-for
+$(foreach n,$(1),$(patsubst $(n):%,%,$(filter $(n):%,$(pathmap_INCL))))
+endef
+
+#
+# Many modules expect to be able to say "#include <jni.h>",
+# so make it easy for them to find the correct path.
+#
+JNI_H_INCLUDE := $(call include-path-for,libnativehelper)/nativehelper
+
+#
+# A list of all source roots under frameworks/base, which will be
+# built into the android.jar.
+#
+FRAMEWORKS_BASE_SUBDIRS := \
+ $(addsuffix /java, \
+ core \
+ graphics \
+ im \
+ location \
+ media \
+ opengl \
+ sax \
+ telephony \
+ wifi \
+ )
+
+#
+# A version of FRAMEWORKS_BASE_SUBDIRS that is expanded to full paths from
+# the root of the tree. This currently needs to be here so that other libraries
+# and apps can find the .aidl files in the framework, though we should really
+# figure out a better way to do this.
+#
+FRAMEWORKS_BASE_JAVA_SRC_DIRS := \
+ $(addprefix frameworks/base/,$(FRAMEWORKS_BASE_SUBDIRS))
diff --git a/core/prebuilt.mk b/core/prebuilt.mk
new file mode 100644
index 0000000..2d93162
--- /dev/null
+++ b/core/prebuilt.mk
@@ -0,0 +1,37 @@
+###########################################################
+## Standard rules for copying files that are prebuilt
+##
+## Additional inputs from base_rules.make:
+## None.
+##
+###########################################################
+
+ifneq ($(LOCAL_PREBUILT_LIBS),)
+$(error dont use LOCAL_PREBUILT_LIBS anymore LOCAL_PATH=$(LOCAL_PATH))
+endif
+ifneq ($(LOCAL_PREBUILT_EXECUTABLES),)
+$(error dont use LOCAL_PREBUILT_EXECUTABLES anymore LOCAL_PATH=$(LOCAL_PATH))
+endif
+ifneq ($(LOCAL_PREBUILT_JAVA_LIBRARIES),)
+$(error dont use LOCAL_PREBUILT_JAVA_LIBRARIES anymore LOCAL_PATH=$(LOCAL_PATH))
+endif
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+# Deal with the OSX library timestamp issue when installing
+# a prebuilt simulator library.
+ifneq ($(filter STATIC_LIBRARIES SHARED_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
+ prebuilt_module_is_a_library := true
+else
+ prebuilt_module_is_a_library :=
+endif
+
+$(LOCAL_BUILT_MODULE) : $(LOCAL_PATH)/$(LOCAL_SRC_FILES) | $(ACP)
+ $(transform-prebuilt-to-target)
+ifneq ($(prebuilt_module_is_a_library),)
+ ifneq ($(LOCAL_IS_HOST_MODULE),)
+ $(transform-host-ranlib-copy-hack)
+ else
+ $(transform-ranlib-copy-hack)
+ endif
+endif
diff --git a/core/prelink-linux-arm.map b/core/prelink-linux-arm.map
new file mode 100644
index 0000000..429ae1a
--- /dev/null
+++ b/core/prelink-linux-arm.map
@@ -0,0 +1,139 @@
+
+# 0xC0000000 - 0xFFFFFFFF Kernel
+# 0xB0100000 - 0xBFFFFFFF Thread 0 Stack
+# 0xB0000000 - 0xB00FFFFF Linker
+# 0xA0000000 - 0xBFFFFFFF Prelinked System Libraries
+# 0x90000000 - 0x9FFFFFFF Prelinked App Libraries
+# 0x80000000 - 0x8FFFFFFF Non-prelinked Libraries
+# 0x40000000 - 0x7FFFFFFF mmap'd stuff
+# 0x10000000 - 0x3FFFFFFF Thread Stacks
+# 0x00000000 - 0x0FFFFFFF .text / .data / heap
+
+# core system libraries
+libdl.so 0xAFF00000
+libc.so 0xAFE00000
+libstdc++.so 0xAFD00000
+libm.so 0xAFC00000
+liblog.so 0xAFBC0000
+libcutils.so 0xAFB00000
+libthread_db.so 0xAFA00000
+libz.so 0xAF900000
+libevent.so 0xAF800000
+libssl.so 0xAF700000
+libcrypto.so 0xAF500000
+
+# bluetooth
+liba2dp.so 0xAEE00000
+audio.so 0xAED00000
+input.so 0xAEC00000
+libhcid.so 0xAEB00000
+libbluedroid.so 0xAEA00000
+libbluetooth.so 0xAE900000
+libdbus.so 0xAE800000
+
+# extended system libraries
+libril.so 0xAE400000
+libreference-ril.so 0xAE000000
+libwpa_client.so 0xADC00000
+libnetutils.so 0xADB00000
+
+# core dalvik runtime support
+libandroid_servers.so 0xAD900000
+libicudata.so 0xAD600000
+libicuuc.so 0xAD500000
+libicui18n.so 0xAD400000
+libandroid_runtime.so 0xAD300000
+libnativehelper.so 0xAD200000
+libdvm-ARM.so 0xAD100000
+libdvm.so 0xAD000000
+
+# graphics
+libpixelflinger.so 0xACF00000
+libcorecg.so 0xACE00000
+libsurfaceflinger.so 0xACD00000
+libagl.so 0xACC00000
+
+libGLESv1_CM.so 0xACB00000
+libGLESv2.so 0xACA00000
+libOpenVG_CM.so 0xAC900000
+libOpenVGU_CM.so 0xAC800000
+libEGL.so 0xAC700000
+
+libexif.so 0xAC500000
+libui.so 0xAC400000
+libsgl.so 0xAC000000
+
+# audio
+libspeech.so 0xAB800000
+libaudio.so 0xAB700000
+libsonivox.so 0xAB600000
+libsoundpool.so 0xAB500000
+libvorbisidec.so 0xAB400000
+libmedia_jni.so 0xAB300000
+libmediaplayerservice.so 0xAB280000
+libmedia.so 0xAB200000
+libFFTEm.so 0xAB100000
+libaudioflinger.so 0xAB000000
+
+# assorted system libraries
+libsqlite.so 0xAAC00000
+libexpat.so 0xAAB00000
+libwebcore.so 0xAA000000
+libutils.so 0xA9D00000
+libcameraservice.so 0xA9C80000
+libhardware.so 0xA9C70000
+libhardware_legacy.so 0xA9C00000
+libapp_process.so 0xA9B00000
+libsystem_server.so 0xA9A00000
+libime.so 0xA9800000
+libgps.so 0xA9700000
+libcamera.so 0xA9680000
+libqcamera.so 0xA9400000
+
+# pv libraries
+libopencorenet_support.so 0xA7D20000
+libpvasf.so 0xA7BC0000
+libpvasfreg.so 0xA7B70000
+libopencoredownload.so 0xA7B40000
+libopencoredownloadreg.so 0xA7B00000
+libopencorenet_support.so 0xA7A00000
+libopencorertsp.so 0xA7900000
+libopencorertspreg.so 0xA7800000
+libopencoreauthor.so 0xA7600000
+libopencorecommon.so 0xA7500000
+libopencoremp4.so 0xA7400000
+libopencoremp4reg.so 0xA7300000
+libopencoreplayer.so 0xA7000000
+
+# opencore hardware support
+libmm-adspsvc.so 0xA6FFD000
+libOmxCore.so 0xA6FF0000
+libOmxMpeg4Dec.so 0xA6FC0000
+libOmxH264Dec.so 0xA6F90000
+libOmxVidEnc.so 0xA6F60000
+libopencorehw.so 0xA6F50000
+
+# libraries for specific apps or temporary libraries
+libcam_ipl.so 0x9F000000
+libwbxml.so 0x9E800000
+libwbxml_jni.so 0x9E400000
+libxml2wbxml.so 0x9E000000
+libaes.so 0x9DC00000
+libdrm1.so 0x9D800000
+libdrm1_jni.so 0x9D400000
+libwapcore.so 0x9D000000
+libstreetview.so 0x9CC00000
+libwapbrowsertest.so 0x9C800000
+libminiglobe.so 0x9C400000
+libearth.so 0x9C000000
+libembunit.so 0x9BC00000
+libneon.so 0x9B800000
+libjni_example.so 0x9B400000
+libjni_load_test.so 0x9B000000
+libjni_lib_test.so 0x9AC00000
+librunperf.so 0x9A800000
+libctest.so 0x9A700000
+libUAPI_jni.so 0x9A500000
+librpc.so 0x9A400000
+libtrace_test.so 0x9A300000
+libsrec_jni.so 0x9A200000
diff --git a/core/process_wrapper.sh b/core/process_wrapper.sh
new file mode 100755
index 0000000..9c3104e
--- /dev/null
+++ b/core/process_wrapper.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# When using a process wrapper, this is the top-level
+# command that is executed instead of the server
+# command. It starts a new xterm in which the user can
+# interact with the new process.
+#
+# Inside of the xterm is a gdb session, through which
+# the user can debug the new process.
+
+# Save away these variables, since we may loose them
+# when starting in the xterm.
+export PREV_LD_LIBRARY_PATH=$LD_LIBRARY_PATH
+export PREV_PATH=$PATH
+
+gnome-terminal -t "Wrapper: $1" --disable-factory -x $2/process_wrapper_gdb.sh "$@"
+
diff --git a/core/process_wrapper_gdb.cmds b/core/process_wrapper_gdb.cmds
new file mode 100644
index 0000000..f5bdd21
--- /dev/null
+++ b/core/process_wrapper_gdb.cmds
@@ -0,0 +1 @@
+run
diff --git a/core/process_wrapper_gdb.sh b/core/process_wrapper_gdb.sh
new file mode 100755
index 0000000..38b948a
--- /dev/null
+++ b/core/process_wrapper_gdb.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# This is the command running inside the xterm of our
+# debug wrapper. It needs to take care of starting
+# the server command, so it can attach to the parent
+# process. In addition, here we run the command inside
+# of a gdb session to allow for debugging.
+
+# On some systems, running xterm will cause LD_LIBRARY_PATH
+# to be cleared, so restore it and PATH to be safe.
+export PATH=$PREV_PATH
+export LD_LIBRARY_PATH=$PREV_LD_LIBRARY_PATH
+
+# Start binderproc (or whatever sub-command is being run)
+# inside of gdb, giving gdb an initial command script to
+# automatically run the process without user intervention.
+gdb -q -x $2/process_wrapper_gdb.cmds --args "$@"
diff --git a/core/product.mk b/core/product.mk
new file mode 100644
index 0000000..8f5dc7b
--- /dev/null
+++ b/core/product.mk
@@ -0,0 +1,156 @@
+#
+# Copyright (C) 2007 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.
+#
+
+#
+# Functions for including AndroidProducts.mk files
+#
+
+#
+# Returns the list of all AndroidProducts.mk files.
+# $(call ) isn't necessary.
+#
+define _find-android-products-files
+$(shell test -d vendor && find vendor -maxdepth 6 -name AndroidProducts.mk) \
+ $(SRC_TARGET_DIR)/product/AndroidProducts.mk
+endef
+
+#
+# Returns the sorted concatenation of all PRODUCT_MAKEFILES
+# variables set in all AndroidProducts.mk files.
+# $(call ) isn't necessary.
+#
+define get-all-product-makefiles
+$(sort \
+ $(foreach f,$(_find-android-products-files), \
+ $(eval PRODUCT_MAKEFILES :=) \
+ $(eval LOCAL_DIR := $(patsubst %/,%,$(dir $(f)))) \
+ $(eval include $(f)) \
+ $(PRODUCT_MAKEFILES) \
+ ) \
+ $(eval PRODUCT_MAKEFILES :=) \
+ $(eval LOCAL_DIR :=) \
+ )
+endef
+
+#
+# Functions for including product makefiles
+#
+
+_product_var_list := \
+ PRODUCT_NAME \
+ PRODUCT_MODEL \
+ PRODUCT_LOCALES \
+ PRODUCT_PACKAGES \
+ PRODUCT_DEVICE \
+ PRODUCT_MANUFACTURER \
+ PRODUCT_BRAND \
+ PRODUCT_PROPERTY_OVERRIDES \
+ PRODUCT_COPY_FILES \
+ PRODUCT_OTA_PUBLIC_KEYS \
+ PRODUCT_POLICY \
+ PRODUCT_PACKAGE_OVERLAYS \
+ DEVICE_PACKAGE_OVERLAYS \
+ PRODUCT_CONTRIBUTORS_FILE \
+ PRODUCT_TAGS
+
+define dump-product
+$(info ==== $(1) ====)\
+$(foreach v,$(_product_var_list),\
+$(info PRODUCTS.$(1).$(v) := $(PRODUCTS.$(1).$(v))))\
+$(info --------)
+endef
+
+define dump-products
+$(foreach p,$(PRODUCTS),$(call dump-product,$(p)))
+endef
+
+#
+# $(1): product to inherit
+#
+define inherit-product
+ $(foreach v,$(_product_var_list), \
+ $(eval $(v) := $($(v)) $(INHERIT_TAG)$(strip $(1))))
+endef
+
+#
+# $(1): product makefile list
+#
+#TODO: check to make sure that products have all the necessary vars defined
+define import-products
+$(call import-nodes,PRODUCTS,$(1),$(_product_var_list))
+endef
+
+
+#
+# Does various consistency checks on all of the known products.
+# Takes no parameters, so $(call ) is not necessary.
+#
+define check-all-products
+$(if ,, \
+ $(eval _cap_names :=) \
+ $(foreach p,$(PRODUCTS), \
+ $(eval pn := $(strip $(PRODUCTS.$(p).PRODUCT_NAME))) \
+ $(if $(pn),,$(error $(p): PRODUCT_NAME must be defined.)) \
+ $(if $(filter $(pn),$(_cap_names)), \
+ $(error $(p): PRODUCT_NAME must be unique; "$(pn)" already used by $(strip \
+ $(foreach \
+ pp,$(PRODUCTS),
+ $(if $(filter $(pn),$(PRODUCTS.$(pp).PRODUCT_NAME)), \
+ $(pp) \
+ ))) \
+ ) \
+ ) \
+ $(eval _cap_names += $(pn)) \
+ $(if $(call is-c-identifier,$(pn)),, \
+ $(error $(p): PRODUCT_NAME must be a valid C identifier, not "$(pn)") \
+ ) \
+ $(eval pb := $(strip $(PRODUCTS.$(p).PRODUCT_BRAND))) \
+ $(if $(pb),,$(error $(p): PRODUCT_BRAND must be defined.)) \
+ $(foreach cf,$(strip $(PRODUCTS.$(p).PRODUCT_COPY_FILES)), \
+ $(if $(filter 2,$(words $(subst :,$(space),$(cf)))),, \
+ $(error $(p): malformed COPY_FILE "$(cf)") \
+ ) \
+ ) \
+ ) \
+)
+endef
+
+
+#
+# Returns the product makefile path for the product with the provided name
+#
+# $(1): short product name like "generic"
+#
+define _resolve-short-product-name
+ $(eval pn := $(strip $(1)))
+ $(eval p := \
+ $(foreach p,$(PRODUCTS), \
+ $(if $(filter $(pn),$(PRODUCTS.$(p).PRODUCT_NAME)), \
+ $(p) \
+ )) \
+ )
+ $(eval p := $(sort $(p)))
+ $(if $(filter 1,$(words $(p))), \
+ $(p), \
+ $(if $(filter 0,$(words $(p))), \
+ $(error No matches for product "$(pn)"), \
+ $(error Product "$(pn)" ambiguous: matches $(p)) \
+ ) \
+ )
+endef
+define resolve-short-product-name
+$(strip $(call _resolve-short-product-name,$(1)))
+endef
diff --git a/core/product_config.mk b/core/product_config.mk
new file mode 100644
index 0000000..93671f4
--- /dev/null
+++ b/core/product_config.mk
@@ -0,0 +1,244 @@
+#
+# 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.
+#
+
+# ---------------------------------------------------------------
+# Generic functions
+# TODO: Move these to definitions.make once we're able to include
+# definitions.make before config.make.
+
+###########################################################
+## Return non-empty if $(1) is a C identifier; i.e., if it
+## matches /^[a-zA-Z_][a-zA-Z0-9_]*$/. We do this by first
+## making sure that it isn't empty and doesn't start with
+## a digit, then by removing each valid character. If the
+## final result is empty, then it was a valid C identifier.
+##
+## $(1): word to check
+###########################################################
+
+_ici_digits := 0 1 2 3 4 5 6 7 8 9
+_ici_alphaunderscore := \
+ a b c d e f g h i j k l m n o p q r s t u v w x y z \
+ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _
+define is-c-identifier
+$(strip \
+ $(if $(1), \
+ $(if $(filter $(addsuffix %,$(_ici_digits)),$(1)), \
+ , \
+ $(eval w := $(1)) \
+ $(foreach c,$(_ici_digits) $(_ici_alphaunderscore), \
+ $(eval w := $(subst $(c),,$(w))) \
+ ) \
+ $(if $(w),,TRUE) \
+ $(eval w :=) \
+ ) \
+ ) \
+ )
+endef
+
+
+# ---------------------------------------------------------------
+# Provide "PRODUCT-<prodname>-<goal>" targets, which lets you build
+# a particular configuration without needing to set up the environment.
+#
+product_goals := $(strip $(filter PRODUCT-%,$(MAKECMDGOALS)))
+ifdef product_goals
+ # Scrape the product and build names out of the goal,
+ # which should be of the form PRODUCT-<productname>-<buildname>.
+ #
+ ifneq ($(words $(product_goals)),1)
+ $(error Only one PRODUCT-* goal may be specified; saw "$(product_goals)")
+ endif
+ goal_name := $(product_goals)
+ product_goals := $(patsubst PRODUCT-%,%,$(product_goals))
+ product_goals := $(subst -, ,$(product_goals))
+ ifneq ($(words $(product_goals)),2)
+ $(error Bad PRODUCT-* goal "$(goal_name)")
+ endif
+
+ # The product they want
+ TARGET_PRODUCT := $(word 1,$(product_goals))
+
+ # The variant they want
+ TARGET_BUILD_VARIANT := $(word 2,$(product_goals))
+
+ # HACK HACK HACK
+ # The build server wants to do make PRODUCT-dream-installclean
+ # which really means TARGET_PRODUCT=dream make installclean.
+ ifneq ($(filter-out eng user userdebug tests,$(TARGET_BUILD_VARIANT)),)
+ MAKECMDGOALS := $(MAKECMDGOALS) $(TARGET_BUILD_VARIANT)
+ TARGET_BUILD_VARIANT := eng
+ default_goal_substitution :=
+ else
+ default_goal_substitution := $(DEFAULT_GOAL)
+ endif
+ # HACK HACK HACK
+
+ # Hack to make the linux build servers use dexpreopt.
+ # OSX is still a little flaky. Most engineers don't use this
+ # type of target ("make PRODUCT-blah-user"), so this should
+ # only tend to happen when using buildbot.
+ # TODO: remove this and fix the matching lines in build/core/main.mk
+ # once dexpreopt works better on OSX.
+ ifeq ($(TARGET_BUILD_VARIANT),user)
+ WITH_DEXPREOPT_buildbot := true
+ endif
+
+ # Replace the PRODUCT-* goal with the build goal that it refers to.
+ # Note that this will ensure that it appears in the same relative
+ # position, in case it matters.
+ #
+ # Note that modifying this will not affect the goals that make will
+ # attempt to build, but it's important because we inspect this value
+ # in certain situations (like for "make sdk").
+ #
+ MAKECMDGOALS := $(patsubst $(goal_name),$(default_goal_substitution),$(MAKECMDGOALS))
+
+ # Define a rule for the PRODUCT-* goal, and make it depend on the
+ # patched-up command-line goals as well as any other goals that we
+ # want to force.
+ #
+.PHONY: $(goal_name)
+$(goal_name): $(MAKECMDGOALS)
+endif
+# else: Use the value set in the environment or buildspec.mk.
+
+# ---------------------------------------------------------------
+# Include the product definitions.
+# We need to do this to translate TARGET_PRODUCT into its
+# underlying TARGET_DEVICE before we start defining any rules.
+#
+include $(BUILD_SYSTEM)/node_fns.mk
+include $(BUILD_SYSTEM)/product.mk
+include $(BUILD_SYSTEM)/device.mk
+
+# Read in all of the product definitions specified by the AndroidProducts.mk
+# files in the tree.
+#
+#TODO: when we start allowing direct pointers to product files,
+# guarantee that they're in this list.
+$(call import-products, $(get-all-product-makefiles))
+$(check-all-products)
+#$(dump-products)
+#$(error done)
+
+# Convert a short name like "sooner" into the path to the product
+# file defining that product.
+#
+INTERNAL_PRODUCT := $(call resolve-short-product-name, $(TARGET_PRODUCT))
+#$(error TARGET_PRODUCT $(TARGET_PRODUCT) --> $(INTERNAL_PRODUCT))
+
+# Find the device that this product maps to.
+TARGET_DEVICE := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEVICE)
+
+# Figure out which resoure configuration options to use for this
+# product.
+PRODUCT_LOCALES := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_LOCALES))
+# TODO: also keep track of things like "port", "land" in product files.
+
+# If CUSTOM_LOCALES contains any locales not already included
+# in PRODUCT_LOCALES, add them to PRODUCT_LOCALES.
+extra_locales := $(filter-out $(PRODUCT_LOCALES),$(CUSTOM_LOCALES))
+ifneq (,$(extra_locales))
+ $(info Adding CUSTOM_LOCALES [$(extra_locales)] to PRODUCT_LOCALES [$(PRODUCT_LOCALES)])
+ PRODUCT_LOCALES += $(extra_locales)
+ extra_locales :=
+endif
+
+# Assemble the list of options.
+PRODUCT_AAPT_CONFIG := $(PRODUCT_LOCALES)
+
+# Convert spaces to commas.
+comma := ,
+PRODUCT_AAPT_CONFIG := \
+ $(subst $(space),$(comma),$(strip $(PRODUCT_AAPT_CONFIG)))
+
+PRODUCT_BRAND := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_BRAND))
+
+PRODUCT_MODEL := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_MODEL))
+ifndef PRODUCT_MODEL
+ PRODUCT_MODEL := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_NAME))
+endif
+
+PRODUCT_MANUFACTURER := \
+ $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_MANUFACTURER))
+ifndef PRODUCT_MANUFACTURER
+ PRODUCT_MANUFACTURER := unknown
+endif
+
+# Which policy should this product use
+PRODUCT_POLICY := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_POLICY))
+
+# A list of words like <source path>:<destination path>. The file at
+# the source path should be copied to the destination path when building
+# this product. <destination path> is relative to $(PRODUCT_OUT), so
+# it should look like, e.g., "system/etc/file.xml". The rules
+# for these copy steps are defined in config/Makefile.
+PRODUCT_COPY_FILES := \
+ $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_COPY_FILES))
+
+# The HTML file containing the contributors to the project.
+PRODUCT_CONTRIBUTORS_FILE := \
+ $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_CONTRIBUTORS_FILE))
+
+# A list of property assignments, like "key = value", with zero or more
+# whitespace characters on either side of the '='.
+PRODUCT_PROPERTY_OVERRIDES := \
+ $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PROPERTY_OVERRIDES))
+
+# Should we use the default resources or add any product specific overlays
+PRODUCT_PACKAGE_OVERLAYS := \
+ $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGE_OVERLAYS))
+DEVICE_PACKAGE_OVERLAYS := \
+ $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).DEVICE_PACKAGE_OVERLAYS))
+
+# An list of whitespace-separated words.
+PRODUCT_TAGS := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_TAGS))
+
+# Add the product-defined properties to the build properties.
+ADDITIONAL_BUILD_PROPERTIES := \
+ $(ADDITIONAL_BUILD_PROPERTIES) \
+ $(PRODUCT_PROPERTY_OVERRIDES)
+
+# Get the list of OTA public keys for the product.
+OTA_PUBLIC_KEYS := \
+ $(sort \
+ $(OTA_PUBLIC_KEYS) \
+ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_OTA_PUBLIC_KEYS) \
+ )
+
+# HACK: Not all products define OTA keys yet, and the -user build
+# will fail if no keys are defined.
+# TODO: Let a product opt out of needing OTA keys, and stop defaulting to
+# the test key as soon as possible.
+ifeq (,$(strip $(OTA_PUBLIC_KEYS)))
+ ifeq (,$(CALLED_FROM_SETUP))
+ $(warning WARNING: adding test OTA key)
+ endif
+ OTA_PUBLIC_KEYS := $(SRC_TARGET_DIR)/product/security/testkey.x509.pem
+endif
+
+# ---------------------------------------------------------------
+# Force the simulator to be the simulator, and make BUILD_TYPE
+# default to debug.
+ifeq ($(TARGET_PRODUCT),sim)
+ TARGET_SIMULATOR := true
+ ifeq (,$(strip $(TARGET_BUILD_TYPE)))
+ TARGET_BUILD_TYPE := debug
+ endif
+ # dexpreopt doesn't work when building the simulator
+ DISABLE_DEXPREOPT := true
+endif
diff --git a/core/raw_executable.mk b/core/raw_executable.mk
new file mode 100644
index 0000000..30e0ade
--- /dev/null
+++ b/core/raw_executable.mk
@@ -0,0 +1,26 @@
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE_SUFFIX :=
+LOCAL_FORCE_STATIC_EXECUTABLE := true
+
+include $(BUILD_SYSTEM)/binary.mk
+
+$(LOCAL_BUILT_MODULE) : PRIVATE_ELF_FILE := $(intermediates)/$(PRIVATE_MODULE).elf
+$(LOCAL_BUILT_MODULE) : PRIVATE_LIBS := `$(TARGET_CC) -mthumb-interwork -print-libgcc-file-name`
+
+$(all_objects) : TARGET_PROJECT_INCLUDES :=
+$(all_objects) : TARGET_C_INCLUDES :=
+$(all_objects) : TARGET_GLOBAL_CFLAGS :=
+$(all_objects) : TARGET_GLOBAL_CPPFLAGS :=
+
+$(LOCAL_BUILT_MODULE): $(all_objects) $(all_libraries)
+ @$(mkdir -p $(dir $@)
+ @echo "target Linking: $(PRIVATE_MODULE)"
+ $(hide) $(TARGET_LD) \
+ $(addprefix --script ,$(PRIVATE_LINK_SCRIPT)) \
+ $(PRIVATE_RAW_EXECUTABLE_LDFLAGS) \
+ -o $(PRIVATE_ELF_FILE) \
+ $(PRIVATE_ALL_OBJECTS) \
+ --start-group $(PRIVATE_ALL_STATIC_LIBRARIES) --end-group \
+ $(PRIVATE_LIBS)
+ $(hide) $(TARGET_OBJCOPY) -O binary $(PRIVATE_ELF_FILE) $@
+
diff --git a/core/raw_static_library.mk b/core/raw_static_library.mk
new file mode 100644
index 0000000..f7b11ef
--- /dev/null
+++ b/core/raw_static_library.mk
@@ -0,0 +1,5 @@
+
+LOCAL_RAW_STATIC_LIBRARY:=true
+
+include $(BUILD_STATIC_LIBRARY)
+
diff --git a/core/root.mk b/core/root.mk
new file mode 100644
index 0000000..6c8f795
--- /dev/null
+++ b/core/root.mk
@@ -0,0 +1,3 @@
+### DO NOT EDIT THIS FILE ###
+include build/core/main.mk
+### DO NOT EDIT THIS FILE ###
diff --git a/core/shared_library.mk b/core/shared_library.mk
new file mode 100644
index 0000000..a30d868
--- /dev/null
+++ b/core/shared_library.mk
@@ -0,0 +1,32 @@
+###########################################################
+## Standard rules for building a normal shared library.
+##
+## Additional inputs from base_rules.make:
+## None.
+##
+## LOCAL_MODULE_SUFFIX will be set for you.
+###########################################################
+
+ifeq ($(strip $(LOCAL_MODULE_CLASS)),)
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+endif
+ifeq ($(strip $(LOCAL_MODULE_SUFFIX)),)
+LOCAL_MODULE_SUFFIX := $(TARGET_SHLIB_SUFFIX)
+endif
+ifeq ($(strip $(LOCAL_PRELINK_MODULE)),)
+LOCAL_PRELINK_MODULE := $(strip $(TARGET_PRELINK_MODULE))
+endif
+ifneq ($(strip $(OVERRIDE_BUILT_MODULE_PATH)),)
+$(error $(LOCAL_PATH): Illegal use of OVERRIDE_BUILT_MODULE_PATH)
+endif
+
+# Put the built targets of all shared libraries in a common directory
+# to simplify the link line.
+OVERRIDE_BUILT_MODULE_PATH := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)
+
+include $(BUILD_SYSTEM)/dynamic_binary.mk
+
+$(linked_module): $(all_objects) $(all_libraries) \
+ $(LOCAL_ADDITIONAL_DEPENDENCIES) \
+ $(TARGET_CRTBEGIN_SO_O) $(TARGET_CRTEND_SO_O)
+ $(transform-o-to-shared-lib)
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
new file mode 100644
index 0000000..93d770a
--- /dev/null
+++ b/core/static_java_library.mk
@@ -0,0 +1,25 @@
+#
+# 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.
+#
+
+# Standard rules for building a "static" java library.
+# Static java libraries are not installed, nor listed on any
+# classpaths. They can, however, be included wholesale in
+# other java modules.
+
+LOCAL_UNINSTALLABLE_MODULE := true
+LOCAL_IS_STATIC_JAVA_LIBRARY := true
+include $(BUILD_SYSTEM)/java_library.mk
+LOCAL_IS_STATIC_JAVA_LIBRARY :=
diff --git a/core/static_library.mk b/core/static_library.mk
new file mode 100644
index 0000000..252dfd0
--- /dev/null
+++ b/core/static_library.mk
@@ -0,0 +1,29 @@
+###########################################################
+## Standard rules for building a static library.
+##
+## Additional inputs from base_rules.make:
+## None.
+##
+## LOCAL_MODULE_SUFFIX will be set for you.
+###########################################################
+
+ifeq ($(strip $(LOCAL_MODULE_CLASS)),)
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+endif
+ifeq ($(strip $(LOCAL_MODULE_SUFFIX)),)
+LOCAL_MODULE_SUFFIX := .a
+endif
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/binary.mk
+
+ifeq ($(LOCAL_RAW_STATIC_LIBRARY),true)
+LOCAL_RAW_STATIC_LIBRARY:=
+$(all_objects) : TARGET_PROJECT_INCLUDES :=
+$(all_objects) : TARGET_C_INCLUDES :=
+$(all_objects) : TARGET_GLOBAL_CFLAGS :=
+$(all_objects) : TARGET_GLOBAL_CPPFLAGS :=
+endif
+
+$(LOCAL_BUILT_MODULE): $(all_objects)
+ $(transform-o-to-static-lib)
diff --git a/core/tasks/apicheck.mk b/core/tasks/apicheck.mk
new file mode 100644
index 0000000..044e4af
--- /dev/null
+++ b/core/tasks/apicheck.mk
@@ -0,0 +1,76 @@
+# 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.
+
+#
+# Rules for running apicheck to confirm that you haven't broken
+# api compatibility or added apis illegally.
+#
+
+ifneq ($(BUILD_TINY_ANDROID), true)
+
+.PHONY: checkapi
+
+# eval this to define a rule that runs apicheck.
+#
+# Args:
+# $(1) target
+# $(2) stable api xml file
+# $(3) api xml file to be tested
+# $(4) arguments for apicheck
+# $(5) command to run if apicheck failed
+define check-api
+$(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/$(strip $(1))-timestamp: $(2) $(3) $(APICHECK)
+ @echo "Checking API:" $(1)
+ $(hide) ( $(APICHECK) $(4) $(2) $(3) || ( $(5) ; exit 38 ) )
+ $(hide) mkdir -p $$(dir $$@)
+ $(hide) touch $$@
+checkapi: $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/$(strip $(1))-timestamp
+endef
+
+# Run the checkapi rules by default.
+droidcore: checkapi
+
+# INTERNAL_PLATFORM_API_FILE is the one build by droiddoc.
+
+# Check that the API we're building hasn't broken the last-released
+# SDK version.
+$(eval $(call check-api, \
+ checkapi-last, \
+ $(SRC_API_DIR)/$(lastword $(TARGET_AVAILABLE_SDK_VERSIONS)).xml, \
+ $(INTERNAL_PLATFORM_API_FILE), \
+ -hide 2 -hide 3 -hide 4 -hide 5 -hide 6 -hide 24 -hide 25 \
+ -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
+ -error 16 -error 17 -error 18 , \
+ cat $(BUILD_SYSTEM)/apicheck_msg_last.txt \
+ ))
+
+# Check that the API we're building hasn't changed from the not-yet-released
+# SDK version.
+$(eval $(call check-api, \
+ checkapi-current, \
+ $(SRC_API_DIR)/current.xml, \
+ $(INTERNAL_PLATFORM_API_FILE), \
+ -error 2 -error 3 -error 4 -error 5 -error 6 \
+ -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
+ -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \
+ -error 25 , \
+ cat $(BUILD_SYSTEM)/apicheck_msg_current.txt \
+ ))
+
+.PHONY: update-api
+update-api: $(INTERNAL_PLATFORM_API_FILE) | $(ACP)
+ @echo Copying current.xml
+ $(hide) $(ACP) $(INTERNAL_PLATFORM_API_FILE) $(SRC_API_DIR)/current.xml
+
+endif
diff --git a/core/tasks/cts.mk b/core/tasks/cts.mk
new file mode 100644
index 0000000..9ef99db
--- /dev/null
+++ b/core/tasks/cts.mk
@@ -0,0 +1,95 @@
+# 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.
+
+cts_dir := $(HOST_OUT)/cts
+cts_tools_src_dir := cts/tools
+
+cts_name := android-cts
+
+CTS_EXECUTABLE := cts
+ifeq ($(HOST_OS),windows)
+ CTS_EXECUTABLE_PATH := $(cts_tools_src_dir)/host/etc/cts.bat
+else
+ CTS_EXECUTABLE_PATH := $(HOST_OUT_EXECUTABLES)/$(CTS_EXECUTABLE)
+endif
+CTS_HOST_JAR := $(HOST_OUT_JAVA_LIBRARIES)/cts.jar
+
+CTS_CASE_LIST := \
+ DeviceInfoCollector \
+ CtsTestStubs \
+ CtsAppTestCases \
+ CtsContentTestCases \
+ CtsDatabaseTestCases \
+ CtsGraphicsTestCases \
+ CtsLocationTestCases \
+ CtsOsTestCases \
+ CtsProviderTestCases \
+ CtsTextTestCases \
+ CtsUtilTestCases \
+ CtsViewTestCases \
+ CtsWidgetTestCases \
+ CtsNetTestCases \
+ SignatureTest
+
+DEFAULT_TEST_PLAN := $(PRIVATE_DIR)/resource/plans
+
+$(cts_dir)/all_cts_files_stamp: $(CTS_CASE_LIST) | $(ACP)
+# Make necessary directory for CTS
+ @rm -rf $(PRIVATE_CTS_DIR)
+ @mkdir -p $(TMP_DIR)
+ @mkdir -p $(PRIVATE_DIR)/docs
+ @mkdir -p $(PRIVATE_DIR)/tools
+ @mkdir -p $(PRIVATE_DIR)/repository/testcases
+ @mkdir -p $(PRIVATE_DIR)/repository/plans
+# Copy executable to CTS directory
+ $(hide) $(ACP) -fp $(CTS_HOST_JAR) $(PRIVATE_DIR)/tools
+ $(hide) $(ACP) -fp $(CTS_EXECUTABLE_PATH) $(PRIVATE_DIR)/tools
+# Change mode of the executables
+ $(hide) chmod ug+rwX $(PRIVATE_DIR)/tools/$(notdir $(CTS_EXECUTABLE_PATH))
+ $(foreach apk,$(CTS_CASE_LIST), \
+ $(call copy-testcase-apk,$(apk)))
+# Copy CTS host config and start script to CTS directory
+ $(hide) $(ACP) -fp $(cts_tools_src_dir)/utils/host_config.xml $(PRIVATE_DIR)/repository/
+ $(hide) $(ACP) -fp $(cts_tools_src_dir)/utils/startcts $(PRIVATE_DIR)/tools/
+ $(hide) touch $@
+
+# Generate the default test plan for User.
+$(DEFAULT_TEST_PLAN): $(cts_dir)/all_cts_files_stamp $(cts_tools_src_dir)/utils/genDefaultTestPlan.sh
+ $(hide) bash $(cts_tools_src_dir)/utils/genDefaultTestPlan.sh cts/tests/tests/ \
+ $(PRIVATE_DIR) $(TMP_DIR) $(TOP) $(TARGET_COMMON_OUT_ROOT) $(OUT_DIR)
+
+# Package CTS and clean up.
+#
+# TODO:
+# Pack cts.bat into the same zip file as well. See http://buganizer/issue?id=1656821 for more details
+INTERNAL_CTS_TARGET := $(cts_dir)/$(cts_name).zip
+$(INTERNAL_CTS_TARGET): PRIVATE_NAME := $(cts_name)
+$(INTERNAL_CTS_TARGET): PRIVATE_CTS_DIR := $(cts_dir)
+$(INTERNAL_CTS_TARGET): PRIVATE_DIR := $(cts_dir)/$(cts_name)
+$(INTERNAL_CTS_TARGET): TMP_DIR := $(cts_dir)/temp
+$(INTERNAL_CTS_TARGET): $(cts_dir)/all_cts_files_stamp $(DEFAULT_TEST_PLAN)
+ @echo "Package CTS: $@"
+ $(hide) cd $(dir $@) && zip -rq $(notdir $@) $(PRIVATE_NAME)
+
+.PHONY: cts
+cts: $(INTERNAL_CTS_TARGET) adb
+$(call dist-for-goals,cts,$(INTERNAL_CTS_TARGET))
+
+define copy-testcase-apk
+
+$(hide) $(ACP) -fp $(call intermediates-dir-for,APPS,$(1))/package.apk \
+ $(PRIVATE_DIR)/repository/testcases/$(1).apk
+
+endef
+
diff --git a/core/tasks/localize.mk b/core/tasks/localize.mk
new file mode 100644
index 0000000..12e7b5c
--- /dev/null
+++ b/core/tasks/localize.mk
@@ -0,0 +1,47 @@
+# 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.
+
+#
+# Rules for building the xlb files for export for translation.
+#
+
+# Gather all of the resource files for the default locale -- that is,
+# all resources in directories called values or values-something, where
+# one of the - separated segments is not two characters long -- those are the
+# language directories, and we don't want those.
+all_resource_files := $(foreach pkg, \
+ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES), \
+ $(PACKAGES.$(pkg).RESOURCE_FILES))
+values_resource_files := $(shell echo $(all_resource_files) | \
+ tr -s / | \
+ tr " " "\n" | \
+ grep -E "\/values[^/]*/(strings.xml|arrays.xml)$$" | \
+ grep -v -E -e "-[a-zA-Z]{2}[/\-]")
+
+xlb_target := $(PRODUCT_OUT)/strings.xlb
+
+$(xlb_target): $(values_resource_files) | $(LOCALIZE)
+ @echo XLB: $@
+ $(hide) mkdir -p $(dir $@)
+ $(hide) rm -f $@
+ $(hide) $(LOCALIZE) xlb $@ $^
+
+# Add a phony target so typing make xlb is convenient
+.PHONY: xlb
+xlb: $(xlb_target)
+
+# We want this on the build-server builds, but no reason to inflict it on
+# everyone
+$(call dist-for-goals, droid, $(xlb_target))
+
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
new file mode 100644
index 0000000..e38a803
--- /dev/null
+++ b/core/version_defaults.mk
@@ -0,0 +1,84 @@
+#
+# 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.
+#
+
+#
+# Handle various build version information.
+#
+# Guarantees that the following are defined:
+# PLATFORM_VERSION
+# PLATFORM_SDK_VERSION
+# BUILD_ID
+# BUILD_NUMBER
+#
+
+# Look for an optional file containing overrides of the defaults,
+# but don't cry if we don't find it. We could just use -include, but
+# the build.prop target also wants INTERNAL_BUILD_ID_MAKEFILE to be set
+# if the file exists.
+#
+INTERNAL_BUILD_ID_MAKEFILE := $(wildcard $(BUILD_SYSTEM)/build_id.mk)
+ifneq "" "$(INTERNAL_BUILD_ID_MAKEFILE)"
+ include $(INTERNAL_BUILD_ID_MAKEFILE)
+endif
+
+ifeq "" "$(PLATFORM_VERSION)"
+ # This is the canonical definition of the platform version,
+ # which is the version that we reveal to the end user.
+ # Update this value when the platform version changes (rather
+ # than overriding it somewhere else). Can be an arbitrary string.
+ PLATFORM_VERSION := 1.5
+endif
+
+ifeq "" "$(PLATFORM_SDK_VERSION)"
+ # This is the canonical definition of the SDK version, which defines
+ # the set of APIs and functionality available in the platform. This is
+ # a single integer, that increases monotonically as updates to the SDK
+ # are released.
+ PLATFORM_SDK_VERSION := 3
+endif
+
+ifeq "" "$(BUILD_ID)"
+ # Used to signify special builds. E.g., branches and/or releases,
+ # like "M5-RC7". Can be an arbitrary string, but must be a single
+ # word and a valid file name.
+ #
+ # If there is no BUILD_ID set, make it obvious.
+ BUILD_ID := UNKNOWN
+endif
+
+ifeq "" "$(BUILD_NUMBER)"
+ # BUILD_NUMBER should be set to the source control value that
+ # represents the current state of the source code. E.g., a
+ # perforce changelist number or a git hash. Can be an arbitrary string
+ # (to allow for source control that uses something other than numbers),
+ # but must be a single word and a valid file name.
+ #
+ # If no BUILD_NUMBER is set, create a useful "I am an engineering build
+ # from this date/time" value. Make it start with a non-digit so that
+ # anyone trying to parse it as an integer will probably get "0".
+ BUILD_NUMBER := eng.$(USER).$(shell date +%Y%m%d.%H%M%S)
+endif
+
+ifeq "true" "$(DISPLAY_BUILD_NUMBER)"
+ # if the build_id.mk has this defined, then BUILD_ID is updated with
+ # the BUILD_NUMBER as well. For development branches, this will be
+ # set, but release branches this will not be set.
+ BUILD_DISPLAY_ID := "$(BUILD_ID).$(BUILD_NUMBER)"
+else
+ BUILD_DISPLAY_ID := "$(BUILD_ID)"
+endif
+
+
diff --git a/envsetup.sh b/envsetup.sh
new file mode 100644
index 0000000..016c399
--- /dev/null
+++ b/envsetup.sh
@@ -0,0 +1,1037 @@
+function help() {
+cat <<EOF
+Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment:
+- croot: Changes directory to the top of the tree.
+- m: Makes from the top of the tree.
+- mm: Builds all of the modules in the current directory.
+- mmm: Builds all of the modules in the supplied directories.
+- cgrep: Greps on all local C/C++ files.
+- jgrep: Greps on all local Java files.
+- resgrep: Greps on all local res/*.xml files.
+- godir: Go to the directory containing a file.
+
+Look at the source to view more functions. The complete list is:
+EOF
+ T=$(gettop)
+ local A
+ A=""
+ for i in `cat $T/build/envsetup.sh | sed -n "/^function /s/function \([a-z_]*\).*/\1/p" | sort`; do
+ A="$A $i"
+ done
+ echo $A
+}
+
+# Get the value of a build variable as an absolute path.
+function get_abs_build_var()
+{
+ T=$(gettop)
+ if [ ! "$T" ]; then
+ echo "Couldn't locate the top of the tree. Try setting TOP." >&2
+ return
+ fi
+ CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
+ make --no-print-directory -C "$T" -f build/core/config.mk dumpvar-abs-$1
+}
+
+# Get the exact value of a build variable.
+function get_build_var()
+{
+ T=$(gettop)
+ if [ ! "$T" ]; then
+ echo "Couldn't locate the top of the tree. Try setting TOP." >&2
+ return
+ fi
+ CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
+ make --no-print-directory -C "$T" -f build/core/config.mk dumpvar-$1
+}
+
+# check to see if the supplied product is one we can build
+function check_product()
+{
+ T=$(gettop)
+ if [ ! "$T" ]; then
+ echo "Couldn't locate the top of the tree. Try setting TOP." >&2
+ return
+ fi
+ CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
+ TARGET_PRODUCT=$1 TARGET_BUILD_VARIANT= \
+ TARGET_SIMULATOR= TARGET_BUILD_TYPE= \
+ get_build_var TARGET_DEVICE > /dev/null
+ # hide successful answers, but allow the errors to show
+}
+
+VARIANT_CHOICES=(user userdebug eng)
+
+# check to see if the supplied variant is valid
+function check_variant()
+{
+ for v in ${VARIANT_CHOICES[@]}
+ do
+ if [ "$v" = "$1" ]
+ then
+ return 0
+ fi
+ done
+ return 1
+}
+
+function setpaths()
+{
+ T=$(gettop)
+ if [ ! "$T" ]; then
+ echo "Couldn't locate the top of the tree. Try setting TOP."
+ return
+ fi
+
+ ##################################################################
+ # #
+ # Read me before you modify this code #
+ # #
+ # This function sets ANDROID_BUILD_PATHS to what it is adding #
+ # to PATH, and the next time it is run, it removes that from #
+ # PATH. This is required so lunch can be run more than once #
+ # and still have working paths. #
+ # #
+ ##################################################################
+
+ # out with the old
+ if [ -n $ANDROID_BUILD_PATHS ] ; then
+ export PATH=${PATH/$ANDROID_BUILD_PATHS/}
+ fi
+
+ # and in with the new
+ CODE_REVIEWS=
+ prebuiltdir=$(getprebuilt)
+ export ANDROID_EABI_TOOLCHAIN=$prebuiltdir/toolchain/arm-eabi-4.2.1/bin
+ export ANDROID_TOOLCHAIN=$ANDROID_EABI_TOOLCHAIN
+ 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 PATH=$PATH$ANDROID_BUILD_PATHS
+
+ unset ANDROID_PRODUCT_OUT
+ export ANDROID_PRODUCT_OUT=$(get_abs_build_var PRODUCT_OUT)
+ export OUT=$ANDROID_PRODUCT_OUT
+
+ # needed for building linux on MacOS
+ # TODO: fix the path
+ #export HOST_EXTRACFLAGS="-I "$T/system/kernel_headers/host_include
+
+ # needed for OProfile to post-process collected samples
+ export OPROFILE_EVENTS_DIR=$prebuiltdir/oprofile
+}
+
+function printconfig()
+{
+ T=$(gettop)
+ if [ ! "$T" ]; then
+ echo "Couldn't locate the top of the tree. Try setting TOP." >&2
+ return
+ fi
+ get_build_var report_config
+}
+
+function set_stuff_for_environment()
+{
+ settitle
+ setpaths
+ set_sequence_number
+
+ # Don't try to do preoptimization until it works better on OSX.
+ export DISABLE_DEXPREOPT=true
+
+ export ANDROID_BUILD_TOP=$(gettop)
+}
+
+function set_sequence_number()
+{
+ export BUILD_ENV_SEQUENCE_NUMBER=9
+}
+
+function settitle()
+{
+ if [ "$STAY_OFF_MY_LAWN" = "" ]; then
+ local product=$(get_build_var TARGET_PRODUCT)
+ local variant=$(get_build_var TARGET_BUILD_VARIANT)
+ export PROMPT_COMMAND="echo -ne \"\033]0;[${product}-${variant}] ${USER}@${HOSTNAME}: ${PWD}\007\""
+ fi
+}
+
+case `uname -s` in
+ Linux)
+ function choosesim()
+ {
+ echo "Build for the simulator or the device?"
+ echo " 1. Device"
+ echo " 2. Simulator"
+ echo
+
+ export TARGET_SIMULATOR=
+ local ANSWER
+ while [ -z $TARGET_SIMULATOR ]
+ do
+ echo -n "Which would you like? [1] "
+ if [ -z "$1" ] ; then
+ read ANSWER
+ else
+ echo $1
+ ANSWER=$1
+ fi
+ case $ANSWER in
+ "")
+ export TARGET_SIMULATOR=false
+ ;;
+ 1)
+ export TARGET_SIMULATOR=false
+ ;;
+ Device)
+ export TARGET_SIMULATOR=false
+ ;;
+ 2)
+ export TARGET_SIMULATOR=true
+ ;;
+ Simulator)
+ export TARGET_SIMULATOR=true
+ ;;
+ *)
+ echo
+ echo "I didn't understand your response. Please try again."
+ echo
+ ;;
+ esac
+ if [ -n "$1" ] ; then
+ break
+ fi
+ done
+
+ set_stuff_for_environment
+ }
+ ;;
+ *)
+ function choosesim()
+ {
+ echo "Only device builds are supported for" `uname -s`
+ echo " Forcing TARGET_SIMULATOR=false"
+ echo
+ if [ -z "$1" ]
+ then
+ echo -n "Press enter: "
+ read
+ fi
+
+ export TARGET_SIMULATOR=false
+ set_stuff_for_environment
+ }
+ ;;
+esac
+
+function choosetype()
+{
+ echo "Build type choices are:"
+ echo " 1. release"
+ echo " 2. debug"
+ echo
+
+ local DEFAULT_NUM DEFAULT_VALUE
+ if [ $TARGET_SIMULATOR = "false" ] ; then
+ DEFAULT_NUM=1
+ DEFAULT_VALUE=release
+ else
+ DEFAULT_NUM=2
+ DEFAULT_VALUE=debug
+ fi
+
+ export TARGET_BUILD_TYPE=
+ local ANSWER
+ while [ -z $TARGET_BUILD_TYPE ]
+ do
+ echo -n "Which would you like? ["$DEFAULT_NUM"] "
+ if [ -z "$1" ] ; then
+ read ANSWER
+ else
+ echo $1
+ ANSWER=$1
+ fi
+ case $ANSWER in
+ "")
+ export TARGET_BUILD_TYPE=$DEFAULT_VALUE
+ ;;
+ 1)
+ export TARGET_BUILD_TYPE=release
+ ;;
+ release)
+ export TARGET_BUILD_TYPE=release
+ ;;
+ 2)
+ export TARGET_BUILD_TYPE=debug
+ ;;
+ debug)
+ export TARGET_BUILD_TYPE=debug
+ ;;
+ *)
+ echo
+ echo "I didn't understand your response. Please try again."
+ echo
+ ;;
+ esac
+ if [ -n "$1" ] ; then
+ break
+ fi
+ done
+
+ set_stuff_for_environment
+}
+
+#
+# This function isn't really right: It chooses a TARGET_PRODUCT
+# based on the list of boards. Usually, that gets you something
+# that kinda works with a generic product, but really, you should
+# pick a product by name.
+#
+function chooseproduct()
+{
+ # Find the makefiles that must exist for a product.
+ # Send stderr to /dev/null in case partner isn't present.
+ local -a choices
+ choices=(`/bin/ls build/target/board/*/BoardConfig.mk vendor/*/*/BoardConfig.mk 2> /dev/null`)
+
+ local choice
+ local -a prodlist
+ for choice in ${choices[@]}
+ do
+ # The product name is the name of the directory containing
+ # the makefile we found, above.
+ prodlist=(${prodlist[@]} `dirname ${choice} | xargs basename`)
+ done
+
+ local index=1
+ local p
+ echo "Product choices are:"
+ for p in ${prodlist[@]}
+ do
+ echo " $index. $p"
+ let "index = $index + 1"
+ done
+
+
+ if [ "x$TARGET_PRODUCT" != x ] ; then
+ default_value=$TARGET_PRODUCT
+ else
+ if [ "$TARGET_SIMULATOR" = true ] ; then
+ default_value=sim
+ else
+ default_value=generic
+ fi
+ fi
+
+ export TARGET_PRODUCT=
+ local ANSWER
+ while [ -z "$TARGET_PRODUCT" ]
+ do
+ echo "You can also type the name of a product if you know it."
+ echo -n "Which would you like? [$default_value] "
+ if [ -z "$1" ] ; then
+ read ANSWER
+ else
+ echo $1
+ ANSWER=$1
+ fi
+
+ if [ -z "$ANSWER" ] ; then
+ export TARGET_PRODUCT=$default_value
+ elif (echo -n $ANSWER | grep -q -e "^[0-9][0-9]*$") ; then
+ local poo=`echo -n $ANSWER`
+ if [ $poo -le ${#prodlist[@]} ] ; then
+ export TARGET_PRODUCT=${prodlist[$(($ANSWER-$_arrayoffset))]}
+ else
+ echo "** Bad product selection: $ANSWER"
+ fi
+ else
+ if check_product $ANSWER
+ then
+ export TARGET_PRODUCT=$ANSWER
+ else
+ echo "** Not a valid product: $ANSWER"
+ fi
+ fi
+ if [ -n "$1" ] ; then
+ break
+ fi
+ done
+
+ set_stuff_for_environment
+}
+
+function choosevariant()
+{
+ echo "Variant choices are:"
+ local index=1
+ local v
+ for v in ${VARIANT_CHOICES[@]}
+ do
+ # The product name is the name of the directory containing
+ # the makefile we found, above.
+ echo " $index. $v"
+ index=$(($index+1))
+ done
+
+ local default_value=eng
+ local ANSWER
+
+ export TARGET_BUILD_VARIANT=
+ while [ -z "$TARGET_BUILD_VARIANT" ]
+ do
+ echo -n "Which would you like? [$default_value] "
+ if [ -z "$1" ] ; then
+ read ANSWER
+ else
+ echo $1
+ ANSWER=$1
+ fi
+
+ if [ -z "$ANSWER" ] ; then
+ export TARGET_BUILD_VARIANT=$default_value
+ elif (echo -n $ANSWER | grep -q -e "^[0-9][0-9]*$") ; then
+ if [ "$ANSWER" -le "${#VARIANT_CHOICES[@]}" ] ; then
+ export TARGET_BUILD_VARIANT=${VARIANT_CHOICES[$(($ANSWER-$_arrayoffset))]}
+ fi
+ else
+ if check_variant $ANSWER
+ then
+ export TARGET_BUILD_VARIANT=$ANSWER
+ else
+ echo "** Not a valid variant: $ANSWER"
+ fi
+ fi
+ if [ -n "$1" ] ; then
+ break
+ fi
+ done
+}
+
+function tapas()
+{
+ choosecombo
+}
+
+function choosecombo()
+{
+ choosesim $1
+
+ echo
+ echo
+ choosetype $2
+
+ echo
+ echo
+ chooseproduct $3
+
+ echo
+ echo
+ choosevariant $4
+
+ echo
+ set_stuff_for_environment
+ printconfig
+}
+
+# Clear this variable. It will be built up again when the vendorsetup.sh
+# files are included at the end of this file.
+unset LUNCH_MENU_CHOICES
+function add_lunch_combo()
+{
+ local new_combo=$1
+ local c
+ for c in ${LUNCH_MENU_CHOICES[@]} ; do
+ if [ "$new_combo" = "$c" ] ; then
+ return
+ fi
+ done
+ LUNCH_MENU_CHOICES=(${LUNCH_MENU_CHOICES[@]} $new_combo)
+}
+
+# add the default one here
+add_lunch_combo generic-eng
+
+# if we're on linux, add the simulator. There is a special case
+# in lunch to deal with the simulator
+if [ "$(uname)" = "Linux" ] ; then
+ add_lunch_combo simulator
+fi
+
+function print_lunch_menu()
+{
+ local uname=$(uname)
+ echo
+ echo "You're building on" $uname
+ echo
+ echo ${LUNCH_MENU_CHOICES[@]}
+ echo "Lunch menu... pick a combo:"
+
+ local i=1
+ local choice
+ for choice in ${LUNCH_MENU_CHOICES[@]}
+ do
+ echo " $i. $choice"
+ i=$(($i+1))
+ done
+
+ echo
+}
+
+function lunch()
+{
+ local answer
+
+ if [ "$1" ] ; then
+ answer=$1
+ else
+ print_lunch_menu
+ echo -n "Which would you like? [generic-eng] "
+ read answer
+ fi
+
+ local selection=
+
+ if [ -z "$answer" ]
+ then
+ selection=generic-eng
+ elif [ "$answer" = "simulator" ]
+ then
+ selection=simulator
+ elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
+ then
+ if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
+ then
+ selection=${LUNCH_MENU_CHOICES[$(($answer-$_arrayoffset))]}
+ fi
+ elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$")
+ then
+ selection=$answer
+ fi
+
+ if [ -z "$selection" ]
+ then
+ echo
+ echo "Invalid lunch combo: $answer"
+ return 1
+ fi
+
+ # special case the simulator
+ if [ "$selection" = "simulator" ]
+ then
+ export TARGET_PRODUCT=sim
+ export TARGET_BUILD_VARIANT=eng
+ export TARGET_SIMULATOR=true
+ export TARGET_BUILD_TYPE=debug
+ else
+ local product=$(echo -n $selection | sed -e "s/-.*$//")
+ check_product $product
+ if [ $? -ne 0 ]
+ then
+ echo
+ echo "** Don't have a product spec for: '$product'"
+ echo "** Do you have the right repo manifest?"
+ product=
+ fi
+
+ local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//")
+ check_variant $variant
+ if [ $? -ne 0 ]
+ then
+ echo
+ echo "** Invalid variant: '$variant'"
+ echo "** Must be one of ${VARIANT_CHOICES[@]}"
+ variant=
+ fi
+
+ if [ -z "$product" -o -z "$variant" ]
+ then
+ echo
+ return 1
+ fi
+
+ export TARGET_PRODUCT=$product
+ export TARGET_BUILD_VARIANT=$variant
+ export TARGET_SIMULATOR=false
+ export TARGET_BUILD_TYPE=release
+ fi # !simulator
+
+ echo
+
+ set_stuff_for_environment
+ printconfig
+}
+
+function gettop
+{
+ local TOPFILE=build/core/envsetup.mk
+ if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then
+ echo $TOP
+ else
+ if [ -f $TOPFILE ] ; then
+ echo $PWD
+ else
+ # 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
+ cd .. > /dev/null
+ T=$PWD
+ done
+ cd $HERE > /dev/null
+ if [ -f "$T/$TOPFILE" ]; then
+ echo $T
+ fi
+ fi
+ fi
+}
+
+function m()
+{
+ T=$(gettop)
+ if [ "$T" ]; then
+ make -C $T $@
+ else
+ echo "Couldn't locate the top of the tree. Try setting TOP."
+ fi
+}
+
+function findmakefile()
+{
+ 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
+ echo $T/Android.mk
+ cd $HERE > /dev/null
+ return
+ fi
+ cd .. > /dev/null
+ done
+ cd $HERE > /dev/null
+}
+
+function mm()
+{
+ # If we're sitting in the root of the build tree, just do a
+ # normal make.
+ if [ -f build/core/envsetup.mk -a -f Makefile ]; then
+ make $@
+ else
+ # Find the closest Android.mk file.
+ T=$(gettop)
+ local M=$(findmakefile)
+ if [ ! "$T" ]; then
+ echo "Couldn't locate the top of the tree. Try setting TOP."
+ elif [ ! "$M" ]; then
+ echo "Couldn't locate a makefile from the current directory."
+ else
+ ONE_SHOT_MAKEFILE=$M make -C $T files $@
+ fi
+ fi
+}
+
+function mmm()
+{
+ T=$(gettop)
+ if [ "$T" ]; then
+ local MAKEFILE=
+ local ARGS=
+ local DIR TO_CHOP
+ local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/')
+ local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/')
+ for DIR in $DIRS ; do
+ DIR=`echo $DIR | sed -e 's:/$::'`
+ if [ -f $DIR/Android.mk ]; then
+ TO_CHOP=`echo $T | wc -c | tr -d ' '`
+ TO_CHOP=`expr $TO_CHOP + 1`
+ MFILE=`echo $PWD | cut -c${TO_CHOP}-`
+ if [ "$MFILE" = "" ] ; then
+ MFILE=$DIR/Android.mk
+ else
+ MFILE=$MFILE/$DIR/Android.mk
+ fi
+ MAKEFILE="$MAKEFILE $MFILE"
+ else
+ if [ "$DIR" = snod ]; then
+ ARGS="$ARGS snod"
+ elif [ "$DIR" = showcommands ]; then
+ ARGS="$ARGS showcommands"
+ else
+ echo "No Android.mk in $DIR."
+ fi
+ fi
+ done
+ ONE_SHOT_MAKEFILE="$MAKEFILE" make -C $T $DASH_ARGS files $ARGS
+ else
+ echo "Couldn't locate the top of the tree. Try setting TOP."
+ fi
+}
+
+function croot()
+{
+ T=$(gettop)
+ if [ "$T" ]; then
+ cd $(gettop)
+ else
+ echo "Couldn't locate the top of the tree. Try setting TOP."
+ fi
+}
+
+function pid()
+{
+ local EXE="$1"
+ if [ "$EXE" ] ; then
+ local PID=`adb shell ps | fgrep $1 | sed -e 's/[^ ]* *\([0-9]*\).*/\1/'`
+ echo "$PID"
+ else
+ echo "usage: pid name"
+ fi
+}
+
+function gdbclient()
+{
+ local OUT_ROOT=$(get_abs_build_var PRODUCT_OUT)
+ local OUT_SYMBOLS=$(get_abs_build_var TARGET_OUT_UNSTRIPPED)
+ local OUT_SO_SYMBOLS=$(get_abs_build_var TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED)
+ local OUT_EXE_SYMBOLS=$(get_abs_build_var TARGET_OUT_EXECUTABLES_UNSTRIPPED)
+ local PREBUILTS=$(get_abs_build_var ANDROID_PREBUILTS)
+ if [ "$OUT_ROOT" -a "$PREBUILTS" ]; then
+ local EXE="$1"
+ if [ "$EXE" ] ; then
+ EXE=$1
+ else
+ EXE="app_process"
+ fi
+
+ local PORT="$2"
+ if [ "$PORT" ] ; then
+ PORT=$2
+ else
+ PORT=":5039"
+ fi
+
+ local PID
+ local PROG="$3"
+ if [ "$PROG" ] ; then
+ PID=`pid $3`
+ adb forward "tcp$PORT" "tcp$PORT"
+ adb shell gdbserver $PORT --attach $PID &
+ sleep 2
+ else
+ echo ""
+ echo "If you haven't done so already, do this first on the device:"
+ echo " gdbserver $PORT /system/bin/$EXE"
+ echo " or"
+ echo " gdbserver $PORT --attach $PID"
+ echo ""
+ fi
+
+ echo >|"$OUT_ROOT/gdbclient.cmds" "set solib-absolute-prefix $OUT_SYMBOLS"
+ echo >>"$OUT_ROOT/gdbclient.cmds" "set solib-search-path $OUT_SO_SYMBOLS"
+ echo >>"$OUT_ROOT/gdbclient.cmds" "target remote $PORT"
+ echo >>"$OUT_ROOT/gdbclient.cmds" ""
+
+ arm-eabi-gdb -x "$OUT_ROOT/gdbclient.cmds" "$OUT_EXE_SYMBOLS/$EXE"
+ else
+ echo "Unable to determine build system output dir."
+ fi
+
+}
+
+case `uname -s` in
+ Darwin)
+ function sgrep()
+ {
+ find -E . -type f -iregex '.*\.(c|h|cpp|S|java|xml)' -print0 | xargs -0 grep --color -n "$@"
+ }
+
+ ;;
+ *)
+ function sgrep()
+ {
+ find . -type f -iregex '.*\.\(c\|h\|cpp\|S\|java\|xml\)' -print0 | xargs -0 grep --color -n "$@"
+ }
+ ;;
+esac
+
+function jgrep()
+{
+ find . -type f -name "*\.java" -print0 | xargs -0 grep --color -n "$@"
+}
+
+function cgrep()
+{
+ find . -type f -name "*\.c*" -print0 | xargs -0 grep --color -n "$@"
+}
+
+function resgrep()
+{
+ for dir in `find . -name res -type d`; do find $dir -type f -name '*\.xml' -print0 | xargs -0 grep --color -n "$@"; done;
+}
+
+case `uname -s` in
+ Darwin)
+ function mgrep()
+ {
+ find -E . -type f -iregex '.*/(Makefile|Makefile\..*|.*\.make|.*\.mak|.*\.mk)' -print0 | xargs -0 grep --color -n "$@"
+ }
+
+ function treegrep()
+ {
+ find -E . -type f -iregex '.*\.(c|h|cpp|S|java|xml)' -print0 | xargs -0 grep --color -n -i "$@"
+ }
+
+ ;;
+ *)
+ function mgrep()
+ {
+ find . -regextype posix-egrep -iregex '(.*\/Makefile|.*\/Makefile\..*|.*\.make|.*\.mak|.*\.mk)' -type f -print0 | xargs -0 grep --color -n "$@"
+ }
+
+ function treegrep()
+ {
+ find . -regextype posix-egrep -iregex '.*\.(c|h|cpp|S|java|xml)' -type f -print0 | xargs -0 grep --color -n -i "$@"
+ }
+
+ ;;
+esac
+
+function getprebuilt
+{
+ get_abs_build_var ANDROID_PREBUILTS
+}
+
+function tracedmdump()
+{
+ T=$(gettop)
+ if [ ! "$T" ]; then
+ echo "Couldn't locate the top of the tree. Try setting TOP."
+ return
+ fi
+ local prebuiltdir=$(getprebuilt)
+ local KERNEL=$T/prebuilt/android-arm/vmlinux-qemu
+
+ local TRACE=$1
+ if [ ! "$TRACE" ] ; then
+ echo "usage: tracedmdump tracename"
+ return
+ fi
+
+ local BASETRACE=$(basename $TRACE)
+ if [ "$BASETRACE" = "$TRACE" ] ; then
+ TRACE=$ANDROID_PRODUCT_OUT/traces/$TRACE
+ fi
+
+ echo "post-processing traces..."
+ rm -f $TRACE/qtrace.dexlist
+ post_trace $TRACE
+ if [ $? -ne 0 ]; then
+ echo "***"
+ echo "*** Error: malformed trace. Did you remember to exit the emulator?"
+ echo "***"
+ return
+ fi
+ echo "generating dexlist output..."
+ /bin/ls $ANDROID_PRODUCT_OUT/system/framework/*.jar $ANDROID_PRODUCT_OUT/system/app/*.apk $ANDROID_PRODUCT_OUT/data/app/*.apk 2>/dev/null | xargs dexlist > $TRACE/qtrace.dexlist
+ echo "generating dmtrace data..."
+ q2dm -r $ANDROID_PRODUCT_OUT/symbols $TRACE $KERNEL $TRACE/dmtrace || return
+ echo "generating html file..."
+ dmtracedump -h $TRACE/dmtrace >| $TRACE/dmtrace.html || return
+ echo "done, see $TRACE/dmtrace.html for details"
+ echo "or run:"
+ echo " traceview $TRACE/dmtrace"
+}
+
+# communicate with a running device or emulator, set up necessary state,
+# and run the hat command.
+function runhat()
+{
+ # process standard adb options
+ local adbTarget=""
+ if [ $1 = "-d" -o $1 = "-e" ]; then
+ adbTarget=$1
+ shift 1
+ elif [ $1 = "-s" ]; then
+ adbTarget="$1 $2"
+ shift 2
+ fi
+ local adbOptions=${adbTarget}
+ echo adbOptions = ${adbOptions}
+
+ # runhat options
+ local targetPid=$1
+ local outputFile=$2
+
+ if [ "$targetPid" = "" ]; then
+ echo "Usage: runhat [ -d | -e | -s serial ] target-pid [output-file]"
+ return
+ fi
+
+ # confirm hat is available
+ if [ -z $(which hat) ]; then
+ echo "hat is not available in this configuration."
+ return
+ fi
+
+ adb ${adbOptions} shell >/dev/null mkdir /data/misc
+ adb ${adbOptions} shell chmod 777 /data/misc
+
+ # send a SIGUSR1 to cause the hprof dump
+ echo "Poking $targetPid and waiting for data..."
+ adb ${adbOptions} shell kill -10 $targetPid
+ echo "Press enter when logcat shows \"hprof: heap dump completed\""
+ echo -n "> "
+ read
+
+ local availFiles=( $(adb ${adbOptions} shell ls /data/misc | grep '^heap-dump' | sed -e 's/.*heap-dump-/heap-dump-/' | sort -r | tr '[:space:][:cntrl:]' ' ') )
+ local devFile=/data/misc/${availFiles[0]}
+ local localFile=/tmp/$$-hprof
+
+ echo "Retrieving file $devFile..."
+ adb ${adbOptions} pull $devFile $localFile
+
+ adb ${adbOptions} shell rm $devFile
+
+ echo "Running hat on $localFile"
+ echo "View the output by pointing your browser at http://localhost:7000/"
+ echo ""
+ hat $localFile
+}
+
+function getbugreports()
+{
+ local reports=(`adb shell ls /sdcard/bugreports | tr -d '\r'`)
+
+ if [ ! "$reports" ]; then
+ echo "Could not locate any bugreports."
+ return
+ fi
+
+ local report
+ for report in ${reports[@]}
+ do
+ echo "/sdcard/bugreports/${report}"
+ adb pull /sdcard/bugreports/${report} ${report}
+ gunzip ${report}
+ done
+}
+
+function startviewserver()
+{
+ local port=4939
+ if [ $# -gt 0 ]; then
+ port=$1
+ fi
+ adb shell service call window 1 i32 $port
+}
+
+function stopviewserver()
+{
+ adb shell service call window 2
+}
+
+function isviewserverstarted()
+{
+ adb shell service call window 3
+}
+
+function smoketest()
+{
+ if [ ! "$ANDROID_PRODUCT_OUT" ]; then
+ echo "Couldn't locate output files. Try running 'lunch' first." >&2
+ return
+ fi
+ T=$(gettop)
+ if [ ! "$T" ]; then
+ echo "Couldn't locate the top of the tree. Try setting TOP." >&2
+ return
+ fi
+
+ (cd "$T" && mmm tests/SmokeTest) &&
+ adb uninstall com.android.smoketest > /dev/null &&
+ adb uninstall com.android.smoketest.tests > /dev/null &&
+ adb install $ANDROID_PRODUCT_OUT/data/app/SmokeTestApp.apk &&
+ adb install $ANDROID_PRODUCT_OUT/data/app/SmokeTest.apk &&
+ adb shell am instrument -w com.android.smoketest.tests/android.test.InstrumentationTestRunner
+}
+
+# simple shortcut to the runtest command
+function runtest()
+{
+ T=$(gettop)
+ if [ ! "$T" ]; then
+ echo "Couldn't locate the top of the tree. Try setting TOP." >&2
+ return
+ fi
+ (cd "$T" && development/tools/runtest $@)
+}
+
+function godir () {
+ if [[ -z "$1" ]]; then
+ echo "Usage: godir <regex>"
+ return
+ fi
+ if [[ ! -f $T/filelist ]]; then
+ echo -n "Creating index..."
+ (cd $T; find . -wholename ./out -prune -o -type f > filelist)
+ echo " Done"
+ echo ""
+ fi
+ local lines
+ lines=($(grep "$1" $T/filelist | sed -e 's/\/[^/]*$//' | sort | uniq))
+ if [[ ${#lines[@]} = 0 ]]; then
+ echo "Not found"
+ return
+ fi
+ local pathname
+ local choice
+ if [[ ${#lines[@]} > 1 ]]; then
+ while [[ -z "$pathname" ]]; do
+ local index=1
+ local line
+ for line in ${lines[@]}; do
+ printf "%6s %s\n" "[$index]" $line
+ index=$(($index + 1))
+ done
+ echo
+ echo -n "Select one: "
+ unset choice
+ read choice
+ if [[ $choice -gt ${#lines[@]} || $choice -lt 1 ]]; then
+ echo "Invalid choice"
+ continue
+ fi
+ pathname=${lines[$(($choice-$_arrayoffset))]}
+ done
+ else
+ # even though zsh arrays are 1-based, $foo[0] is an alias for $foo[1]
+ pathname=${lines[0]}
+ fi
+ cd $T/$pathname
+}
+
+# determine whether arrays are zero-based (bash) or one-based (zsh)
+_xarray=(a b c)
+if [ -z "${_xarray[${#_xarray[@]}]}" ]
+then
+ _arrayoffset=1
+else
+ _arrayoffset=0
+fi
+unset _xarray
+
+# Execute the contents of any vendorsetup.sh files we can find.
+for f in `/bin/ls vendor/*/vendorsetup.sh 2> /dev/null`
+do
+ echo "including $f"
+ . $f
+done
+unset f
diff --git a/libs/host/Android.mk b/libs/host/Android.mk
new file mode 100644
index 0000000..81f2cc5
--- /dev/null
+++ b/libs/host/Android.mk
@@ -0,0 +1,26 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ CopyFile.c \
+ Directories.cpp \
+ pseudolocalize.cpp
+
+ifeq ($(HOST_OS),cygwin)
+LOCAL_CFLAGS += -DWIN32_EXE
+endif
+ifeq ($(HOST_OS),darwin)
+LOCAL_CFLAGS += -DMACOSX_RSRC
+endif
+ifeq ($(HOST_OS),linux)
+endif
+
+LOCAL_MODULE:= libhost
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+
+# acp uses libhost, so we can't use
+# acp to install libhost.
+LOCAL_ACP_UNAVAILABLE:= true
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
diff --git a/libs/host/CopyFile.c b/libs/host/CopyFile.c
new file mode 100644
index 0000000..a822b41
--- /dev/null
+++ b/libs/host/CopyFile.c
@@ -0,0 +1,626 @@
+/*
+ * Copyright 2005 The Android Open Source Project
+ *
+ * Android "cp" replacement.
+ *
+ * The GNU/Linux "cp" uses O_LARGEFILE in its open() calls, utimes() instead
+ * of utime(), and getxattr()/setxattr() instead of chmod(). These are
+ * probably "better", but are non-portable, and not necessary for our
+ * purposes.
+ */
+#include <host/CopyFile.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <getopt.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <utime.h>
+#include <limits.h>
+#include <errno.h>
+#include <assert.h>
+
+#ifdef HAVE_MS_C_RUNTIME
+# define mkdir(path,mode) _mkdir(path)
+#endif
+
+#ifndef HAVE_SYMLINKS
+# define lstat stat
+# ifndef EACCESS /* seems to be missing from the Mingw headers */
+# define EACCESS 13
+# endif
+#endif
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+/*#define DEBUG_MSGS*/
+#ifdef DEBUG_MSGS
+# define DBUG(x) printf x
+#else
+# define DBUG(x) ((void)0)
+#endif
+
+#define FSSEP '/' /* filename separator char */
+
+static int copyFileRecursive(const char* src, const char* dst, bool isCmdLine, unsigned int options);
+
+/*
+ * Returns true if the source file is newer than the destination file.
+ *
+ * The check is based on the modification date, whole seconds only. This
+ * also returns true if the file sizes don't match.
+ */
+static bool isSourceNewer(const struct stat* pSrcStat, const struct stat* pDstStat)
+{
+ return (pSrcStat->st_mtime > pDstStat->st_mtime) ||
+ (pSrcStat->st_size != pDstStat->st_size);
+}
+
+/*
+ * Returns true if the source and destination files are actually the
+ * same thing. We detect this by checking the inode numbers, which seems
+ * to work on Cygwin.
+ */
+static bool isSameFile(const struct stat* pSrcStat, const struct stat* pDstStat)
+{
+#ifndef HAVE_VALID_STAT_ST_INO
+ /* with MSVCRT.DLL, stat always sets st_ino to 0, and there is no simple way to */
+ /* get the equivalent information with Win32 (Cygwin does some weird stuff in */
+ /* its winsup/cygwin/fhandler_disk_file.cc to emulate this, too complex for us) */
+ return 0;
+#else
+ return (pSrcStat->st_ino == pDstStat->st_ino);
+#endif
+}
+
+static void printCopyMsg(const char* src, const char* dst, unsigned int options)
+{
+ if ((options & COPY_VERBOSE_MASK) > 0)
+ printf(" '%s' --> '%s'\n", src, dst);
+}
+
+static void printNotNewerMsg(const char* src, const char* dst, unsigned int options)
+{
+ if ((options & COPY_VERBOSE_MASK) > 1)
+ printf(" '%s' is up-to-date\n", dst);
+}
+
+/*
+ * Copy the contents of one file to another.
+ *
+ * The files are assumed to be seeked to the start.
+ */
+static int copyFileContents(const char* dst, int dstFd, const char* src, int srcFd)
+{
+ unsigned char buf[8192];
+ ssize_t readCount, writeCount;
+
+ /*
+ * Read a chunk, write it, and repeat.
+ */
+ while (1) {
+ readCount = read(srcFd, buf, sizeof(buf));
+ if (readCount < 0) {
+ fprintf(stderr,
+ "acp: failed reading '%s': %s\n", src, strerror(errno));
+ return -1;
+ }
+
+ if (readCount > 0) {
+ writeCount = write(dstFd, buf, readCount);
+ if (writeCount < 0) {
+ fprintf(stderr,
+ "acp: failed writing '%s': %s\n", dst, strerror(errno));
+ return -1;
+ }
+ if (writeCount != readCount) {
+ fprintf(stderr, "acp: partial write to '%s' (%d of %d)\n",
+ dst, writeCount, readCount);
+ return -1;
+ }
+ }
+
+ if (readCount < (ssize_t) sizeof(buf))
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * Set the permissions, owner, and timestamps on the destination file
+ * equal to those of the source file.
+ *
+ * Failures here are "soft"; they don't produce warning messages and don't
+ * cause the cp command to report a failure.
+ */
+static int setPermissions(const char* dst, const struct stat* pSrcStat, unsigned int options)
+{
+ struct utimbuf ut;
+
+ if (options & COPY_TIMESTAMPS) {
+ /*
+ * Start with timestamps. The access and mod dates are not affected
+ * by the next operations.
+ */
+ ut.actime = pSrcStat->st_atime;
+ ut.modtime = pSrcStat->st_mtime;
+ if (utime(dst, &ut) != 0) {
+ DBUG(("--- unable to set timestamps on '%s': %s\n",
+ dst, strerror(errno)));
+ }
+ }
+
+ if (options & COPY_PERMISSIONS) {
+ /*
+ * Set the permissions.
+ */
+ if (chmod(dst, pSrcStat->st_mode & ~(S_IFMT)) != 0) {
+ DBUG(("--- unable to set perms on '%s' to 0%o: %s\n",
+ dst, pSrcStat->st_mode & ~(S_IFMT), strerror(errno)));
+ }
+#ifndef HAVE_MS_C_RUNTIME
+ /*
+ * Set the owner.
+ */
+ if (chown(dst, pSrcStat->st_uid, pSrcStat->st_gid) != 0) {
+ DBUG(("--- unable to set owner of '%s' to %d/%d: %s\n",
+ dst, pSrcStat->st_uid, pSrcStat->st_gid, strerror(errno)));
+ }
+#endif
+ }
+
+ return 0;
+}
+
+/*
+ * Copy a regular file. If the destination file exists and is not a
+ * regular file, we fail. However, we use stat() rather than lstat(),
+ * because it's okay to write through a symlink (the noDereference stuff
+ * only applies to the source file).
+ *
+ * If the file doesn't exist, create it. If it does exist, truncate it.
+ */
+static int copyRegular(const char* src, const char* dst, const struct stat* pSrcStat, unsigned int options)
+{
+ struct stat dstStat;
+ int srcFd, dstFd, statResult, copyResult;
+
+ DBUG(("--- copying regular '%s' to '%s'\n", src, dst));
+
+ statResult = stat(dst, &dstStat);
+ if (statResult == 0 && !S_ISREG(dstStat.st_mode)) {
+ fprintf(stderr,
+ "acp: destination '%s' exists and is not regular file\n",
+ dst);
+ return -1;
+ } else if (statResult != 0 && errno != ENOENT) {
+ fprintf(stderr, "acp: unable to stat destination '%s'\n", dst);
+ return -1;
+ }
+
+ if (statResult == 0) {
+ if (isSameFile(pSrcStat, &dstStat)) {
+ fprintf(stderr, "acp: '%s' and '%s' are the same file\n",
+ src, dst);
+ return -1;
+ }
+ if (options & COPY_UPDATE_ONLY) {
+ if (!isSourceNewer(pSrcStat, &dstStat)) {
+ DBUG(("--- source is not newer: '%s'\n", src));
+ printNotNewerMsg(src, dst, options);
+ return 0;
+ }
+ }
+ }
+
+ /* open src */
+ srcFd = open(src, O_RDONLY | O_BINARY, 0);
+ if (srcFd < 0) {
+ fprintf(stderr, "acp: unable to open '%s': %s\n", src, strerror(errno));
+ return -1;
+ }
+
+ /* open dest with O_CREAT | O_TRUNC */
+ DBUG(("--- opening '%s'\n", dst));
+ dstFd = open(dst, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0644);
+
+ if (dstFd < 0) {
+ if (errno == ENOENT) {
+ /* this happens if the target directory doesn't exist */
+ fprintf(stderr,
+ "acp: cannot create '%s': %s\n", dst, strerror(errno));
+ (void) close(srcFd);
+ return -1;
+ }
+
+ /* if "force" is set, try removing the destination file and retry */
+ if (options & COPY_FORCE) {
+ if (unlink(dst) != 0) {
+#ifdef HAVE_MS_C_RUNTIME
+ /* MSVCRT.DLL unlink will fail with EACCESS if the file is set read-only */
+ /* so try to change its mode, and unlink again */
+ if (errno == EACCESS) {
+ if (chmod(dst, S_IWRITE|S_IREAD) == 0 && unlink(dst) == 0)
+ goto Open_File;
+ }
+#endif
+ fprintf(stderr, "acp: unable to remove '%s': %s\n",
+ dst, strerror(errno));
+ (void) close(srcFd);
+ return -1;
+ }
+#ifdef HAVE_MS_C_RUNTIME
+ Open_File:
+#endif
+ dstFd = open(dst, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0644);
+ }
+ }
+ if (dstFd < 0) {
+ fprintf(stderr, "acp: unable to open '%s': %s\n",
+ dst, strerror(errno));
+ (void) close(srcFd);
+ return -1;
+ }
+
+ copyResult = copyFileContents(dst, dstFd, src, srcFd);
+
+ (void) close(srcFd);
+ (void) close(dstFd);
+ if (copyResult != 0)
+ return -1;
+
+#ifdef MACOSX_RSRC
+ {
+ char* srcRsrcName = NULL;
+ char* dstRsrcName = NULL;
+ struct stat rsrcStat;
+
+ srcRsrcName = malloc(strlen(src) + 5 + 1);
+ strcpy(srcRsrcName, src);
+ strcat(srcRsrcName, "/rsrc");
+
+ dstRsrcName = malloc(strlen(dst) + 5 + 1);
+ strcpy(dstRsrcName, dst);
+ strcat(dstRsrcName, "/rsrc");
+
+ if (stat(srcRsrcName, &rsrcStat) == 0 && rsrcStat.st_size > 0) {
+ DBUG(("--- RSRC: %s --> %s\n", srcRsrcName, dstRsrcName));
+
+ srcFd = open(srcRsrcName, O_RDONLY);
+ dstFd = open(dstRsrcName, O_TRUNC | O_WRONLY, 0);
+ copyResult = -1;
+ if (srcFd >= 0 && dstFd >= 0) {
+ copyResult = copyFileContents(dstRsrcName, dstFd,
+ srcRsrcName, srcFd);
+ (void) close(srcFd);
+ (void) close(dstFd);
+ }
+
+ if (copyResult != 0)
+ return -1;
+ }
+
+ free(srcRsrcName);
+ free(dstRsrcName);
+ }
+#endif
+
+ setPermissions(dst, pSrcStat, options);
+
+ printCopyMsg(src, dst, options);
+
+ return 0;
+}
+
+
+#ifdef HAVE_SYMLINKS
+/*
+ * Copy a symlink. This only happens if we're in "no derefence" mode,
+ * in which we copy the links rather than the files that are pointed at.
+ *
+ * We always discard the destination file. If it's a symlink already,
+ * we want to throw it out and replace it. If it's not a symlink, we
+ * need to trash it so we can create one.
+ */
+static int copySymlink(const char* src, const char* dst, const struct stat* pSrcStat, unsigned int options)
+{
+ struct stat dstStat;
+ char linkBuf[PATH_MAX+1];
+ int statResult, nameLen;
+
+ assert(options & COPY_NO_DEREFERENCE);
+ DBUG(("--- copying symlink '%s' to '%s'\n", src, dst));
+
+ /* NOTE: we use lstat() here */
+ statResult = lstat(dst, &dstStat);
+ if (statResult == 0 && !S_ISREG(dstStat.st_mode)
+ && !S_ISLNK(dstStat.st_mode)
+ )
+ {
+ fprintf(stderr,
+ "acp: destination '%s' exists and is not regular or symlink\n",
+ dst);
+ return -1;
+ }
+
+ if (statResult == 0) {
+ if (isSameFile(pSrcStat, &dstStat)) {
+ fprintf(stderr, "acp: '%s' and '%s' are the same file\n",
+ src, dst);
+ return -1;
+ }
+ if (options & COPY_UPDATE_ONLY) {
+ if (!isSourceNewer(pSrcStat, &dstStat)) {
+ DBUG(("--- source is not newer: '%s'\n", src));
+ printNotNewerMsg(src, dst, options);
+ return 0;
+ }
+ }
+ }
+
+ /* extract the symlink contents */
+ nameLen = readlink(src, linkBuf, sizeof(linkBuf)-1);
+ if (nameLen <= 0) {
+ fprintf(stderr, "acp: unable to read symlink '%s': %s\n",
+ src, strerror(errno));
+ return -1;
+ }
+ linkBuf[nameLen] = '\0';
+ DBUG(("--- creating symlink file '%s' (--> %s)\n", dst, linkBuf));
+
+ if (statResult == 0) {
+ DBUG(("--- removing '%s'\n", dst));
+ if (unlink(dst) != 0) {
+ fprintf(stderr, "acp: unable to remove '%s': %s\n",
+ dst, strerror(errno));
+ return -1;
+ }
+ }
+
+ if (symlink(linkBuf, dst) != 0) {
+ fprintf(stderr, "acp: unable to create symlink '%s' [%s]: %s\n",
+ dst, linkBuf, strerror(errno));
+ return -1;
+ }
+
+ /*
+ * There's no way to set the file date or access permissions, but
+ * it is possible to set the owner.
+ */
+ if (options & COPY_PERMISSIONS) {
+ if (lchown(dst, pSrcStat->st_uid, pSrcStat->st_gid) != 0)
+ DBUG(("--- lchown failed: %s\n", strerror(errno)));
+ }
+
+ printCopyMsg(src, dst, options);
+
+ return 0;
+}
+#endif /* HAVE_SYMLINKS */
+
+/*
+ * Copy the contents of one directory to another. Both "src" and "dst"
+ * must be directories. We will create "dst" if it does not exist.
+ */
+int copyDirectory(const char* src, const char* dst, const struct stat* pSrcStat, unsigned int options)
+{
+ int retVal = 0;
+ struct stat dstStat;
+ DIR* dir;
+ int cc, statResult;
+
+ DBUG(("--- copy dir '%s' to '%s'\n", src, dst));
+
+ statResult = stat(dst, &dstStat);
+ if (statResult == 0 && !S_ISDIR(dstStat.st_mode)) {
+ fprintf(stderr,
+ "acp: destination '%s' exists and is not a directory\n", dst);
+ return -1;
+ } else if (statResult != 0 && errno != ENOENT) {
+ fprintf(stderr, "acp: unable to stat destination '%s'\n", dst);
+ return -1;
+ }
+
+ if (statResult == 0) {
+ if (isSameFile(pSrcStat, &dstStat)) {
+ fprintf(stderr,
+ "acp: cannot copy directory into itself ('%s' and '%s')\n",
+ src, dst);
+ return -1;
+ }
+ } else {
+ DBUG(("--- creating dir '%s'\n", dst));
+ cc = mkdir(dst, 0755);
+ if (cc != 0) {
+ fprintf(stderr, "acp: unable to create directory '%s': %s\n",
+ dst, strerror(errno));
+ return -1;
+ }
+
+ /* only print on mkdir */
+ printCopyMsg(src, dst, options);
+ }
+
+ /*
+ * Open the directory, and plow through its contents.
+ */
+ dir = opendir(src);
+ if (dir == NULL) {
+ fprintf(stderr, "acp: unable to open directory '%s': %s\n",
+ src, strerror(errno));
+ return -1;
+ }
+
+ while (1) {
+ struct dirent* ent;
+ char* srcFile;
+ char* dstFile;
+ int srcLen, dstLen, nameLen;
+
+ ent = readdir(dir);
+ if (ent == NULL)
+ break;
+
+ if (strcmp(ent->d_name, ".") == 0 ||
+ strcmp(ent->d_name, "..") == 0)
+ {
+ continue;
+ }
+
+ nameLen = strlen(ent->d_name);
+ srcLen = strlen(src);
+ dstLen = strlen(dst);
+
+ srcFile = malloc(srcLen +1 + nameLen +1);
+ memcpy(srcFile, src, srcLen);
+ srcFile[srcLen] = FSSEP;
+ memcpy(srcFile + srcLen+1, ent->d_name, nameLen +1);
+
+ dstFile = malloc(dstLen +1 + nameLen +1);
+ memcpy(dstFile, dst, dstLen);
+ dstFile[dstLen] = FSSEP;
+ memcpy(dstFile + dstLen+1, ent->d_name, nameLen +1);
+
+ if (copyFileRecursive(srcFile, dstFile, false, options) != 0)
+ retVal = -1; /* note failure and keep going */
+
+ free(srcFile);
+ free(dstFile);
+ }
+ closedir(dir);
+
+ setPermissions(dst, pSrcStat, options);
+
+ return retVal;
+}
+
+/*
+ * Do the actual copy. This is called recursively from copyDirectory().
+ *
+ * "dst" should only be a directory if "src" is also a directory.
+ *
+ * Returns 0 on success.
+ */
+static int copyFileRecursive(const char* src, const char* dst, bool isCmdLine, unsigned int options)
+{
+ char* srcExe = NULL;
+ char* dstExe = NULL;
+ char* dstDir = NULL;
+ struct stat srcStat;
+ int retVal = 0;
+ int statResult, statErrno;
+
+ /*
+ * Stat the source file. If it doesn't exist, fail.
+ */
+ if (options & COPY_NO_DEREFERENCE)
+ statResult = lstat(src, &srcStat);
+ else
+ statResult = stat(src, &srcStat);
+ statErrno = errno; /* preserve across .exe attempt */
+
+#ifdef WIN32_EXE
+ /*
+ * Here's the interesting part. Under Cygwin, if you have a file
+ * called "foo.exe", stat("foo", ...) will succeed, but open("foo", ...)
+ * will fail. We need to figure out what its name is supposed to be
+ * so we can create the correct destination file.
+ *
+ * If we don't have the "-e" flag set, we want "acp foo bar" to fail,
+ * not automatically find "foo.exe". That way, if we really were
+ * trying to copy "foo", it doesn't grab something we don't want.
+ */
+ if (isCmdLine && statResult == 0) {
+ int tmpFd;
+ tmpFd = open(src, O_RDONLY | O_BINARY, 0);
+ if (tmpFd < 0) {
+ statResult = -1;
+ statErrno = ENOENT;
+ } else {
+ (void) close(tmpFd);
+ }
+ }
+
+ /*
+ * If we didn't find the file, try it again with ".exe".
+ */
+ if (isCmdLine && statResult < 0 && statErrno == ENOENT && (options & COPY_TRY_EXE)) {
+ srcExe = malloc(strlen(src) + 4 +1);
+ strcpy(srcExe, src);
+ strcat(srcExe, ".exe");
+
+ if (options & COPY_NO_DEREFERENCE)
+ statResult = lstat(srcExe, &srcStat);
+ else
+ statResult = stat(srcExe, &srcStat);
+
+ if (statResult == 0 && !S_ISREG(srcStat.st_mode))
+ statResult = -1; /* fail, use original statErrno below */
+
+ if (statResult == 0) {
+ /* found a .exe, copy that instead */
+ dstExe = malloc(strlen(dst) + 4 +1);
+ strcpy(dstExe, dst);
+ strcat(dstExe, ".exe");
+
+ src = srcExe;
+ dst = dstExe;
+ } else {
+ DBUG(("--- couldn't find '%s' either\n", srcExe));
+ }
+ }
+#endif
+ if (statResult < 0) {
+ if (statErrno == ENOENT)
+ fprintf(stderr, "acp: file '%s' does not exist\n", src);
+ else
+ fprintf(stderr, "acp: unable to stat '%s': %s\n",
+ src, strerror(statErrno));
+ retVal = -1;
+ goto bail;
+ }
+
+ /*
+ * If "src" is a directory, ignore it if "recursive" isn't set.
+ *
+ * We want to create "dst" as a directory (or verify that it already
+ * exists as a directory), and then copy its contents.
+ */
+ if (S_ISDIR(srcStat.st_mode)) {
+ if (!(options & COPY_RECURSIVE)) {
+ fprintf(stderr, "acp: omitting directory '%s'\n", src);
+ } else {
+ retVal = copyDirectory(src, dst, &srcStat, options);
+ }
+#ifdef HAVE_SYMLINKS
+ } else if (S_ISLNK(srcStat.st_mode)) {
+ retVal = copySymlink(src, dst, &srcStat, options);
+#endif
+ } else if (S_ISREG(srcStat.st_mode)) {
+ retVal = copyRegular(src, dst, &srcStat, options);
+ } else {
+ fprintf(stderr, "acp: skipping unusual file '%s' (mode=0%o)\n",
+ src, srcStat.st_mode);
+ retVal = -1;
+ }
+
+bail:
+ free(srcExe);
+ free(dstExe);
+ free(dstDir);
+ return retVal;
+}
+
+int copyFile(const char* src, const char* dst, unsigned int options)
+{
+ return copyFileRecursive(src, dst, true, options);
+}
+
+
diff --git a/libs/host/Directories.cpp b/libs/host/Directories.cpp
new file mode 100644
index 0000000..a34f5b7
--- /dev/null
+++ b/libs/host/Directories.cpp
@@ -0,0 +1,42 @@
+#include <host/Directories.h>
+#include <utils/String8.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_MS_C_RUNTIME
+#include <direct.h>
+#endif
+
+using namespace android;
+using namespace std;
+
+string
+parent_dir(const string& path)
+{
+ return string(String8(path.c_str()).getPathDir().string());
+}
+
+int
+mkdirs(const char* last)
+{
+ String8 dest;
+ const char* s = last-1;
+ int err;
+ do {
+ s++;
+ if (s > last && (*s == '.' || *s == 0)) {
+ String8 part(last, s-last);
+ dest.appendPath(part);
+#ifdef HAVE_MS_C_RUNTIME
+ err = _mkdir(dest.string());
+#else
+ err = mkdir(dest.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
+#endif
+ if (err != 0) {
+ return err;
+ }
+ last = s+1;
+ }
+ } while (*s);
+ return 0;
+}
diff --git a/libs/host/include/host/CopyFile.h b/libs/host/include/host/CopyFile.h
new file mode 100644
index 0000000..e65712b
--- /dev/null
+++ b/libs/host/include/host/CopyFile.h
@@ -0,0 +1,30 @@
+#ifndef _HOST_COPYFILE_H
+#define _HOST_COPYFILE_H
+
+#include <stdbool.h>
+#include <sys/stat.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+// command line options
+enum {
+ COPY_NO_DEREFERENCE = 0x00010000, // copy symlink link instead of target
+ COPY_TRY_EXE = 0x00020000, // on Win32, try adding '.exe' to filename
+ COPY_FORCE = 0x00040000, // override access permissions
+ COPY_PERMISSIONS = 0x00080000, // preserve mode, ownership, timestamps
+ COPY_TIMESTAMPS = 0x00100000, // preserve mode, ownership, timestamps
+ COPY_RECURSIVE = 0x00200000, // copy directories
+ COPY_UPDATE_ONLY = 0x00400000, // only copy if source file is newer
+ COPY_VERBOSE_MASK = 0x000000ff // talk lots
+};
+
+int copyFile(const char* src, const char* dst, unsigned int options);
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+#endif // _HOST_COPYFILE_H
+
diff --git a/libs/host/include/host/Directories.h b/libs/host/include/host/Directories.h
new file mode 100644
index 0000000..fccce46
--- /dev/null
+++ b/libs/host/include/host/Directories.h
@@ -0,0 +1,10 @@
+#ifndef HOST_MKDIRS_H
+#define HOST_MKDIRS_H
+
+#include <string>
+
+std::string parent_dir(const std::string& path);
+
+extern "C" int mkdirs(const char* path);
+
+#endif // HOST_MKDIRS_H
diff --git a/libs/host/include/host/pseudolocalize.h b/libs/host/include/host/pseudolocalize.h
new file mode 100644
index 0000000..94cb034
--- /dev/null
+++ b/libs/host/include/host/pseudolocalize.h
@@ -0,0 +1,9 @@
+#ifndef HOST_PSEUDOLOCALIZE_H
+#define HOST_PSEUDOLOCALIZE_H
+
+#include <string>
+
+std::string pseudolocalize_string(const std::string& source);
+
+#endif // HOST_PSEUDOLOCALIZE_H
+
diff --git a/libs/host/list.java b/libs/host/list.java
new file mode 100644
index 0000000..30546e3
--- /dev/null
+++ b/libs/host/list.java
@@ -0,0 +1,35 @@
+import java.io.*;
+
+public class list {
+ private static char nibble(int c) {
+ return (char)(c < 10 ? ('0' + c) : ('a' + (c-10)));
+ }
+ public static void main(String[] argv)
+ {
+ ByteArrayOutputStream stream = new ByteArrayOutputStream(100);
+ OutputStreamWriter writer = null;
+ try {
+ writer = new OutputStreamWriter(stream, "utf-8");
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace(System.err);
+ }
+
+ int n = Integer.parseInt(argv[1], 16);
+ try {
+ writer.write(n);
+ writer.close();
+ } catch (IOException e) {
+ e.printStackTrace(System.err);
+ }
+
+ byte[] array = stream.toByteArray();
+
+ System.out.print(" case '" + argv[0] + "': return \"");
+ for (int i=0; i<array.length; i++) {
+ int b = array[i];
+ System.out.print("\\x" + nibble((b >> 4) & 0x0f) + nibble(b & 0xf));
+ }
+ System.out.println("\";");
+ }
+}
+
diff --git a/libs/host/pseudolocalize.cpp b/libs/host/pseudolocalize.cpp
new file mode 100644
index 0000000..a2b3c2f
--- /dev/null
+++ b/libs/host/pseudolocalize.cpp
@@ -0,0 +1,119 @@
+#include <host/pseudolocalize.h>
+
+using namespace std;
+
+static const char*
+pseudolocalize_char(char c)
+{
+ switch (c) {
+ case 'a': return "\xc4\x83";
+ case 'b': return "\xcf\x84";
+ case 'c': return "\xc4\x8b";
+ case 'd': return "\xc4\x8f";
+ case 'e': return "\xc4\x99";
+ case 'f': return "\xc6\x92";
+ case 'g': return "\xc4\x9d";
+ case 'h': return "\xd1\x9b";
+ case 'i': return "\xcf\x8a";
+ case 'j': return "\xc4\xb5";
+ case 'k': return "\xc4\xb8";
+ case 'l': return "\xc4\xba";
+ case 'm': return "\xe1\xb8\xbf";
+ case 'n': return "\xd0\xb8";
+ case 'o': return "\xcf\x8c";
+ case 'p': return "\xcf\x81";
+ case 'q': return "\x51";
+ case 'r': return "\xd2\x91";
+ case 's': return "\xc5\xa1";
+ case 't': return "\xd1\x82";
+ case 'u': return "\xce\xb0";
+ case 'v': return "\x56";
+ case 'w': return "\xe1\xba\x85";
+ case 'x': return "\xd1\x85";
+ case 'y': return "\xe1\xbb\xb3";
+ case 'z': return "\xc5\xba";
+ case 'A': return "\xc3\x85";
+ case 'B': return "\xce\xb2";
+ case 'C': return "\xc4\x88";
+ case 'D': return "\xc4\x90";
+ case 'E': return "\xd0\x84";
+ case 'F': return "\xce\x93";
+ case 'G': return "\xc4\x9e";
+ case 'H': return "\xc4\xa6";
+ case 'I': return "\xd0\x87";
+ case 'J': return "\xc4\xb5";
+ case 'K': return "\xc4\xb6";
+ case 'L': return "\xc5\x81";
+ case 'M': return "\xe1\xb8\xbe";
+ case 'N': return "\xc5\x83";
+ case 'O': return "\xce\x98";
+ case 'P': return "\xcf\x81";
+ case 'Q': return "\x71";
+ case 'R': return "\xd0\xaf";
+ case 'S': return "\xc8\x98";
+ case 'T': return "\xc5\xa6";
+ case 'U': return "\xc5\xa8";
+ case 'V': return "\xce\xbd";
+ case 'W': return "\xe1\xba\x84";
+ case 'X': return "\xc3\x97";
+ case 'Y': return "\xc2\xa5";
+ case 'Z': return "\xc5\xbd";
+ default: return NULL;
+ }
+}
+
+/**
+ * Converts characters so they look like they've been localized.
+ *
+ * Note: This leaves escape sequences untouched so they can later be
+ * processed by ResTable::collectString in the normal way.
+ */
+string
+pseudolocalize_string(const string& source)
+{
+ const char* s = source.c_str();
+ string result;
+ const size_t I = source.length();
+ for (size_t i=0; i<I; i++) {
+ char c = s[i];
+ if (c == '\\') {
+ if (i<I-1) {
+ result += '\\';
+ i++;
+ c = s[i];
+ switch (c) {
+ case 'u':
+ // this one takes up 5 chars
+ result += string(s+i, 5);
+ i += 4;
+ break;
+ case 't':
+ case 'n':
+ case '#':
+ case '@':
+ case '?':
+ case '"':
+ case '\'':
+ case '\\':
+ default:
+ result += c;
+ break;
+ }
+ } else {
+ result += c;
+ }
+ } else {
+ const char* p = pseudolocalize_char(c);
+ if (p != NULL) {
+ result += p;
+ } else {
+ result += c;
+ }
+ }
+ }
+
+ //printf("result=\'%s\'\n", result.c_str());
+ return result;
+}
+
+
diff --git a/target/board/Android.mk b/target/board/Android.mk
new file mode 100644
index 0000000..64e3a74
--- /dev/null
+++ b/target/board/Android.mk
@@ -0,0 +1,54 @@
+#
+# Set up product-global definitions and include product-specific rules.
+#
+
+ifneq ($(strip $(TARGET_NO_BOOTLOADER)),true)
+ INSTALLED_BOOTLOADER_MODULE := $(PRODUCT_OUT)/bootloader
+ ifeq ($(strip $(TARGET_BOOTLOADER_IS_2ND)),true)
+ INSTALLED_2NDBOOTLOADER_TARGET := $(PRODUCT_OUT)/2ndbootloader
+ else
+ INSTALLED_2NDBOOTLOADER_TARGET :=
+ endif
+else
+ INSTALLED_BOOTLOADER_MODULE :=
+ INSTALLED_2NDBOOTLOADER_TARGET :=
+endif # TARGET_NO_BOOTLOADER
+
+ifneq ($(strip $(TARGET_NO_KERNEL)),true)
+ INSTALLED_KERNEL_TARGET := $(PRODUCT_OUT)/kernel
+else
+ INSTALLED_KERNEL_TARGET :=
+endif
+
+ifneq ($(strip $(TARGET_NO_RADIOIMAGE)),true)
+ INSTALLED_RADIOIMAGE_TARGET := $(PRODUCT_OUT)/radio.img
+else
+ INSTALLED_RADIOIMAGE_TARGET :=
+endif
+
+ifeq (,$(wildcard $(TARGET_DEVICE_DIR)/AndroidBoard.mk))
+ ifeq (,$(wildcard $(TARGET_DEVICE_DIR)/Android.mk))
+ $(error Missing "$(TARGET_DEVICE_DIR)/AndroidBoard.mk")
+ else
+ # TODO: Remove this check after people have had a chance to switch,
+ # after April 2009.
+ $(error Please rename "$(TARGET_DEVICE_DIR)/Android.mk" to "$(TARGET_DEVICE_DIR)/AndroidBoard.mk")
+ endif
+endif
+include $(TARGET_DEVICE_DIR)/AndroidBoard.mk
+
+# Generate a file that contains various information about the
+# device we're building for. This file is typically packaged up
+# with everything else.
+#
+# If the file "board-info.txt" appears in $(TARGET_DEVICE_DIR),
+# it will be appended to the output file.
+#
+INSTALLED_ANDROID_INFO_TXT_TARGET := $(PRODUCT_OUT)/android-info.txt
+board_info_txt := $(wildcard $(TARGET_DEVICE_DIR)/board-info.txt)
+$(INSTALLED_ANDROID_INFO_TXT_TARGET): $(board_info_txt)
+ $(call pretty,"Generated: ($@)")
+ $(hide) echo "board=$(TARGET_BOOTLOADER_BOARD_NAME)" > $@
+ifdef board_info_txt
+ $(hide) cat $< >> $@
+endif
diff --git a/target/board/emulator/AndroidBoard.mk b/target/board/emulator/AndroidBoard.mk
new file mode 100644
index 0000000..09badee
--- /dev/null
+++ b/target/board/emulator/AndroidBoard.mk
@@ -0,0 +1,10 @@
+LOCAL_PATH := $(call my-dir)
+
+file := $(TARGET_OUT_KEYLAYOUT)/tuttle2.kl
+ALL_PREBUILT += $(file)
+$(file) : $(LOCAL_PATH)/tuttle2.kl | $(ACP)
+ $(transform-prebuilt-to-target)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := tuttle2.kcm
+include $(BUILD_KEY_CHAR_MAP)
diff --git a/target/board/emulator/BoardConfig.mk b/target/board/emulator/BoardConfig.mk
new file mode 100644
index 0000000..784118a
--- /dev/null
+++ b/target/board/emulator/BoardConfig.mk
@@ -0,0 +1,9 @@
+# config.mk
+#
+# Product-specific compile-time definitions.
+#
+
+# The generic product target doesn't have any hardware-specific pieces.
+TARGET_NO_BOOTLOADER := true
+TARGET_NO_KERNEL := true
+HAVE_HTC_AUDIO_DRIVER := true
diff --git a/target/board/emulator/README.txt b/target/board/emulator/README.txt
new file mode 100644
index 0000000..6a1ec89
--- /dev/null
+++ b/target/board/emulator/README.txt
@@ -0,0 +1,10 @@
+The "emulator" product defines an almost non-hardware-specific target
+without a kernel or bootloader, except that it defines the
+HAVE_HTC_AUDIO_DRIVER constant, since that is what the emulator
+emulates currently.
+
+It can be used to build the entire user-level system, and
+will work with the emulator.
+
+It is not a product "base class"; no other products inherit
+from it or use it in any way.
diff --git a/target/board/emulator/tuttle2.kcm b/target/board/emulator/tuttle2.kcm
new file mode 100644
index 0000000..0a2dd8c
--- /dev/null
+++ b/target/board/emulator/tuttle2.kcm
@@ -0,0 +1,66 @@
+[type=QWERTY]
+
+# keycode display number base caps fn caps_fn
+
+A 'A' '%' 'a' 'A' '%' 0x00
+B 'B' '=' 'b' 'B' '=' 0x00
+C 'C' '8' 'c' 'C' '8' 0x00E7
+D 'D' '5' 'd' 'D' '5' 0x00
+E 'E' '2' 'e' 'E' '2' 0x0301
+F 'F' '6' 'f' 'F' '6' 0x00A5
+G 'G' '-' 'g' 'G' '-' '_'
+H 'H' '[' 'h' 'H' '[' '{'
+I 'I' '$' 'i' 'I' '$' 0x0302
+J 'J' ']' 'j' 'J' ']' '}'
+K 'K' '"' 'k' 'K' '"' '~'
+L 'L' ''' 'l' 'L' ''' '`'
+M 'M' '>' 'm' 'M' '>' 0x00
+N 'N' '<' 'n' 'N' '<' 0x0303
+O 'O' '(' 'o' 'O' '(' 0x00
+P 'P' ')' 'p' 'P' ')' 0x00
+Q 'Q' '*' 'q' 'Q' '*' 0x0300
+R 'R' '3' 'r' 'R' '3' 0x20AC
+S 'S' '4' 's' 'S' '4' 0x00DF
+T 'T' '+' 't' 'T' '+' 0x00A3
+U 'U' '&' 'u' 'U' '&' 0x0308
+V 'V' '9' 'v' 'V' '9' '^'
+W 'W' '1' 'w' 'W' '1' 0x00
+X 'X' '7' 'x' 'X' '7' 0xEF00
+Y 'Y' '!' 'y' 'Y' '!' 0x00A1
+Z 'Z' '#' 'z' 'Z' '#' 0x00
+
+COMMA ',' ',' ',' ';' ';' '|'
+PERIOD '.' '.' '.' ':' ':' 0x2026
+AT '@' '0' '@' '0' '0' 0x2022
+SLASH '/' '/' '/' '?' '?' '\'
+
+SPACE 0x20 0x20 0x20 0x20 0xEF01 0xEF01
+ENTER 0xa 0xa 0xa 0xa 0xa 0xa
+
+# on pc keyboards
+TAB 0x9 0x9 0x9 0x9 0x9 0x9
+0 '0' '0' '0' ')' ')' ')'
+1 '1' '1' '1' '!' '!' '!'
+2 '2' '2' '2' '@' '@' '@'
+3 '3' '3' '3' '#' '#' '#'
+4 '4' '4' '4' '$' '$' '$'
+5 '5' '5' '5' '%' '%' '%'
+6 '6' '6' '6' '^' '^' '^'
+7 '7' '7' '7' '&' '&' '&'
+8 '8' '8' '8' '*' '*' '*'
+9 '9' '9' '9' '(' '(' '('
+
+GRAVE '`' '`' '`' '~' '`' '~'
+MINUS '-' '-' '-' '_' '-' '_'
+EQUALS '=' '=' '=' '+' '=' '+'
+LEFT_BRACKET '[' '[' '[' '{' '[' '{'
+RIGHT_BRACKET ']' ']' ']' '}' ']' '}'
+BACKSLASH '\' '\' '\' '|' '\' '|'
+SEMICOLON ';' ';' ';' ':' ';' ':'
+APOSTROPHE ''' ''' ''' '"' ''' '"'
+STAR '*' '*' '*' '*' '*' '*'
+POUND '#' '#' '#' '#' '#' '#'
+PLUS '+' '+' '+' '+' '+' '+'
+
+
+
diff --git a/target/board/emulator/tuttle2.kl b/target/board/emulator/tuttle2.kl
new file mode 100644
index 0000000..a48a5ab
--- /dev/null
+++ b/target/board/emulator/tuttle2.kl
@@ -0,0 +1,74 @@
+key 2 1
+key 3 2
+key 4 3
+key 5 4
+key 6 5
+key 7 6
+key 8 7
+key 9 8
+key 10 9
+key 11 0
+key 158 BACK WAKE_DROPPED
+key 230 SOFT_RIGHT WAKE
+key 60 SOFT_RIGHT WAKE
+key 107 ENDCALL WAKE_DROPPED
+key 62 ENDCALL WAKE_DROPPED
+key 229 MENU WAKE_DROPPED
+key 59 MENU WAKE_DROPPED
+key 228 POUND
+key 227 STAR
+key 231 CALL WAKE_DROPPED
+key 61 CALL WAKE_DROPPED
+key 232 DPAD_CENTER WAKE_DROPPED
+key 108 DPAD_DOWN WAKE_DROPPED
+key 103 DPAD_UP WAKE_DROPPED
+key 102 HOME WAKE
+key 105 DPAD_LEFT WAKE_DROPPED
+key 106 DPAD_RIGHT WAKE_DROPPED
+key 115 VOLUME_UP
+key 114 VOLUME_DOWN
+key 116 POWER WAKE
+key 212 SLASH
+
+key 16 Q
+key 17 W
+key 18 E
+key 19 R
+key 20 T
+key 21 Y
+key 22 U
+key 23 I
+key 24 O
+key 25 P
+
+key 30 A
+key 31 S
+key 32 D
+key 33 F
+key 34 G
+key 35 H
+key 36 J
+key 37 K
+key 38 L
+key 14 DEL
+
+key 44 Z
+key 45 X
+key 46 C
+key 47 V
+key 48 B
+key 49 N
+key 50 M
+key 51 COMMA
+key 52 PERIOD
+key 28 ENTER
+
+key 56 ALT_LEFT
+key 42 SHIFT_LEFT
+key 215 AT
+key 57 SPACE
+key 53 SLASH
+key 127 SYM
+key 100 ALT_RIGHT
+
+key 399 GRAVE
diff --git a/target/board/generic/AndroidBoard.mk b/target/board/generic/AndroidBoard.mk
new file mode 100644
index 0000000..09badee
--- /dev/null
+++ b/target/board/generic/AndroidBoard.mk
@@ -0,0 +1,10 @@
+LOCAL_PATH := $(call my-dir)
+
+file := $(TARGET_OUT_KEYLAYOUT)/tuttle2.kl
+ALL_PREBUILT += $(file)
+$(file) : $(LOCAL_PATH)/tuttle2.kl | $(ACP)
+ $(transform-prebuilt-to-target)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := tuttle2.kcm
+include $(BUILD_KEY_CHAR_MAP)
diff --git a/target/board/generic/BoardConfig.mk b/target/board/generic/BoardConfig.mk
new file mode 100644
index 0000000..a874742
--- /dev/null
+++ b/target/board/generic/BoardConfig.mk
@@ -0,0 +1,11 @@
+# config.mk
+#
+# Product-specific compile-time definitions.
+#
+
+# The generic product target doesn't have any hardware-specific pieces.
+TARGET_NO_BOOTLOADER := true
+TARGET_NO_KERNEL := true
+TARGET_NO_RADIOIMAGE := true
+HAVE_HTC_AUDIO_DRIVER := true
+BOARD_USES_GENERIC_AUDIO := true
diff --git a/target/board/generic/README.txt b/target/board/generic/README.txt
new file mode 100644
index 0000000..ddac68e
--- /dev/null
+++ b/target/board/generic/README.txt
@@ -0,0 +1,9 @@
+The "generic" product defines a non-hardware-specific target
+without a kernel or bootloader.
+
+It can be used to build the entire user-level system, and
+will work with the emulator, though sound will not work
+(see the "emulator" product for that).
+
+It is not a product "base class"; no other products inherit
+from it or use it in any way.
diff --git a/target/board/generic/system.prop b/target/board/generic/system.prop
new file mode 100644
index 0000000..f2424c9
--- /dev/null
+++ b/target/board/generic/system.prop
@@ -0,0 +1,6 @@
+#
+# system.prop for generic sdk
+#
+
+rild.libpath=/system/lib/libreference-ril.so
+rild.libargs=-d /dev/ttyS0
diff --git a/target/board/generic/tuttle2.kcm b/target/board/generic/tuttle2.kcm
new file mode 100644
index 0000000..0a2dd8c
--- /dev/null
+++ b/target/board/generic/tuttle2.kcm
@@ -0,0 +1,66 @@
+[type=QWERTY]
+
+# keycode display number base caps fn caps_fn
+
+A 'A' '%' 'a' 'A' '%' 0x00
+B 'B' '=' 'b' 'B' '=' 0x00
+C 'C' '8' 'c' 'C' '8' 0x00E7
+D 'D' '5' 'd' 'D' '5' 0x00
+E 'E' '2' 'e' 'E' '2' 0x0301
+F 'F' '6' 'f' 'F' '6' 0x00A5
+G 'G' '-' 'g' 'G' '-' '_'
+H 'H' '[' 'h' 'H' '[' '{'
+I 'I' '$' 'i' 'I' '$' 0x0302
+J 'J' ']' 'j' 'J' ']' '}'
+K 'K' '"' 'k' 'K' '"' '~'
+L 'L' ''' 'l' 'L' ''' '`'
+M 'M' '>' 'm' 'M' '>' 0x00
+N 'N' '<' 'n' 'N' '<' 0x0303
+O 'O' '(' 'o' 'O' '(' 0x00
+P 'P' ')' 'p' 'P' ')' 0x00
+Q 'Q' '*' 'q' 'Q' '*' 0x0300
+R 'R' '3' 'r' 'R' '3' 0x20AC
+S 'S' '4' 's' 'S' '4' 0x00DF
+T 'T' '+' 't' 'T' '+' 0x00A3
+U 'U' '&' 'u' 'U' '&' 0x0308
+V 'V' '9' 'v' 'V' '9' '^'
+W 'W' '1' 'w' 'W' '1' 0x00
+X 'X' '7' 'x' 'X' '7' 0xEF00
+Y 'Y' '!' 'y' 'Y' '!' 0x00A1
+Z 'Z' '#' 'z' 'Z' '#' 0x00
+
+COMMA ',' ',' ',' ';' ';' '|'
+PERIOD '.' '.' '.' ':' ':' 0x2026
+AT '@' '0' '@' '0' '0' 0x2022
+SLASH '/' '/' '/' '?' '?' '\'
+
+SPACE 0x20 0x20 0x20 0x20 0xEF01 0xEF01
+ENTER 0xa 0xa 0xa 0xa 0xa 0xa
+
+# on pc keyboards
+TAB 0x9 0x9 0x9 0x9 0x9 0x9
+0 '0' '0' '0' ')' ')' ')'
+1 '1' '1' '1' '!' '!' '!'
+2 '2' '2' '2' '@' '@' '@'
+3 '3' '3' '3' '#' '#' '#'
+4 '4' '4' '4' '$' '$' '$'
+5 '5' '5' '5' '%' '%' '%'
+6 '6' '6' '6' '^' '^' '^'
+7 '7' '7' '7' '&' '&' '&'
+8 '8' '8' '8' '*' '*' '*'
+9 '9' '9' '9' '(' '(' '('
+
+GRAVE '`' '`' '`' '~' '`' '~'
+MINUS '-' '-' '-' '_' '-' '_'
+EQUALS '=' '=' '=' '+' '=' '+'
+LEFT_BRACKET '[' '[' '[' '{' '[' '{'
+RIGHT_BRACKET ']' ']' ']' '}' ']' '}'
+BACKSLASH '\' '\' '\' '|' '\' '|'
+SEMICOLON ';' ';' ';' ':' ';' ':'
+APOSTROPHE ''' ''' ''' '"' ''' '"'
+STAR '*' '*' '*' '*' '*' '*'
+POUND '#' '#' '#' '#' '#' '#'
+PLUS '+' '+' '+' '+' '+' '+'
+
+
+
diff --git a/target/board/generic/tuttle2.kl b/target/board/generic/tuttle2.kl
new file mode 100644
index 0000000..a78a6eb
--- /dev/null
+++ b/target/board/generic/tuttle2.kl
@@ -0,0 +1,74 @@
+key 2 1
+key 3 2
+key 4 3
+key 5 4
+key 6 5
+key 7 6
+key 8 7
+key 9 8
+key 10 9
+key 11 0
+key 158 BACK WAKE_DROPPED
+key 230 SOFT_RIGHT WAKE
+key 60 SOFT_RIGHT WAKE
+key 107 ENDCALL WAKE_DROPPED
+key 62 ENDCALL WAKE_DROPPED
+key 229 MENU WAKE_DROPPED
+key 59 MENU WAKE_DROPPED
+key 228 POUND
+key 227 STAR
+key 231 CALL WAKE_DROPPED
+key 61 CALL WAKE_DROPPED
+key 232 DPAD_CENTER WAKE_DROPPED
+key 108 DPAD_DOWN WAKE_DROPPED
+key 103 DPAD_UP WAKE_DROPPED
+key 102 HOME WAKE
+key 105 DPAD_LEFT WAKE_DROPPED
+key 106 DPAD_RIGHT WAKE_DROPPED
+key 115 VOLUME_UP
+key 114 VOLUME_DOWN
+key 116 POWER WAKE
+key 212 SLASH
+
+key 16 Q
+key 17 W
+key 18 E
+key 19 R
+key 20 T
+key 21 Y
+key 22 U
+key 23 I
+key 24 O
+key 25 P
+
+key 30 A
+key 31 S
+key 32 D
+key 33 F
+key 34 G
+key 35 H
+key 36 J
+key 37 K
+key 38 L
+key 14 DEL
+
+key 44 Z
+key 45 X
+key 46 C
+key 47 V
+key 48 B
+key 49 N
+key 50 M
+key 51 COMMA
+key 52 PERIOD
+key 28 ENTER
+
+key 56 ALT_LEFT
+key 42 SHIFT_LEFT
+key 215 AT
+key 57 SPACE
+key 53 SLASH
+key 127 SYM
+key 100 ALT_LEFT
+
+key 399 GRAVE
diff --git a/target/board/sim/AndroidBoard.mk b/target/board/sim/AndroidBoard.mk
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/target/board/sim/AndroidBoard.mk
diff --git a/target/board/sim/BoardConfig.mk b/target/board/sim/BoardConfig.mk
new file mode 100644
index 0000000..92679d9
--- /dev/null
+++ b/target/board/sim/BoardConfig.mk
@@ -0,0 +1,22 @@
+# config.mk
+#
+# Product-specific compile-time definitions.
+#
+
+# Don't try prelinking or compressing the shared libraries
+# used by the simulator. The host OS won't know what to do
+# with them, and they may not even be ELF files.
+#
+# These definitions override the defaults in config/config.make.
+TARGET_COMPRESS_MODULE_SYMBOLS := false
+TARGET_PRELINK_MODULE := false
+
+# Don't try to build a bootloader.
+TARGET_NO_BOOTLOADER := true
+
+# Don't bother with a kernel
+TARGET_NO_KERNEL := true
+
+#the simulator partially emulates the original HTC /dev/eac audio interface
+HAVE_HTC_AUDIO_DRIVER := true
+BOARD_USES_GENERIC_AUDIO := true
diff --git a/target/product/AndroidProducts.mk b/target/product/AndroidProducts.mk
new file mode 100644
index 0000000..1bf3c3f
--- /dev/null
+++ b/target/product/AndroidProducts.mk
@@ -0,0 +1,33 @@
+#
+# 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 should set PRODUCT_MAKEFILES to a list of product makefiles
+# to expose to the build system. LOCAL_DIR will already be set to
+# the directory containing this file.
+#
+# This file may not rely on the value of any variable other than
+# LOCAL_DIR; do not use any conditionals, and do not look up the
+# value of any variable that isn't set in this file or in a file that
+# it includes.
+#
+
+PRODUCT_MAKEFILES := \
+ $(LOCAL_DIR)/generic.mk \
+ $(LOCAL_DIR)/min_dev.mk \
+ $(LOCAL_DIR)/sdk.mk \
+ $(LOCAL_DIR)/sim.mk \
+ $(LOCAL_DIR)/generic_with_google.mk
diff --git a/target/product/core.mk b/target/product/core.mk
new file mode 100644
index 0000000..117bb11
--- /dev/null
+++ b/target/product/core.mk
@@ -0,0 +1,23 @@
+PRODUCT_BRAND :=
+PRODUCT_NAME :=
+PRODUCT_DEVICE :=
+PRODUCT_POLICY := android.policy_phone
+PRODUCT_PROPERTY_OVERRIDES := \
+ ro.config.notification_sound=F1_New_SMS.ogg
+
+PRODUCT_PACKAGES := \
+ framework-res \
+ Browser \
+ Contacts \
+ Home \
+ HTMLViewer \
+ Phone \
+ ContactsProvider \
+ DownloadProvider \
+ GoogleSearch \
+ MediaProvider \
+ SettingsProvider \
+ TelephonyProvider \
+ UserDictionaryProvider \
+ PackageInstaller \
+ Bugreport
diff --git a/target/product/generic.mk b/target/product/generic.mk
new file mode 100644
index 0000000..b9bc070
--- /dev/null
+++ b/target/product/generic.mk
@@ -0,0 +1,26 @@
+# This is a generic product that isn't specialized for a specific device.
+# It includes the base Android platform. If you need Google-specific features,
+# you should derive from generic_with_google.mk
+
+PRODUCT_PACKAGES := \
+ AlarmClock \
+ AlarmProvider \
+ Calendar \
+ Camera \
+ DrmProvider \
+ LatinIME \
+ Mms \
+ Music \
+ Settings \
+ Sync \
+ Updater \
+ CalendarProvider \
+ SubscribedFeedsProvider \
+ SyncProvider
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/core.mk)
+
+# Overrides
+PRODUCT_BRAND := generic
+PRODUCT_DEVICE := generic
+PRODUCT_NAME := generic
diff --git a/target/product/generic_with_google.mk b/target/product/generic_with_google.mk
new file mode 100755
index 0000000..af499b3
--- /dev/null
+++ b/target/product/generic_with_google.mk
@@ -0,0 +1,13 @@
+# This is a generic product that isn't specialized for a specific device.
+# It includes the base Android platform including some Google-specific features.
+# If you do not want to include Google specific features, you should derive
+# from generic.mk
+
+PRODUCT_PACKAGES := \
+ GoogleContactsProvider \
+ GoogleSubscribedFeedsProvider
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/generic.mk)
+
+# Overrides
+PRODUCT_NAME := generic_with_google
diff --git a/target/product/min_dev.mk b/target/product/min_dev.mk
new file mode 100644
index 0000000..7d0fbe6
--- /dev/null
+++ b/target/product/min_dev.mk
@@ -0,0 +1,19 @@
+
+PRODUCT_POLICY := android.policy_phone
+PRODUCT_PROPERTY_OVERRIDES := \
+ ro.config.notification_sound=F1_New_SMS.ogg
+PRODUCT_BRAND := generic
+PRODUCT_NAME := min_dev
+PRODUCT_DEVICE := generic
+
+PRODUCT_PACKAGES := \
+ DownloadProvider \
+ GoogleSearch \
+ MediaProvider \
+ SettingsProvider \
+ PackageInstaller \
+ Bugreport \
+ Launcher \
+ Settings \
+ sqlite3
+
diff --git a/target/product/sdk.mk b/target/product/sdk.mk
new file mode 100644
index 0000000..e8109e5
--- /dev/null
+++ b/target/product/sdk.mk
@@ -0,0 +1,29 @@
+PRODUCT_PROPERTY_OVERRIDES :=
+
+PRODUCT_PACKAGES := \
+ AlarmClock \
+ ApiDemos \
+ Camera \
+ Development \
+ DrmProvider \
+ Email \
+ Fallback \
+ GPSEnable \
+ Launcher \
+ Maps \
+ Music \
+ Mms \
+ Settings \
+ SdkSetup \
+ CustomLocale \
+ gpstest \
+ sqlite3 \
+ SoftKeyboard
+
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/core.mk)
+
+# Overrides
+PRODUCT_BRAND := generic
+PRODUCT_NAME := sdk
+PRODUCT_DEVICE := generic
diff --git a/target/product/security/README b/target/product/security/README
new file mode 100644
index 0000000..b92693d
--- /dev/null
+++ b/target/product/security/README
@@ -0,0 +1,38 @@
+The following commands were used to generate the test key pair:
+
+ openssl genrsa -3 -out testkey.pem 2048
+
+ openssl req -new -x509 -key testkey.pem -out testkey.x509.pem -days 10000 \
+ -subj '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
+
+ openssl pkcs8 -in testkey.pem -topk8 -outform DER -out testkey.pk8 -nocrypt
+
+Alternatively you can use the "mkkey.sh" command included in this directory.
+
+The following standard test keys are currently included:
+
+testkey -- a generic key for packages that do not otherwise specify a key.
+platform -- a test key for packages that are part of the core platform.
+shared -- a test key for things that are shared in the home/contacts process.
+media -- a test key for packages that are part of the media/download system.
+
+These test keys are used strictly in development, and should never be assumed
+to convey any sort of validity. When $BUILD_SECURE=true, the code should not
+honor these keys in any context.
+
+
+signing using the openssl commandline (for boot/system images)
+--------------------------------------------------------------
+
+1. convert pk8 format key to pem format
+ % openssl pkcs8 -inform DER -nocrypt -in testkey.pk8 -out testkey.pem
+
+2. create a signature using the pem format key
+ % openssl dgst -binary -sha1 -sign testkey.pem FILE > FILE.sig
+
+extracting public keys for embedding
+------------------------------------
+it's a Java tool
+but it generates C code
+take a look at commands/recovery/Android.mk
+you'll see it running $(HOST_OUT_JAVA_LIBRARIES)/dumpkey.jar
\ No newline at end of file
diff --git a/target/product/security/media.pk8 b/target/product/security/media.pk8
new file mode 100644
index 0000000..a6db9ba
--- /dev/null
+++ b/target/product/security/media.pk8
Binary files differ
diff --git a/target/product/security/media.x509.pem b/target/product/security/media.x509.pem
new file mode 100644
index 0000000..98cd443
--- /dev/null
+++ b/target/product/security/media.x509.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEqDCCA5CgAwIBAgIJAPK5jmEjVyxOMA0GCSqGSIb3DQEBBAUAMIGUMQswCQYD
+VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4g
+VmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UE
+AxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAe
+Fw0wODA0MTUyMzQwNTdaFw0zNTA5MDEyMzQwNTdaMIGUMQswCQYDVQQGEwJVUzET
+MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4G
+A1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9p
+ZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZI
+hvcNAQEBBQADggENADCCAQgCggEBAK4lDFoW75f8KGmsZRsyF8w2ug6GlkFo1YoE
+n0DOhYZxI6P/tPbZScM88to6BcI+rKpX2AOImxdZvPWefG8hiQriUIW37VaqYmwJ
+ie+czTY2LKDo0blgP9TYModnkmzMCQxot3Wuf/MJNMw2nvKFWiZn3wxmf9DHz12O
+umVYBnNzA7tiRybquu37cvB+16dqs8uaOBxLfc2AmxQNiR8AITvkAfWNagamHq3D
+qcLxxlZyhbCa4JNCpm+kIer5Ot91c6AowzHXBgGrOvfMhAM+znx3KjpbhrDb6dd3
+w6SKqYAe3O4ngVifRNnkETl5YAV2qZQQuoEJElna2YxsaP94S48CAQOjgfwwgfkw
+HQYDVR0OBBYEFMopPKqLwO0+VC7vQgWiv/K1fk11MIHJBgNVHSMEgcEwgb6AFMop
+PKqLwO0+VC7vQgWiv/K1fk11oYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UE
+CBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMH
+QW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAG
+CSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJAPK5jmEjVyxOMAwGA1Ud
+EwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBAITelRbV5KhyF6c9qEhwSPUzc6X3
+M/OQ1hvfPMnlJRYlv8qnwxWcriddFyqa4eh21UWBJ6xUL2gpDdUQwAKdj1Hg7hVr
+e3tazbOUJBuOx4t05cQsXK+uFWyvW9GZojonUk2gct6743hGSlM2MLDk0P+34I7L
+cB+ttjecdEZ/bgDG7YiFlTgHkgOHVgB4csjjAHr0I6V6LKs6KChptkxLe9X8GH0K
+fiQVll1ark4Hpt91G0p16Xk8kYphK4HNC2KK7gFo3ETkexDTWTJghJ1q321yfcJE
+RMIh0/nsw2jK0HmZ8rgQW8HyDTjUEGbMFBHCV6lupDSfV0ZWVQfk6AIKGoE=
+-----END CERTIFICATE-----
diff --git a/target/product/security/mkkey.sh b/target/product/security/mkkey.sh
new file mode 100644
index 0000000..86744f6
--- /dev/null
+++ b/target/product/security/mkkey.sh
@@ -0,0 +1,15 @@
+if ["$1" == ""]; then
+ echo "Create a test certificate key."
+ echo "Usage: $0 NAME"
+ echo "Will generate NAME.pk8 and NAME.x509.pem"
+ echo " /C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com"
+ return
+fi
+
+openssl genrsa -3 -out $1.pem 2048
+
+openssl req -new -x509 -key $1.pem -out $1.x509.pem -days 10000 \
+ -subj '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
+
+openssl pkcs8 -in $1.pem -topk8 -outform DER -out $1.pk8 -nocrypt
+
diff --git a/target/product/security/platform.pk8 b/target/product/security/platform.pk8
new file mode 100644
index 0000000..e27a393
--- /dev/null
+++ b/target/product/security/platform.pk8
Binary files differ
diff --git a/target/product/security/platform.x509.pem b/target/product/security/platform.x509.pem
new file mode 100644
index 0000000..087f02e
--- /dev/null
+++ b/target/product/security/platform.x509.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEqDCCA5CgAwIBAgIJALOZgIbQVs/6MA0GCSqGSIb3DQEBBAUAMIGUMQswCQYD
+VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4g
+VmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UE
+AxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAe
+Fw0wODA0MTUyMjQwNTBaFw0zNTA5MDEyMjQwNTBaMIGUMQswCQYDVQQGEwJVUzET
+MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4G
+A1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9p
+ZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZI
+hvcNAQEBBQADggENADCCAQgCggEBAJx4BZKsDV04HN6qZezIpgBuNkgMbXIHsSAR
+vlCGOqvitV0Amt9xRtbyICKAx81Ne9smJDuKgGwms0sTdSOkkmgiSQTcAUk+fArP
+GgXIdPabA3tgMJ2QdNJCgOFrrSqHNDYZUer3KkgtCbIEsYdeEqyYwap3PWgAuer9
+5W1Yvtjo2hb5o2AJnDeoNKbf7be2tEoEngeiafzPLFSW8s821k35CjuNjzSjuqtM
+9TNxqydxmzulh1StDFP8FOHbRdUeI0+76TybpO35zlQmE1DsU1YHv2mi/0qgfbX3
+6iANCabBtJ4hQC+J7RGQiTqrWpGA8VLoL4WkV1PPX8GQccXuyCcCAQOjgfwwgfkw
+HQYDVR0OBBYEFE/koLPdnLop9x1yh8Tnw48ghsKZMIHJBgNVHSMEgcEwgb6AFE/k
+oLPdnLop9x1yh8Tnw48ghsKZoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UE
+CBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMH
+QW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAG
+CSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJALOZgIbQVs/6MAwGA1Ud
+EwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBAFclUbjZOh9z3g9tRp+G2tZwFAAp
+PIigzXzXeLc9r8wZf6t25iEuVsHHYc/EL9cz3lLFCuCIFM78CjtaGkNGBU2Cnx2C
+tCsgSL+ItdFJKe+F9g7dEtctVWV+IuPoXQTIMdYT0Zk4u4mCJH+jISVroS0dao+S
+6h2xw3Mxe6DAN/DRr/ZFrvIkl5+6bnoUvAJccbmBOM7z3fwFlhfPJIRc97QNY4L3
+J17XOElatuWTG5QhdlxJG3L7aOCA29tYwgKdNHyLMozkPvaosVUz7fvpib1qSN1L
+IC7alMarjdW4OZID2q4u1EYjLk/pvZYTlMYwDlE448/Shebk5INTjLixs1c=
+-----END CERTIFICATE-----
diff --git a/target/product/security/shared.pk8 b/target/product/security/shared.pk8
new file mode 100644
index 0000000..cf99acd
--- /dev/null
+++ b/target/product/security/shared.pk8
Binary files differ
diff --git a/target/product/security/shared.x509.pem b/target/product/security/shared.x509.pem
new file mode 100644
index 0000000..7f886a8
--- /dev/null
+++ b/target/product/security/shared.x509.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEqDCCA5CgAwIBAgIJAPKnM5a9OHZ6MA0GCSqGSIb3DQEBBAUAMIGUMQswCQYD
+VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4g
+VmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UE
+AxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAe
+Fw0wODA3MjMyMTU3NTlaFw0zNTEyMDkyMTU3NTlaMIGUMQswCQYDVQQGEwJVUzET
+MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4G
+A1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9p
+ZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZI
+hvcNAQEBBQADggENADCCAQgCggEBAMjC2/0JSi30XD/xoy7SGAXscvxY0BeXG9D2
+tSwmLXCBnRkZZ+FY39Oix/Gz4OgM5UXXnShIIgIR64bw/YMS03tCDBE3UMyUYYro
+cvSIZGO9xGJ8qgwEg8hkk+NRVXEXAzi/3MTNat3RwKLzX1zyTtPkBDo+WOKwXmZM
+zeEry2dzX9bfEknDaeYlQrwKRynlORf1w4/6UtF7c8nHN5jdsY7UgVkIdVR+Zr/F
+2spMJabrlg7ZaSNwnaMCumRstJazJehsXIsuejN3srvkx88zJUKRFj9okVKsCIVQ
+yDxQj0v1rfCu1aLcoFg/mrCtF2UNt+6ksj/bRYhVR9D+q3IYOIkCAQOjgfwwgfkw
+HQYDVR0OBBYEFMtMfizbs/CtqY2reZaNFy6dux7RMIHJBgNVHSMEgcEwgb6AFMtM
+fizbs/CtqY2reZaNFy6dux7RoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UE
+CBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMH
+QW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAG
+CSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJAPKnM5a9OHZ6MAwGA1Ud
+EwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBAECo0JaZeVnpF6NsRCRra6wrrgVD
+fs2JeUEY94NHIDUtHG+KObCGmUL02mWYH6opUdM5cRKewZIdeVZxxSfW4knyUoKf
+r1tZExAxHi3gllANVorUEUplbcNKjG9hBFOvwep5ktukqns/hUOm41wHKN53/pfu
+rIN3H9DskPjkRJQ07gtgRXg+cMei5GAkkmDgA892CNw1Kkye9wbe9LJgUOl4ri//
+16MyN4cBSRXrPMh0/MeprpMId8XIx9HC4qjuhjyJGA0YVc7bpADnukPMyqckPTl+
+fA6Ojk19T5K2u+rUnAzwGAae3coufi+0Zo2J2715UNDNJUGA+h6q/CpVb4Q=
+-----END CERTIFICATE-----
diff --git a/target/product/security/testkey.pk8 b/target/product/security/testkey.pk8
new file mode 100644
index 0000000..586c1bd
--- /dev/null
+++ b/target/product/security/testkey.pk8
Binary files differ
diff --git a/target/product/security/testkey.x509.pem b/target/product/security/testkey.x509.pem
new file mode 100644
index 0000000..e242d83
--- /dev/null
+++ b/target/product/security/testkey.x509.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEqDCCA5CgAwIBAgIJAJNurL4H8gHfMA0GCSqGSIb3DQEBBQUAMIGUMQswCQYD
+VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4g
+VmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UE
+AxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAe
+Fw0wODAyMjkwMTMzNDZaFw0zNTA3MTcwMTMzNDZaMIGUMQswCQYDVQQGEwJVUzET
+MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4G
+A1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9p
+ZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZI
+hvcNAQEBBQADggENADCCAQgCggEBANaTGQTexgskse3HYuDZ2CU+Ps1s6x3i/waM
+qOi8qM1r03hupwqnbOYOuw+ZNVn/2T53qUPn6D1LZLjk/qLT5lbx4meoG7+yMLV4
+wgRDvkxyGLhG9SEVhvA4oU6Jwr44f46+z4/Kw9oe4zDJ6pPQp8PcSvNQIg1QCAcy
+4ICXF+5qBTNZ5qaU7Cyz8oSgpGbIepTYOzEJOmc3Li9kEsBubULxWBjf/gOBzAzU
+RNps3cO4JFgZSAGzJWQTT7/emMkod0jb9WdqVA2BVMi7yge54kdVMxHEa5r3b97s
+zI5p58ii0I54JiCUP5lyfTwE/nKZHZnfm644oLIXf6MdW2r+6R8CAQOjgfwwgfkw
+HQYDVR0OBBYEFEhZAFY9JyxGrhGGBaR0GawJyowRMIHJBgNVHSMEgcEwgb6AFEhZ
+AFY9JyxGrhGGBaR0GawJyowRoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UE
+CBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMH
+QW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAG
+CSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJAJNurL4H8gHfMAwGA1Ud
+EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHqvlozrUMRBBVEY0NqrrwFbinZa
+J6cVosK0TyIUFf/azgMJWr+kLfcHCHJsIGnlw27drgQAvilFLAhLwn62oX6snb4Y
+LCBOsVMR9FXYJLZW2+TcIkCRLXWG/oiVHQGo/rWuWkJgU134NDEFJCJGjDbiLCpe
++ZTWHdcwauTJ9pUbo8EvHRkU3cYfGmLaLfgn9gP+pWA7LFQNvXwBnDa6sppCccEX
+31I828XzgXpJ4O+mDL1/dBd+ek8ZPUP0IgdyZm5MTYPhvVqGCHzzTy3sIeJFymwr
+sBbmg2OAUNLEMO6nwmocSdN2ClirfxqCzJOLSDE4QyS9BAH6EhY6UFcOaE0=
+-----END CERTIFICATE-----
diff --git a/target/product/sim.mk b/target/product/sim.mk
new file mode 100644
index 0000000..7b27495
--- /dev/null
+++ b/target/product/sim.mk
@@ -0,0 +1,9 @@
+PRODUCT_PACKAGES := \
+ IM
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_with_google.mk)
+
+# Overrides
+PRODUCT_NAME := sim
+PRODUCT_DEVICE := sim
+PRODUCT_LOCALES := en_US
diff --git a/tools/acp/Android.mk b/tools/acp/Android.mk
new file mode 100644
index 0000000..5e0e2e4
--- /dev/null
+++ b/tools/acp/Android.mk
@@ -0,0 +1,26 @@
+# Copyright 2005 The Android Open Source Project
+#
+# Custom version of cp.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ acp.c
+
+ifeq ($(HOST_OS),cygwin)
+LOCAL_CFLAGS += -DWIN32_EXE
+endif
+ifeq ($(HOST_OS),darwin)
+LOCAL_CFLAGS += -DMACOSX_RSRC
+endif
+ifeq ($(HOST_OS),linux)
+endif
+
+LOCAL_STATIC_LIBRARIES := libhost
+LOCAL_C_INCLUDES := build/libs/host/include
+LOCAL_MODULE := acp
+LOCAL_ACP_UNAVAILABLE := true
+
+include $(BUILD_HOST_EXECUTABLE)
+
diff --git a/tools/acp/README b/tools/acp/README
new file mode 100644
index 0000000..a1809d9
--- /dev/null
+++ b/tools/acp/README
@@ -0,0 +1,40 @@
+README for Android "acp" Command
+
+The "cp" command was judged and found wanting. The issues are:
+
+Mac OS X:
+ - Uses the BSD cp, not the fancy GNU cp. It lacks the "-u" flag, which
+ only copies files if they are newer than the destination. This can
+ slow the build when copying lots of content.
+ - Doesn't take the "-d" flag, which causes symlinks to be copied as
+ links. This is the default behavior, so it's not all bad, but it
+ complains if you supply "-d".
+
+MinGW/Cygwin:
+ - Gets really weird when copying a file called "foo.exe", failing with
+ "cp: skipping file 'foo.exe', as it was replaced while being copied".
+ This only seems to happen when the source file is on an NFS/Samba
+ volume. "cp" works okay copying from local disk.
+
+Linux:
+ - On some systems it's possible to have microsecond-accurate timestamps
+ on an NFS volume, and non-microsecond timestamps on a local volume.
+ If you copy from NFS to local disk, your NFS files will always be
+ newer, because the local disk time stamp is truncated rather than
+ rounded up. This foils the "-u" flag if you also supply the "-p" flag
+ to preserve timestamps.
+ - The Darwin linker insists that ranlib be current. If you copy the
+ library, the time stamp no longer matches. Preserving the time
+ stamp is essential, so simply turning the "-p" flag off doesn't work.
+
+Futzing around these in make with GNU make functions is awkward at best.
+It's easier and more reliable to write a cp command that works properly.
+
+
+The "acp" command takes most of the standard flags, following the GNU
+conventions. It adds a "-e" flag, used when copying executables around.
+On most systems it is ignored, but on MinGW/Cygwin it allows "cp foo bar"
+to work when what is actually meant is "cp foo.exe bar.exe". Unlike the
+default Cygwin cp, "acp foo bar" will not find foo.exe unless you add
+the "-e" flag, avoiding potential ambiguity.
+
diff --git a/tools/acp/acp.c b/tools/acp/acp.c
new file mode 100644
index 0000000..eb1de1f
--- /dev/null
+++ b/tools/acp/acp.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2005 The Android Open Source Project
+ *
+ * Android "cp" replacement.
+ *
+ * The GNU/Linux "cp" uses O_LARGEFILE in its open() calls, utimes() instead
+ * of utime(), and getxattr()/setxattr() instead of chmod(). These are
+ * probably "better", but are non-portable, and not necessary for our
+ * purposes.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <getopt.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <utime.h>
+#include <limits.h>
+#include <errno.h>
+#include <assert.h>
+#include <host/CopyFile.h>
+
+/*#define DEBUG_MSGS*/
+#ifdef DEBUG_MSGS
+# define DBUG(x) printf x
+#else
+# define DBUG(x) ((void)0)
+#endif
+
+#define FSSEP '/' /* filename separator char */
+
+
+/*
+ * Process the command-line file arguments.
+ *
+ * Returns 0 on success.
+ */
+int process(int argc, char* const argv[], unsigned int options)
+{
+ int retVal = 0;
+ int i, cc;
+ char* stripDest = NULL;
+ int stripDestLen;
+ struct stat destStat;
+ bool destMustBeDir = false;
+ struct stat sb;
+
+ assert(argc >= 2);
+
+ /*
+ * Check for and trim a trailing slash on the last arg.
+ *
+ * It's useful to be able to say "cp foo bar/" when you want to copy
+ * a single file into a directory. If you say "cp foo bar", and "bar"
+ * does not exist, it will create "bar", when what you really wanted
+ * was for the cp command to fail with "directory does not exist".
+ */
+ stripDestLen = strlen(argv[argc-1]);
+ stripDest = malloc(stripDestLen+1);
+ memcpy(stripDest, argv[argc-1], stripDestLen+1);
+ if (stripDest[stripDestLen-1] == FSSEP) {
+ stripDest[--stripDestLen] = '\0';
+ destMustBeDir = true;
+ }
+
+ if (argc > 2)
+ destMustBeDir = true;
+
+ /*
+ * Start with a quick check to ensure that, if we're expecting to copy
+ * to a directory, the target already exists and is actually a directory.
+ * It's okay if it's a symlink to a directory.
+ *
+ * If it turns out to be a directory, go ahead and raise the
+ * destMustBeDir flag so we do some path concatenation below.
+ */
+ if (stat(stripDest, &sb) < 0) {
+ if (destMustBeDir) {
+ if (errno == ENOENT)
+ fprintf(stderr,
+ "acp: destination directory '%s' does not exist\n",
+ stripDest);
+ else
+ fprintf(stderr, "acp: unable to stat dest dir\n");
+ retVal = 1;
+ goto bail;
+ }
+ } else {
+ if (S_ISDIR(sb.st_mode)) {
+ DBUG(("--- dest exists and is a dir, setting flag\n"));
+ destMustBeDir = true;
+ } else if (destMustBeDir) {
+ fprintf(stderr,
+ "acp: destination '%s' is not a directory\n",
+ stripDest);
+ retVal = 1;
+ goto bail;
+ }
+ }
+
+ /*
+ * Copying files.
+ *
+ * Strip trailing slashes off. They shouldn't be there, but
+ * sometimes file completion will put them in for directories.
+ *
+ * The observed behavior of GNU and BSD cp is that they print warnings
+ * if something fails, but continue on. If any part fails, the command
+ * exits with an error status.
+ */
+ for (i = 0; i < argc-1; i++) {
+ const char* srcName;
+ char* src;
+ char* dst;
+ int copyResult;
+ int srcLen;
+
+ /* make a copy of the source name, and strip trailing '/' */
+ srcLen = strlen(argv[i]);
+ src = malloc(srcLen+1);
+ memcpy(src, argv[i], srcLen+1);
+
+ if (src[srcLen-1] == FSSEP)
+ src[--srcLen] = '\0';
+
+ /* find just the name part */
+ srcName = strrchr(src, FSSEP);
+ if (srcName == NULL) {
+ srcName = src;
+ } else {
+ srcName++;
+ assert(*srcName != '\0');
+ }
+
+ if (destMustBeDir) {
+ /* concatenate dest dir and src name */
+ int srcNameLen = strlen(srcName);
+
+ dst = malloc(stripDestLen +1 + srcNameLen +1);
+ memcpy(dst, stripDest, stripDestLen);
+ dst[stripDestLen] = FSSEP;
+ memcpy(dst + stripDestLen+1, srcName, srcNameLen+1);
+ } else {
+ /* simple */
+ dst = stripDest;
+ }
+
+ /*
+ * Copy the source to the destination.
+ */
+ copyResult = copyFile(src, dst, options);
+
+ if (copyResult != 0)
+ retVal = 1;
+
+ free(src);
+ if (dst != stripDest)
+ free(dst);
+ }
+
+bail:
+ free(stripDest);
+ return retVal;
+}
+
+/*
+ * Set up the options.
+ */
+int main(int argc, char* const argv[])
+{
+ bool wantUsage;
+ int ic, retVal;
+ int verboseLevel;
+ unsigned int options;
+
+ verboseLevel = 0;
+ options = 0;
+ wantUsage = false;
+
+ while (1) {
+ ic = getopt(argc, argv, "defprtuv");
+ if (ic < 0)
+ break;
+
+ switch (ic) {
+ case 'd':
+ options |= COPY_NO_DEREFERENCE;
+ break;
+ case 'e':
+ options |= COPY_TRY_EXE;
+ break;
+ case 'f':
+ options |= COPY_FORCE;
+ break;
+ case 'p':
+ options |= COPY_PERMISSIONS;
+ break;
+ case 't':
+ options |= COPY_TIMESTAMPS;
+ break;
+ case 'r':
+ options |= COPY_RECURSIVE;
+ break;
+ case 'u':
+ options |= COPY_UPDATE_ONLY;
+ break;
+ case 'v':
+ verboseLevel++;
+ break;
+ default:
+ fprintf(stderr, "Unexpected arg -%c\n", ic);
+ wantUsage = true;
+ break;
+ }
+
+ if (wantUsage)
+ break;
+ }
+
+ options |= verboseLevel & COPY_VERBOSE_MASK;
+
+ if (optind == argc-1) {
+ fprintf(stderr, "acp: missing destination file\n");
+ return 2;
+ } else if (optind+2 > argc)
+ wantUsage = true;
+
+ if (wantUsage) {
+ fprintf(stderr, "Usage: acp [OPTION]... SOURCE DEST\n");
+ fprintf(stderr, " or: acp [OPTION]... SOURCE... DIRECTORY\n");
+ fprintf(stderr, "\nOptions:\n");
+ fprintf(stderr, " -d never follow (dereference) symbolic links\n");
+ fprintf(stderr, " -e if source file doesn't exist, try adding "
+ "'.exe' [Win32 only]\n");
+ fprintf(stderr, " -f use force, removing existing file if it's "
+ "not writeable\n");
+ fprintf(stderr, " -p preserve mode, ownership\n");
+ fprintf(stderr, " -r recursive copy\n");
+ fprintf(stderr, " -t preserve timestamps\n");
+ fprintf(stderr, " -u update only: don't copy if dest is newer\n");
+ fprintf(stderr, " -v verbose output (-vv is more verbose)\n");
+ return 2;
+ }
+
+ retVal = process(argc-optind, argv+optind, options);
+ DBUG(("EXIT: %d\n", retVal));
+ return retVal;
+}
+
diff --git a/tools/apicheck/Android.mk b/tools/apicheck/Android.mk
new file mode 100644
index 0000000..a2ff8a2
--- /dev/null
+++ b/tools/apicheck/Android.mk
@@ -0,0 +1,44 @@
+# Copyright (C) 2007-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.
+
+LOCAL_PATH := $(call my-dir)
+
+# We use copy-file-to-new-target so that the installed
+# script file's timestamp is at least as new as the
+# .jar file it wraps.
+
+#TODO(dbort): add a template to do this stuff; share with jx
+
+# the hat script
+# ============================================================
+include $(CLEAR_VARS)
+LOCAL_IS_HOST_MODULE := true
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE := apicheck
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(HOST_OUT_JAVA_LIBRARIES)/apicheck$(COMMON_JAVA_PACKAGE_SUFFIX)
+$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/etc/apicheck | $(ACP)
+ @echo "Copy: $(PRIVATE_MODULE) ($@)"
+ $(copy-file-to-new-target)
+ $(hide) chmod 755 $@
+
+# the other stuff
+# ============================================================
+subdirs := $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \
+ src \
+ ))
+
+include $(subdirs)
diff --git a/tools/apicheck/etc/apicheck b/tools/apicheck/etc/apicheck
new file mode 100644
index 0000000..9c00e25
--- /dev/null
+++ b/tools/apicheck/etc/apicheck
@@ -0,0 +1,46 @@
+#!/bin/bash
+#
+# Copyright (C) 2005, 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.
+
+# Set up prog to be the path of this script, including following symlinks,
+# and set up progdir to be the fully-qualified pathname of its directory.
+prog="$0"
+while [ -h "${prog}" ]; do
+ newProg=`/bin/ls -ld "${prog}"`
+ newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
+ if expr "x${newProg}" : 'x/' >/dev/null; then
+ prog="${newProg}"
+ else
+ progdir=`dirname "${prog}"`
+ prog="${progdir}/${newProg}"
+ fi
+done
+oldwd=`pwd`
+progdir=`dirname "${prog}"`
+cd "${progdir}"
+progdir=`pwd`
+prog="${progdir}"/`basename "${prog}"`
+cd "${oldwd}"
+
+libdir=`dirname $progdir`/framework
+
+javaOpts=""
+while expr "x$1" : 'x-J' >/dev/null; do
+ opt=`expr "$1" : '-J\(.*\)'`
+ javaOpts="${javaOpts} -${opt}"
+ shift
+done
+
+exec java $javaOpts -jar $libdir/apicheck.jar "$@"
diff --git a/tools/apicheck/src/Android.mk b/tools/apicheck/src/Android.mk
new file mode 100644
index 0000000..c4e7c6e
--- /dev/null
+++ b/tools/apicheck/src/Android.mk
@@ -0,0 +1,28 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+
+# apicheck java library
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_JAR_MANIFEST := MANIFEST.mf
+
+LOCAL_MODULE:= apicheck
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/tools/apicheck/src/MANIFEST.mf b/tools/apicheck/src/MANIFEST.mf
new file mode 100644
index 0000000..e6dc263
--- /dev/null
+++ b/tools/apicheck/src/MANIFEST.mf
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Main-Class: com.android.apicheck.ApiCheck
diff --git a/tools/apicheck/src/com/android/apicheck/AbstractMethodInfo.java b/tools/apicheck/src/com/android/apicheck/AbstractMethodInfo.java
new file mode 100644
index 0000000..ca90820
--- /dev/null
+++ b/tools/apicheck/src/com/android/apicheck/AbstractMethodInfo.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+package com.android.apicheck;
+
+public interface AbstractMethodInfo {
+
+ public void addException(String exec);
+ public void addParameter(ParameterInfo p);
+
+}
diff --git a/tools/apicheck/src/com/android/apicheck/ApiCheck.java b/tools/apicheck/src/com/android/apicheck/ApiCheck.java
new file mode 100644
index 0000000..f78117c
--- /dev/null
+++ b/tools/apicheck/src/com/android/apicheck/ApiCheck.java
@@ -0,0 +1,253 @@
+/*
+ * 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.
+ */
+
+package com.android.apicheck;
+
+import org.xml.sax.*;
+import org.xml.sax.helpers.*;
+import java.io.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Stack;
+
+public class ApiCheck {
+ // parse out and consume the -whatever command line flags
+ private static ArrayList<String[]> parseFlags(ArrayList<String> allArgs) {
+ ArrayList<String[]> ret = new ArrayList<String[]>();
+
+ int i;
+ for (i = 0; i < allArgs.size(); i++) {
+ // flags with one value attached
+ String flag = allArgs.get(i);
+ if (flag.equals("-error")
+ || flag.equals("-warning")
+ || flag.equals("-hide")) {
+ String[] arg = new String[2];
+ arg[0] = flag;
+ arg[1] = allArgs.get(++i);
+ ret.add(arg);
+ } else {
+ // we've consumed all of the -whatever args, so we're done
+ break;
+ }
+ }
+
+ // i now points to the first non-flag arg; strip what came before
+ for (; i > 0; i--) {
+ allArgs.remove(0);
+ }
+ return ret;
+ }
+
+ public static void main(String[] originalArgs) {
+ // translate to an ArrayList<String> for munging
+ ArrayList<String> args = new ArrayList<String>(originalArgs.length);
+ for (String a: originalArgs) {
+ args.add(a);
+ }
+
+ ArrayList<String[]> flags = ApiCheck.parseFlags(args);
+ for (String[] a: flags) {
+ if (a[0].equals("-error") || a[0].equals("-warning")
+ || a[0].equals("-hide")) {
+ try {
+ int level = -1;
+ if (a[0].equals("-error")) {
+ level = Errors.ERROR;
+ }
+ else if (a[0].equals("-warning")) {
+ level = Errors.WARNING;
+ }
+ else if (a[0].equals("-hide")) {
+ level = Errors.HIDDEN;
+ }
+ Errors.setErrorLevel(Integer.parseInt(a[1]), level);
+ }
+ catch (NumberFormatException e) {
+ System.err.println("Bad argument: " + a[0] + " " + a[1]);
+ System.exit(2);
+ }
+ }
+ }
+
+ String xmlFileName = args.get(0);
+ String xmlFileNameNew = args.get(1);
+ XMLReader xmlreader = null;
+ try {
+ // parse the XML files into our data structures
+ xmlreader = XMLReaderFactory.createXMLReader();
+ ApiCheck acheck = new ApiCheck();
+ MakeHandler handler = acheck.new MakeHandler();
+ xmlreader.setContentHandler(handler);
+ xmlreader.setErrorHandler(handler);
+ FileReader filereader = new FileReader(xmlFileName);
+ xmlreader.parse(new InputSource(filereader));
+ FileReader filereaderNew = new FileReader(xmlFileNameNew);
+ xmlreader.parse(new InputSource(filereaderNew));
+
+ // establish the superclass relationships
+ handler.getOldApi().resolveSuperclasses();
+ handler.getNewApi().resolveSuperclasses();
+
+ // finally, run the consistency check
+ handler.getOldApi().isConsistent(handler.getNewApi());
+
+ } catch (SAXParseException e) {
+ Errors.error(Errors.PARSE_ERROR,
+ new SourcePositionInfo(xmlFileName, e.getLineNumber(), 0),
+ e.getMessage());
+ } catch (Exception e) {
+ e.printStackTrace();
+ Errors.error(Errors.PARSE_ERROR,
+ new SourcePositionInfo(xmlFileName, 0, 0),
+ e.getMessage());
+ }
+
+ Errors.printErrors();
+ System.exit(Errors.hadError ? 1 : 0);
+ }
+
+ private class MakeHandler extends DefaultHandler {
+
+ private Integer mWarningCount;
+ private ApiInfo mOriginalApi;
+ private ApiInfo mNewApi;
+ private boolean mOldApi;
+ private PackageInfo mCurrentPackage;
+ private ClassInfo mCurrentClass;
+ private AbstractMethodInfo mCurrentMethod;
+ private ConstructorInfo mCurrentConstructor;
+ private Stack<ClassInfo> mClassScope = new Stack<ClassInfo>();
+
+
+ public MakeHandler() {
+ super();
+ mOriginalApi = new ApiInfo();
+ mNewApi = new ApiInfo();
+ mOldApi = true;
+
+ }
+
+ public void startElement(String uri, String localName, String qName,
+ Attributes attributes) {
+ if (qName.equals("package")) {
+ mCurrentPackage = new PackageInfo(attributes.getValue("name"),
+ SourcePositionInfo.fromXml(attributes.getValue("source")));
+ } else if (qName.equals("class")
+ || qName.equals("interface")) {
+ // push the old outer scope for later recovery, then set
+ // up the new current class object
+ mClassScope.push(mCurrentClass);
+ mCurrentClass = new ClassInfo(attributes.getValue("name"),
+ mCurrentPackage,
+ attributes.getValue("extends") ,
+ qName.equals("interface"),
+ Boolean.valueOf(
+ attributes.getValue("abstract")),
+ Boolean.valueOf(
+ attributes.getValue("static")),
+ Boolean.valueOf(
+ attributes.getValue("final")),
+ attributes.getValue("deprecated"),
+ attributes.getValue("visibility"),
+ SourcePositionInfo.fromXml(attributes.getValue("source")),
+ mCurrentClass);
+ } else if (qName.equals("method")) {
+ mCurrentMethod = new MethodInfo(attributes.getValue("name"),
+ attributes.getValue("return") ,
+ Boolean.valueOf(
+ attributes.getValue("abstract")),
+ Boolean.valueOf(
+ attributes.getValue("native")),
+ Boolean.valueOf(
+ attributes.getValue("synchronized")),
+ Boolean.valueOf(
+ attributes.getValue("static")),
+ Boolean.valueOf(
+ attributes.getValue("final")),
+ attributes.getValue("deprecated"),
+ attributes.getValue("visibility"),
+ SourcePositionInfo.fromXml(attributes.getValue("source")),
+ mCurrentClass);
+ } else if (qName.equals("constructor")) {
+ mCurrentMethod = new ConstructorInfo(attributes.getValue("name"),
+ attributes.getValue("type") ,
+ Boolean.valueOf(
+ attributes.getValue("static")),
+ Boolean.valueOf(
+ attributes.getValue("final")),
+ attributes.getValue("deprecated"),
+ attributes.getValue("visibility"),
+ SourcePositionInfo.fromXml(attributes.getValue("source")),
+ mCurrentClass);
+ } else if (qName.equals("field")) {
+ FieldInfo fInfo = new FieldInfo(attributes.getValue("name"),
+ attributes.getValue("type") ,
+ Boolean.valueOf(
+ attributes.getValue("transient")),
+ Boolean.valueOf(
+ attributes.getValue("volatile")),
+ attributes.getValue("value"),
+ Boolean.valueOf(
+ attributes.getValue("static")),
+ Boolean.valueOf(
+ attributes.getValue("final")),
+ attributes.getValue("deprecated"),
+ attributes.getValue("visibility"),
+ SourcePositionInfo.fromXml(attributes.getValue("source")),
+ mCurrentClass);
+ mCurrentClass.addField(fInfo);
+ } else if (qName.equals("parameter")) {
+ mCurrentMethod.addParameter(new ParameterInfo(attributes.getValue("type"),
+ attributes.getValue("name")));
+ } else if (qName.equals("exception")) {
+ mCurrentMethod.addException(attributes.getValue("type"));
+ } else if (qName.equals("implements")) {
+ mCurrentClass.addInterface(attributes.getValue("name"));
+ }
+ }
+ public void endElement(String uri, String localName, String qName) {
+ if (qName.equals("method")) {
+ mCurrentClass.addMethod((MethodInfo) mCurrentMethod);
+ } else if (qName.equals("constructor")) {
+ mCurrentClass.addConstructor((ConstructorInfo) mCurrentMethod);
+ } else if (qName.equals("class")
+ || qName.equals("interface")) {
+ mCurrentPackage.addClass(mCurrentClass);
+ mCurrentClass = mClassScope.pop();
+ } else if (qName.equals("package")){
+ if (mOldApi) {
+ mOriginalApi.addPackage(mCurrentPackage);
+ } else {
+ mNewApi.addPackage(mCurrentPackage);
+ }
+ }
+ }
+ public void endDocument() {
+ mOldApi = !mOldApi;
+ }
+
+ public ApiInfo getOldApi() {
+ return mOriginalApi;
+ }
+
+ public ApiInfo getNewApi() {
+ return mNewApi;
+ }
+
+
+ }
+}
diff --git a/tools/apicheck/src/com/android/apicheck/ApiInfo.java b/tools/apicheck/src/com/android/apicheck/ApiInfo.java
new file mode 100644
index 0000000..01d8f9e
--- /dev/null
+++ b/tools/apicheck/src/com/android/apicheck/ApiInfo.java
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+package com.android.apicheck;
+import java.util.*;
+
+public class ApiInfo {
+
+ private HashMap<String, PackageInfo> mPackages;
+ private HashMap<String, ClassInfo> mAllClasses;
+
+ public ApiInfo() {
+ mPackages = new HashMap<String, PackageInfo>();
+ mAllClasses = new HashMap<String, ClassInfo>();
+ }
+
+ public boolean isConsistent(ApiInfo otherApi) {
+ boolean consistent = true;
+ for (PackageInfo pInfo : mPackages.values()) {
+ if (otherApi.getPackages().containsKey(pInfo.name())) {
+ if (!pInfo.isConsistent(otherApi.getPackages().get(pInfo.name()))) {
+ consistent = false;
+ }
+ } else {
+ Errors.error(Errors.REMOVED_PACKAGE, pInfo.position(),
+ "Removed package " + pInfo.name());
+ consistent = false;
+ }
+ }
+ for (PackageInfo pInfo : otherApi.mPackages.values()) {
+ if (!pInfo.isInBoth()) {
+ Errors.error(Errors.ADDED_PACKAGE, pInfo.position(),
+ "Added package " + pInfo.name());
+ consistent = false;
+ }
+ }
+ return consistent;
+ }
+
+ public HashMap<String, PackageInfo> getPackages() {
+ return mPackages;
+ }
+
+ public void addPackage(PackageInfo pInfo) {
+ // track the set of organized packages in the API
+ mPackages.put(pInfo.name(), pInfo);
+
+ // accumulate a direct map of all the classes in the API
+ for (ClassInfo cl: pInfo.allClasses().values()) {
+ mAllClasses.put(cl.qualifiedName(), cl);
+ }
+ }
+
+ public void resolveSuperclasses() {
+ for (ClassInfo cl: mAllClasses.values()) {
+ // java.lang.Object has no superclass
+ if (!cl.qualifiedName().equals("java.lang.Object")) {
+ String scName = cl.superclassName();
+ if (scName == null) {
+ scName = "java.lang.Object";
+ }
+
+ ClassInfo superclass = mAllClasses.get(scName);
+ cl.setSuperClass(superclass);
+ }
+ }
+ }
+}
diff --git a/tools/apicheck/src/com/android/apicheck/ClassInfo.java b/tools/apicheck/src/com/android/apicheck/ClassInfo.java
new file mode 100644
index 0000000..4bbf78b
--- /dev/null
+++ b/tools/apicheck/src/com/android/apicheck/ClassInfo.java
@@ -0,0 +1,282 @@
+/*
+ * 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.
+ */
+
+package com.android.apicheck;
+import java.util.*;
+
+public class ClassInfo {
+ private String mName;
+ private String mSuperClassName;
+ private boolean mIsInterface;
+ private boolean mIsAbstract;
+ private boolean mIsStatic;
+ private boolean mIsFinal;
+ private String mDeprecated;
+ private String mScope;
+ private List<String> mInterfaces;
+ private HashMap<String, MethodInfo> mMethods;
+ private HashMap<String, FieldInfo> mFields;
+ private HashMap<String, ConstructorInfo> mConstructors;
+ private boolean mExistsInBoth;
+ private PackageInfo mPackage;
+ private SourcePositionInfo mSourcePosition;
+ private ClassInfo mSuperClass;
+ private ClassInfo mParentClass;
+
+ public ClassInfo(String name, PackageInfo pack, String superClass, boolean isInterface,
+ boolean isAbstract, boolean isStatic, boolean isFinal, String deprecated,
+ String visibility, SourcePositionInfo source, ClassInfo parent) {
+ mName = name;
+ mPackage = pack;
+ mSuperClassName = superClass;
+ mIsInterface = isInterface;
+ mIsAbstract = isAbstract;
+ mIsStatic = isStatic;
+ mIsFinal = isFinal;
+ mDeprecated = deprecated;
+ mScope = visibility;
+ mInterfaces = new ArrayList<String>();
+ mMethods = new HashMap<String, MethodInfo>();
+ mFields = new HashMap<String, FieldInfo>();
+ mConstructors = new HashMap<String, ConstructorInfo>();
+ mExistsInBoth = false;
+ mSourcePosition = source;
+ mParentClass = parent;
+ }
+
+ public String name() {
+ return mName;
+ }
+
+ public String qualifiedName() {
+ String parentQName = (mParentClass != null)
+ ? (mParentClass.qualifiedName() + ".")
+ : "";
+ return mPackage.name() + "." + parentQName + name();
+ }
+
+ public String superclassName() {
+ return mSuperClassName;
+ }
+
+ public SourcePositionInfo position() {
+ return mSourcePosition;
+ }
+
+ public boolean isInterface() {
+ return mIsInterface;
+ }
+
+ public boolean isFinal() {
+ return mIsFinal;
+ }
+
+ // Find a superclass implementation of the given method. Looking at our superclass
+ // instead of at 'this' is unusual, but it fits the point-of-call demands well.
+ public MethodInfo overriddenMethod(MethodInfo candidate) {
+ if (mSuperClass == null) {
+ return null;
+ }
+
+ // does our immediate superclass have it?
+ ClassInfo sup = mSuperClass;
+ for (MethodInfo mi : sup.mMethods.values()) {
+ if (mi.matches(candidate)) {
+ // found it
+ return mi;
+ }
+ }
+
+ // no, so recurse
+ if (sup.mSuperClass != null) {
+ return mSuperClass.overriddenMethod(candidate);
+ }
+
+ // no parent, so we just don't have it
+ return null;
+ }
+
+ public boolean isConsistent(ClassInfo cl) {
+ cl.mExistsInBoth = true;
+ mExistsInBoth = true;
+ boolean consistent = true;
+
+ if (isInterface() != cl.isInterface()) {
+ Errors.error(Errors.CHANGED_CLASS, cl.position(),
+ "Class " + cl.qualifiedName()
+ + " changed class/interface declaration");
+ consistent = false;
+ }
+ for (String iface : mInterfaces) {
+ if (!cl.mInterfaces.contains(iface)) {
+ Errors.error(Errors.REMOVED_INTERFACE, cl.position(),
+ "Class " + qualifiedName() + " no longer implements " + iface);
+ }
+ }
+ for (String iface : cl.mInterfaces) {
+ if (!mInterfaces.contains(iface)) {
+ Errors.error(Errors.ADDED_INTERFACE, cl.position(),
+ "Added interface " + iface + " to class "
+ + qualifiedName());
+ consistent = false;
+ }
+ }
+
+ for (MethodInfo mInfo : mMethods.values()) {
+ if (cl.mMethods.containsKey(mInfo.getHashableName())) {
+ if (!mInfo.isConsistent(cl.mMethods.get(mInfo.getHashableName()))) {
+ consistent = false;
+ }
+ } else {
+ /* This class formerly provided this method directly, and now does not.
+ * Check our ancestry to see if there's an inherited version that still
+ * fulfills the API requirement.
+ */
+ MethodInfo mi = mInfo.containingClass().overriddenMethod(mInfo);
+ if (mi == null) {
+ Errors.error(Errors.REMOVED_METHOD, mInfo.position(),
+ "Removed public method " + mInfo.qualifiedName());
+ consistent = false;
+ }
+ }
+ }
+ for (MethodInfo mInfo : cl.mMethods.values()) {
+ if (!mInfo.isInBoth()) {
+ /* Similarly to the above, do not fail if this "new" method is
+ * really an override of an existing superclass method.
+ */
+ MethodInfo mi = mInfo.containingClass().overriddenMethod(mInfo);
+ if (mi == null) {
+ Errors.error(Errors.ADDED_METHOD, mInfo.position(),
+ "Added public method " + mInfo.qualifiedName());
+ consistent = false;
+ }
+ }
+ }
+
+ for (ConstructorInfo mInfo : mConstructors.values()) {
+ if (cl.mConstructors.containsKey(mInfo.getHashableName())) {
+ if (!mInfo.isConsistent(cl.mConstructors.get(mInfo.getHashableName()))) {
+ consistent = false;
+ }
+ } else {
+ Errors.error(Errors.REMOVED_METHOD, mInfo.position(),
+ "Removed public constructor " + mInfo.prettySignature());
+ consistent = false;
+ }
+ }
+ for (ConstructorInfo mInfo : cl.mConstructors.values()) {
+ if (!mInfo.isInBoth()) {
+ Errors.error(Errors.ADDED_METHOD, mInfo.position(),
+ "Added public constructor " + mInfo.prettySignature());
+ consistent = false;
+ }
+ }
+
+ for (FieldInfo mInfo : mFields.values()) {
+ if (cl.mFields.containsKey(mInfo.qualifiedName())) {
+ if (!mInfo.isConsistent(cl.mFields.get(mInfo.qualifiedName()))) {
+ consistent = false;
+ }
+ } else {
+ Errors.error(Errors.REMOVED_FIELD, mInfo.position(),
+ "Removed field " + mInfo.qualifiedName());
+ consistent = false;
+ }
+ }
+ for (FieldInfo mInfo : cl.mFields.values()) {
+ if (!mInfo.isInBoth()) {
+ Errors.error(Errors.ADDED_FIELD, mInfo.position(),
+ "Added public field " + mInfo.qualifiedName());
+ consistent = false;
+ }
+ }
+
+ if (mIsAbstract != cl.mIsAbstract) {
+ consistent = false;
+ Errors.error(Errors.CHANGED_ABSTRACT, cl.position(),
+ "Class " + cl.qualifiedName() + " changed abstract qualifier");
+ }
+
+ if (mIsFinal != cl.mIsFinal) {
+ consistent = false;
+ Errors.error(Errors.CHANGED_FINAL, cl.position(),
+ "Class " + cl.qualifiedName() + " changed final qualifier");
+ }
+
+ if (mIsStatic != cl.mIsStatic) {
+ consistent = false;
+ Errors.error(Errors.CHANGED_STATIC, cl.position(),
+ "Class " + cl.qualifiedName() + " changed static qualifier");
+ }
+
+ if (!mScope.equals(cl.mScope)) {
+ consistent = false;
+ Errors.error(Errors.CHANGED_SCOPE, cl.position(),
+ "Class " + cl.qualifiedName() + " scope changed from "
+ + mScope + " to " + cl.mScope);
+ }
+
+ if (!mDeprecated.equals(cl.mDeprecated)) {
+ consistent = false;
+ Errors.error(Errors.CHANGED_DEPRECATED, cl.position(),
+ "Class " + cl.qualifiedName() + " has changed deprecation state");
+ }
+
+ if (mSuperClassName != null) {
+ if (cl.mSuperClassName == null || !mSuperClassName.equals(cl.mSuperClassName)) {
+ consistent = false;
+ Errors.error(Errors.CHANGED_SUPERCLASS, cl.position(),
+ "Class " + qualifiedName() + " superclass changed from "
+ + mSuperClassName + " to " + cl.mSuperClassName);
+ }
+ } else if (cl.mSuperClassName != null) {
+ consistent = false;
+ Errors.error(Errors.CHANGED_SUPERCLASS, cl.position(),
+ "Class " + qualifiedName() + " superclass changed from "
+ + "null to " + cl.mSuperClassName);
+ }
+
+ return consistent;
+ }
+
+ public void addInterface(String name) {
+ mInterfaces.add(name);
+ }
+
+ public void addMethod(MethodInfo mInfo) {
+ mMethods.put(mInfo.getHashableName(), mInfo);
+ }
+
+ public void addConstructor(ConstructorInfo cInfo) {
+ mConstructors.put(cInfo.getHashableName(), cInfo);
+
+ }
+
+ public void addField(FieldInfo fInfo) {
+ mFields.put(fInfo.qualifiedName(), fInfo);
+
+ }
+
+ public void setSuperClass(ClassInfo superclass) {
+ mSuperClass = superclass;
+ }
+
+ public boolean isInBoth() {
+ return mExistsInBoth;
+ }
+
+}
diff --git a/tools/apicheck/src/com/android/apicheck/ConstructorInfo.java b/tools/apicheck/src/com/android/apicheck/ConstructorInfo.java
new file mode 100644
index 0000000..57d7617
--- /dev/null
+++ b/tools/apicheck/src/com/android/apicheck/ConstructorInfo.java
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+package com.android.apicheck;
+import java.util.*;
+
+public class ConstructorInfo implements AbstractMethodInfo {
+
+ private String mName;
+ private String mType;
+ private boolean mIsStatic;
+ private boolean mIsFinal;
+ private String mDeprecated;
+ private String mScope;
+ private List<String> mExceptions;
+ private List<ParameterInfo> mParameters;
+ private boolean mExistsInBoth;
+ private SourcePositionInfo mSourcePosition;
+ private ClassInfo mClass;
+
+ public ConstructorInfo(String name, String type, boolean isStatic, boolean isFinal,
+ String deprecated, String scope, SourcePositionInfo pos, ClassInfo clazz) {
+ mName = name;
+ mType = type;
+ mIsStatic = isStatic;
+ mIsFinal = isFinal;
+ mDeprecated= deprecated;
+ mScope = scope;
+ mExistsInBoth = false;
+ mExceptions = new ArrayList<String>();
+ mParameters = new ArrayList<ParameterInfo>();
+ mSourcePosition = pos;
+ mClass = clazz;
+ }
+
+ public void addParameter(ParameterInfo pInfo) {
+ mParameters.add(pInfo);
+ }
+
+ public void addException(String exec) {
+ mExceptions.add(exec);
+ }
+
+ public String getHashableName() {
+ String returnString = qualifiedName();
+ for (ParameterInfo pInfo : mParameters) {
+ returnString += ":" + pInfo.getType();
+ }
+ return returnString;
+ }
+
+ public boolean isInBoth() {
+ return mExistsInBoth;
+ }
+
+ public SourcePositionInfo position() {
+ return mSourcePosition;
+ }
+
+ public String name() {
+ return mName;
+ }
+
+ public String qualifiedName() {
+ String baseName = (mClass != null)
+ ? (mClass.qualifiedName() + ".")
+ : "";
+ return baseName + name();
+ }
+
+ public String prettySignature() {
+ String params = "";
+ for (ParameterInfo pInfo : mParameters) {
+ if (params.length() > 0) {
+ params += ", ";
+ }
+ params += pInfo.getType();
+ }
+ return qualifiedName() + '(' + params + ')';
+ }
+
+ public boolean isConsistent(ConstructorInfo mInfo) {
+ mInfo.mExistsInBoth = true;
+ mExistsInBoth = true;
+ boolean consistent = true;
+
+ if (mIsFinal != mInfo.mIsFinal) {
+ consistent = false;
+ Errors.error(Errors.CHANGED_FINAL, mInfo.position(),
+ "Constructor " + mInfo.qualifiedName() + " has changed 'final' qualifier");
+ }
+
+ if (mIsStatic != mInfo.mIsStatic) {
+ consistent = false;
+ Errors.error(Errors.CHANGED_FINAL, mInfo.position(),
+ "Constructor " + mInfo.qualifiedName() + " has changed 'static' qualifier");
+ }
+
+ if (!mScope.equals(mInfo.mScope)) {
+ consistent = false;
+ Errors.error(Errors.CHANGED_SCOPE, mInfo.position(),
+ "Constructor " + mInfo.qualifiedName() + " changed scope from "
+ + mScope + " to " + mInfo.mScope);
+ }
+
+ if (!mDeprecated.equals(mInfo.mDeprecated)) {
+ consistent = false;
+ Errors.error(Errors.CHANGED_DEPRECATED, mInfo.position(),
+ "Constructor " + mInfo.qualifiedName() + " has changed deprecation state");
+ }
+
+ for (String exec : mExceptions) {
+ if (!mInfo.mExceptions.contains(exec)) {
+ Errors.error(Errors.CHANGED_THROWS, mInfo.position(),
+ "Constructor " + mInfo.qualifiedName() + " no longer throws exception "
+ + exec);
+ consistent = false;
+ }
+ }
+
+ for (String exec : mInfo.mExceptions) {
+ if (!mExceptions.contains(exec)) {
+ Errors.error(Errors.CHANGED_THROWS, mInfo.position(),
+ "Constructor " + mInfo.qualifiedName() + " added thrown exception "
+ + exec);
+ consistent = false;
+ }
+ }
+
+ return consistent;
+ }
+
+
+}
diff --git a/tools/apicheck/src/com/android/apicheck/Errors.java b/tools/apicheck/src/com/android/apicheck/Errors.java
new file mode 100644
index 0000000..d7013e3
--- /dev/null
+++ b/tools/apicheck/src/com/android/apicheck/Errors.java
@@ -0,0 +1,156 @@
+/*
+ * 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.
+ */
+
+package com.android.apicheck;
+
+import java.lang.Comparable;
+import java.util.TreeSet;
+
+public class Errors
+{
+ public static boolean hadError = false;
+ private static boolean warningsAreErrors = false;
+ private static TreeSet<Message> allErrors = new TreeSet<Message>();
+
+ private static class Message implements Comparable {
+ SourcePositionInfo pos;
+ String msg;
+
+ Message(SourcePositionInfo p, String m) {
+ pos = p;
+ msg = m;
+ }
+
+ public int compareTo(Object o) {
+ Message that = (Message)o;
+ int r = this.pos.compareTo(that.pos);
+ if (r != 0) return r;
+ return this.msg.compareTo(that.msg);
+ }
+
+ public String toString() {
+ return this.pos.toString() + this.msg;
+ }
+ }
+
+ public static void error(Error error, SourcePositionInfo where, String text) {
+ if (error.level == HIDDEN) {
+ return;
+ }
+
+ String which = (!warningsAreErrors && error.level == WARNING) ? " warning " : " error ";
+ String message = which + error.code + ": " + text;
+
+ if (where == null) {
+ where = new SourcePositionInfo("unknown", 0, 0);
+ }
+
+ allErrors.add(new Message(where, message));
+
+ if (error.level == ERROR || (warningsAreErrors && error.level == WARNING)) {
+ hadError = true;
+ }
+ }
+
+ public static void printErrors() {
+ for (Message m: allErrors) {
+ System.err.println(m.toString());
+ }
+ }
+
+ public static int HIDDEN = 0;
+ public static int WARNING = 1;
+ public static int ERROR = 2;
+
+ public static void setWarningsAreErrors(boolean val) {
+ warningsAreErrors = val;
+ }
+
+ public static class Error {
+ public int code;
+ public int level;
+
+ public Error(int code, int level)
+ {
+ this.code = code;
+ this.level = level;
+ }
+ }
+
+ public static Error PARSE_ERROR = new Error(1, ERROR);
+ public static Error ADDED_PACKAGE = new Error(2, WARNING);
+ public static Error ADDED_CLASS = new Error(3, WARNING);
+ public static Error ADDED_METHOD = new Error(4, WARNING);
+ public static Error ADDED_FIELD = new Error(5, WARNING);
+ public static Error ADDED_INTERFACE = new Error(6, WARNING);
+ public static Error REMOVED_PACKAGE = new Error(7, WARNING);
+ public static Error REMOVED_CLASS = new Error(8, WARNING);
+ public static Error REMOVED_METHOD = new Error(9, WARNING);
+ public static Error REMOVED_FIELD = new Error(10, WARNING);
+ public static Error REMOVED_INTERFACE = new Error(11, WARNING);
+ public static Error CHANGED_STATIC = new Error(12, WARNING);
+ public static Error CHANGED_FINAL = new Error(13, WARNING);
+ public static Error CHANGED_TRANSIENT = new Error(14, WARNING);
+ public static Error CHANGED_VOLATILE = new Error(15, WARNING);
+ public static Error CHANGED_TYPE = new Error(16, WARNING);
+ public static Error CHANGED_VALUE = new Error(17, WARNING);
+ public static Error CHANGED_SUPERCLASS = new Error(18, WARNING);
+ public static Error CHANGED_SCOPE = new Error(19, WARNING);
+ public static Error CHANGED_ABSTRACT = new Error(20, WARNING);
+ public static Error CHANGED_THROWS = new Error(21, WARNING);
+ public static Error CHANGED_NATIVE = new Error(22, HIDDEN);
+ public static Error CHANGED_CLASS = new Error(23, WARNING);
+ public static Error CHANGED_DEPRECATED = new Error(24, WARNING);
+ public static Error CHANGED_SYNCHRONIZED = new Error(25, ERROR);
+
+ public static Error[] ERRORS = {
+ PARSE_ERROR,
+ ADDED_PACKAGE,
+ ADDED_CLASS,
+ ADDED_METHOD,
+ ADDED_FIELD,
+ ADDED_INTERFACE,
+ REMOVED_PACKAGE,
+ REMOVED_CLASS,
+ REMOVED_METHOD,
+ REMOVED_FIELD,
+ REMOVED_INTERFACE,
+ CHANGED_STATIC,
+ CHANGED_FINAL,
+ CHANGED_TRANSIENT,
+ CHANGED_VOLATILE,
+ CHANGED_TYPE,
+ CHANGED_VALUE,
+ CHANGED_SUPERCLASS,
+ CHANGED_SCOPE,
+ CHANGED_ABSTRACT,
+ CHANGED_THROWS,
+ CHANGED_NATIVE,
+ CHANGED_CLASS,
+ CHANGED_DEPRECATED,
+ CHANGED_SYNCHRONIZED,
+ };
+
+ public static boolean setErrorLevel(int code, int level) {
+ for (Error e: ERRORS) {
+ if (e.code == code) {
+ e.level = level;
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/tools/apicheck/src/com/android/apicheck/FieldInfo.java b/tools/apicheck/src/com/android/apicheck/FieldInfo.java
new file mode 100644
index 0000000..d80d9f6
--- /dev/null
+++ b/tools/apicheck/src/com/android/apicheck/FieldInfo.java
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+package com.android.apicheck;
+
+public class FieldInfo {
+
+ private String mName;
+ private String mType;
+ private boolean mIsTransient;
+ private boolean mIsVolatile;
+ private String mValue;
+ private boolean mIsStatic;
+ private boolean mIsFinal;
+ private String mDeprecated;
+ private String mScope;
+ private boolean mExistsInBoth;
+ private SourcePositionInfo mSourcePosition;
+ private ClassInfo mClass;
+
+ public FieldInfo (String name, String type, boolean isTransient, boolean isVolatile,
+ String value, boolean isStatic, boolean isFinal, String deprecated,
+ String scope, SourcePositionInfo source, ClassInfo parent) {
+ mName = name;
+ mType = type;
+ mIsTransient = isTransient;
+ mIsVolatile = isVolatile;
+ mValue = value;
+ mIsStatic = isStatic;
+ mIsFinal = isFinal;
+ mDeprecated = deprecated;
+ mScope = scope;
+ mExistsInBoth = false;
+ mSourcePosition = source;
+ mClass = parent;
+ }
+
+ public boolean isInBoth() {
+ return mExistsInBoth;
+ }
+ public SourcePositionInfo position() {
+ return mSourcePosition;
+ }
+
+ public String name() {
+ return mName;
+ }
+
+ public String qualifiedName() {
+ String parentQName = (mClass != null)
+ ? (mClass.qualifiedName() + ".")
+ : "";
+ return parentQName + name();
+ }
+
+ // Check the declared value with a typed comparison, not a string comparison,
+ // to accommodate toolchains with different fp -> string conversions.
+ public boolean valueEquals(FieldInfo other) {
+ // Type mismatch means nonequal, as does a null/non-null mismatch
+ if (!mType.equals(other.mType)
+ || ((mValue == null) != (other.mValue == null))) {
+ return false;
+ }
+
+ // Null values are considered equal
+ if (mValue == null) {
+ return true;
+ }
+
+ // Floating point gets an implementation-type comparison; all others just use the string
+ // If float/double parse fails, fall back to string comparison -- it means that it's a
+ // canonical droiddoc-generated constant expression that represents a NaN.
+ try {
+ if (mType.equals("float")) {
+ float val = Float.parseFloat(mValue);
+ float otherVal = Float.parseFloat(other.mValue);
+ return (val == otherVal);
+ } else if (mType.equals("double")) {
+ double val = Double.parseDouble(mValue);
+ double otherVal = Double.parseDouble(other.mValue);
+ return (val == otherVal);
+ }
+ } catch (NumberFormatException e) {
+ // fall through
+ }
+
+ return mValue.equals(other.mValue);
+ }
+
+ public boolean isConsistent(FieldInfo fInfo) {
+ fInfo.mExistsInBoth = true;
+ mExistsInBoth = true;
+ boolean consistent = true;
+ if (!mType.equals(fInfo.mType)) {
+ Errors.error(Errors.CHANGED_TYPE, fInfo.position(),
+ "Field " + fInfo.qualifiedName() + " has changed type");
+ consistent = false;
+ }
+
+ if (!this.valueEquals(fInfo)) {
+ Errors.error(Errors.CHANGED_VALUE, fInfo.position(),
+ "Field " + fInfo.qualifiedName() + " has changed value from "
+ + mValue + " to " + fInfo.mValue);
+ consistent = false;
+ }
+
+ if (!mScope.equals(fInfo.mScope)) {
+ Errors.error(Errors.CHANGED_SCOPE, fInfo.position(),
+ "Method " + fInfo.qualifiedName() + " changed scope from "
+ + mScope + " to " + fInfo.mScope);
+ consistent = false;
+ }
+
+ if (mIsStatic != fInfo.mIsStatic) {
+ Errors.error(Errors.CHANGED_STATIC, fInfo.position(),
+ "Field " + fInfo.qualifiedName() + " has changed 'static' qualifier");
+ consistent = false;
+ }
+
+ if (mIsFinal != fInfo.mIsFinal) {
+ Errors.error(Errors.CHANGED_FINAL, fInfo.position(),
+ "Field " + fInfo.qualifiedName() + " has changed 'final' qualifier");
+ consistent = false;
+ }
+
+ if (mIsTransient != fInfo.mIsTransient) {
+ Errors.error(Errors.CHANGED_TRANSIENT, fInfo.position(),
+ "Field " + fInfo.qualifiedName() + " has changed 'transient' qualifier");
+ consistent = false;
+ }
+
+ if (mIsVolatile != fInfo.mIsVolatile) {
+ Errors.error(Errors.CHANGED_VOLATILE, fInfo.position(),
+ "Field " + fInfo.qualifiedName() + " has changed 'volatile' qualifier");
+ consistent = false;
+ }
+
+ if (!mDeprecated.equals(fInfo.mDeprecated)) {
+ Errors.error(Errors.CHANGED_DEPRECATED, fInfo.position(),
+ "Field " + fInfo.qualifiedName() + " has changed deprecation state");
+ consistent = false;
+ }
+
+ return consistent;
+ }
+
+}
diff --git a/tools/apicheck/src/com/android/apicheck/MethodInfo.java b/tools/apicheck/src/com/android/apicheck/MethodInfo.java
new file mode 100644
index 0000000..86e20de
--- /dev/null
+++ b/tools/apicheck/src/com/android/apicheck/MethodInfo.java
@@ -0,0 +1,209 @@
+/*
+ * 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.
+ */
+
+package com.android.apicheck;
+import java.util.*;
+
+public class MethodInfo implements AbstractMethodInfo {
+
+ private String mName;
+ private String mReturn;
+ private boolean mIsAbstract;
+ private boolean mIsNative;
+ private boolean mIsSynchronized;
+ private boolean mIsStatic;
+ private boolean mIsFinal;
+ private String mDeprecated;
+ private String mScope;
+ private boolean mExistsInBoth;
+ private List<ParameterInfo> mParameters;
+ private List<String> mExceptions;
+ private SourcePositionInfo mSourcePosition;
+ private ClassInfo mClass;
+
+ public MethodInfo (String name, String returnType, boolean isAbstract, boolean isNative,
+ boolean isSynchronized, boolean isStatic, boolean isFinal, String deprecated
+ , String scope, SourcePositionInfo source, ClassInfo parent) {
+
+ mName = name;
+ mReturn = returnType;
+ mIsAbstract = isAbstract;
+ mIsNative = isNative;
+ mIsSynchronized = isSynchronized;
+ mIsStatic = isStatic;
+ mIsFinal = isFinal;
+ mDeprecated = deprecated;
+ mScope = scope;
+ mParameters = new ArrayList<ParameterInfo>();
+ mExceptions = new ArrayList<String>();
+ mExistsInBoth = false;
+ mSourcePosition = source;
+ mClass = parent;
+ }
+
+
+ public String name() {
+ return mName;
+ }
+
+ public String qualifiedName() {
+ String parentQName = (mClass != null)
+ ? (mClass.qualifiedName() + ".")
+ : "";
+ return parentQName + name();
+ }
+
+ public String prettySignature() {
+ String params = "";
+ for (ParameterInfo pInfo : mParameters) {
+ if (params.length() > 0) {
+ params += ", ";
+ }
+ params += pInfo.getType();
+ }
+ return qualifiedName() + '(' + params + ')';
+ }
+
+ public SourcePositionInfo position() {
+ return mSourcePosition;
+ }
+
+ public ClassInfo containingClass() {
+ return mClass;
+ }
+
+ public boolean matches(MethodInfo other) {
+ return getSignature().equals(other.getSignature());
+ }
+
+ public boolean isConsistent(MethodInfo mInfo) {
+ mInfo.mExistsInBoth = true;
+ mExistsInBoth = true;
+ boolean consistent = true;
+ if (!mReturn.equals(mInfo.mReturn)) {
+ consistent = false;
+ Errors.error(Errors.CHANGED_TYPE, mInfo.position(),
+ "Method " + mInfo.qualifiedName() + " has changed return type from "
+ + mReturn + " to " + mInfo.mReturn);
+ }
+
+ if (mIsAbstract != mInfo.mIsAbstract) {
+ consistent = false;
+ Errors.error(Errors.CHANGED_ABSTRACT, mInfo.position(),
+ "Method " + mInfo.qualifiedName() + " has changed 'abstract' qualifier");
+ }
+
+ if (mIsNative != mInfo.mIsNative) {
+ consistent = false;
+ Errors.error(Errors.CHANGED_NATIVE, mInfo.position(),
+ "Method " + mInfo.qualifiedName() + " has changed 'native' qualifier");
+ }
+
+ if (mIsFinal != mInfo.mIsFinal) {
+ // Compiler-generated methods vary in their 'final' qual between versions of
+ // the compiler, so this check needs to be quite narrow. A change in 'final'
+ // status of a method is only relevant if (a) the method is not declared 'static'
+ // and (b) the method's class is not itself 'final'.
+ if (!mIsStatic) {
+ if ((mClass == null) || (!mClass.isFinal())) {
+ consistent = false;
+ Errors.error(Errors.CHANGED_FINAL, mInfo.position(),
+ "Method " + mInfo.qualifiedName() + " has changed 'final' qualifier");
+ }
+ }
+ }
+
+ if (mIsStatic != mInfo.mIsStatic) {
+ consistent = false;
+ Errors.error(Errors.CHANGED_STATIC, mInfo.position(),
+ "Method " + mInfo.qualifiedName() + " has changed 'static' qualifier");
+ }
+
+ if (!mScope.equals(mInfo.mScope)) {
+ consistent = false;
+ Errors.error(Errors.CHANGED_SCOPE, mInfo.position(),
+ "Method " + mInfo.qualifiedName() + " changed scope from "
+ + mScope + " to " + mInfo.mScope);
+ }
+
+ if (!mDeprecated.equals(mInfo.mDeprecated)) {
+ Errors.error(Errors.CHANGED_DEPRECATED, mInfo.position(),
+ "Method " + mInfo.qualifiedName() + " has changed deprecation state");
+ consistent = false;
+ }
+
+ if (mIsSynchronized != mInfo.mIsSynchronized) {
+ Errors.error(Errors.CHANGED_SYNCHRONIZED, mInfo.position(),
+ "Method " + mInfo.qualifiedName() + " has changed 'synchronized' qualifier from " + mIsSynchronized + " to " + mInfo.mIsSynchronized);
+ consistent = false;
+ }
+
+ for (String exec : mExceptions) {
+ if (!mInfo.mExceptions.contains(exec)) {
+ // exclude 'throws' changes to finalize() overrides with no arguments
+ if (!name().equals("finalize") || (mParameters.size() > 0)) {
+ Errors.error(Errors.CHANGED_THROWS, mInfo.position(),
+ "Method " + mInfo.qualifiedName() + " no longer throws exception "
+ + exec);
+ consistent = false;
+ }
+ }
+ }
+
+ for (String exec : mInfo.mExceptions) {
+ // exclude 'throws' changes to finalize() overrides with no arguments
+ if (!mExceptions.contains(exec)) {
+ if (!name().equals("finalize") || (mParameters.size() > 0)) {
+ Errors.error(Errors.CHANGED_THROWS, mInfo.position(),
+ "Method " + mInfo.qualifiedName() + " added thrown exception "
+ + exec);
+ consistent = false;
+ }
+ }
+ }
+
+ return consistent;
+ }
+
+ public void addParameter(ParameterInfo pInfo) {
+ mParameters.add(pInfo);
+ }
+
+ public void addException(String exc) {
+ mExceptions.add(exc);
+ }
+
+ public String getParameterHash() {
+ String hash = "";
+ for (ParameterInfo pInfo : mParameters) {
+ hash += ":" + pInfo.getType();
+ }
+ return hash;
+ }
+
+ public String getHashableName() {
+ return qualifiedName() + getParameterHash();
+ }
+
+ public String getSignature() {
+ return name() + getParameterHash();
+ }
+
+ public boolean isInBoth() {
+ return mExistsInBoth;
+ }
+
+}
diff --git a/tools/apicheck/src/com/android/apicheck/PackageInfo.java b/tools/apicheck/src/com/android/apicheck/PackageInfo.java
new file mode 100644
index 0000000..2262f21
--- /dev/null
+++ b/tools/apicheck/src/com/android/apicheck/PackageInfo.java
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+package com.android.apicheck;
+import java.util.*;
+
+public class PackageInfo {
+ private String mName;
+ private HashMap<String, ClassInfo> mClasses;
+ private boolean mExistsInBoth;
+ private SourcePositionInfo mPosition;
+
+ public PackageInfo(String name, SourcePositionInfo position) {
+ mName = name;
+ mClasses = new HashMap<String, ClassInfo>();
+ mExistsInBoth = false;
+ mPosition = position;
+ }
+
+ public void addClass(ClassInfo cl) {
+ mClasses.put(cl.name() , cl);
+ }
+
+ public HashMap<String, ClassInfo> allClasses() {
+ return mClasses;
+ }
+
+ public String name() {
+ return mName;
+ }
+
+ public SourcePositionInfo position() {
+ return mPosition;
+ }
+
+ public boolean isConsistent(PackageInfo pInfo) {
+ mExistsInBoth = true;
+ pInfo.mExistsInBoth = true;
+ boolean consistent = true;
+ for (ClassInfo cInfo : mClasses.values()) {
+ if (pInfo.mClasses.containsKey(cInfo.name())) {
+ if (!cInfo.isConsistent(pInfo.mClasses.get(cInfo.name()))) {
+ consistent = false;
+ }
+ } else {
+ Errors.error(Errors.REMOVED_CLASS, cInfo.position(),
+ "Removed public class " + cInfo.qualifiedName());
+ consistent = false;
+ }
+ }
+ for (ClassInfo cInfo : pInfo.mClasses.values()) {
+ if (!cInfo.isInBoth()) {
+ Errors.error(Errors.ADDED_CLASS, cInfo.position(),
+ "Added class " + cInfo.name() + " to package "
+ + pInfo.name());
+ consistent = false;
+ }
+ }
+ return consistent;
+ }
+
+ public boolean isInBoth() {
+ return mExistsInBoth;
+ }
+}
diff --git a/tools/apicheck/src/com/android/apicheck/ParameterInfo.java b/tools/apicheck/src/com/android/apicheck/ParameterInfo.java
new file mode 100644
index 0000000..5788814
--- /dev/null
+++ b/tools/apicheck/src/com/android/apicheck/ParameterInfo.java
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+package com.android.apicheck;
+
+public class ParameterInfo {
+ private String mType;
+ private String mName;
+
+ public ParameterInfo(String type, String name) {
+ mType = type;
+ mName = name;
+ }
+
+ public String getType() {
+ return mType;
+ }
+
+ public String getName() {
+ return mName;
+ }
+}
diff --git a/tools/apicheck/src/com/android/apicheck/SourcePositionInfo.java b/tools/apicheck/src/com/android/apicheck/SourcePositionInfo.java
new file mode 100644
index 0000000..477c1d3
--- /dev/null
+++ b/tools/apicheck/src/com/android/apicheck/SourcePositionInfo.java
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+package com.android.apicheck;
+
+import java.lang.Comparable;
+
+public class SourcePositionInfo implements Comparable
+{
+ public SourcePositionInfo() {
+ this.file = "<unknown>";
+ this.line = 0;
+ this.column = 0;
+ }
+
+ public SourcePositionInfo(String file, int line, int column)
+ {
+ this.file = file;
+ this.line = line;
+ this.column = column;
+ }
+
+ public SourcePositionInfo(SourcePositionInfo that)
+ {
+ this.file = that.file;
+ this.line = that.line;
+ this.column = that.column;
+ }
+
+ /**
+ * Given this position and str which occurs at that position, as well as str an index into str,
+ * find the SourcePositionInfo.
+ *
+ * @throw StringIndexOutOfBoundsException if index > str.length()
+ */
+ public static SourcePositionInfo add(SourcePositionInfo that, String str, int index)
+ {
+ if (that == null) {
+ return null;
+ }
+ int line = that.line;
+ char prev = 0;
+ for (int i=0; i<index; i++) {
+ char c = str.charAt(i);
+ if (c == '\r' || (c == '\n' && prev != '\r')) {
+ line++;
+ }
+ prev = c;
+ }
+ return new SourcePositionInfo(that.file, line, 0);
+ }
+
+ public static SourcePositionInfo findBeginning(SourcePositionInfo that, String str)
+ {
+ if (that == null) {
+ return null;
+ }
+ int line = that.line-1; // -1 because, well, it seems to work
+ int prev = 0;
+ for (int i=str.length()-1; i>=0; i--) {
+ char c = str.charAt(i);
+ if ((c == '\r' && prev != '\n') || (c == '\n')) {
+ line--;
+ }
+ prev = c;
+ }
+ return new SourcePositionInfo(that.file, line, 0);
+ }
+
+ public String toString()
+ {
+ if (this.file == null) {
+ return "(unknown)";
+ } else {
+ if (this.line == 0) {
+ return this.file + ':';
+ } else {
+ return this.file + ':' + this.line + ':';
+ }
+ }
+ }
+
+ public int compareTo(Object o) {
+ SourcePositionInfo that = (SourcePositionInfo)o;
+ int r = this.file.compareTo(that.file);
+ if (r != 0) return r;
+ return this.line - that.line;
+ }
+
+ /**
+ * Build a SourcePositionInfo from the XML source= notation
+ */
+ public static SourcePositionInfo fromXml(String source) {
+ if (source != null) {
+ for (int i = 0; i < source.length(); i++) {
+ if (source.charAt(i) == ':') {
+ return new SourcePositionInfo(source.substring(0, i),
+ Integer.parseInt(source.substring(i+1)), 0);
+ }
+ }
+ }
+
+ return new SourcePositionInfo("(unknown)", 0, 0);
+ }
+
+ public String file;
+ public int line;
+ public int column;
+}
diff --git a/tools/applypatch/Android.mk b/tools/applypatch/Android.mk
new file mode 100644
index 0000000..09f9862
--- /dev/null
+++ b/tools/applypatch/Android.mk
@@ -0,0 +1,29 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+LOCAL_SRC_FILES := applypatch.c bsdiff.c freecache.c
+LOCAL_MODULE := applypatch
+LOCAL_FORCE_STATIC_EXECUTABLE := true
+LOCAL_MODULE_TAGS := eng
+LOCAL_C_INCLUDES += external/bzip2
+LOCAL_STATIC_LIBRARIES += libmincrypt libbz libc
+
+include $(BUILD_EXECUTABLE)
+
+endif # !TARGET_SIMULATOR
diff --git a/tools/applypatch/applypatch.c b/tools/applypatch/applypatch.c
new file mode 100644
index 0000000..9954869
--- /dev/null
+++ b/tools/applypatch/applypatch.c
@@ -0,0 +1,457 @@
+/*
+ * 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.
+ */
+
+#include <errno.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <unistd.h>
+
+#include "mincrypt/sha.h"
+#include "applypatch.h"
+
+// Read a file into memory; store it and its associated metadata in
+// *file. Return 0 on success.
+int LoadFileContents(const char* filename, FileContents* file) {
+ file->data = NULL;
+
+ if (stat(filename, &file->st) != 0) {
+ fprintf(stderr, "failed to stat \"%s\": %s\n", filename, strerror(errno));
+ return -1;
+ }
+
+ file->size = file->st.st_size;
+ file->data = malloc(file->size);
+
+ FILE* f = fopen(filename, "rb");
+ if (f == NULL) {
+ fprintf(stderr, "failed to open \"%s\": %s\n", filename, strerror(errno));
+ free(file->data);
+ return -1;
+ }
+
+ size_t bytes_read = fread(file->data, 1, file->size, f);
+ if (bytes_read != file->size) {
+ fprintf(stderr, "short read of \"%s\" (%d bytes of %d)\n",
+ filename, bytes_read, file->size);
+ free(file->data);
+ return -1;
+ }
+ fclose(f);
+
+ SHA(file->data, file->size, file->sha1);
+ return 0;
+}
+
+// Save the contents of the given FileContents object under the given
+// filename. Return 0 on success.
+int SaveFileContents(const char* filename, FileContents file) {
+ FILE* f = fopen(filename, "wb");
+ if (f == NULL) {
+ fprintf(stderr, "failed to open \"%s\" for write: %s\n",
+ filename, strerror(errno));
+ return -1;
+ }
+
+ size_t bytes_written = fwrite(file.data, 1, file.size, f);
+ if (bytes_written != file.size) {
+ fprintf(stderr, "short write of \"%s\" (%d bytes of %d)\n",
+ filename, bytes_written, file.size);
+ return -1;
+ }
+ fflush(f);
+ fsync(fileno(f));
+ fclose(f);
+
+ if (chmod(filename, file.st.st_mode) != 0) {
+ fprintf(stderr, "chmod of \"%s\" failed: %s\n", filename, strerror(errno));
+ return -1;
+ }
+ if (chown(filename, file.st.st_uid, file.st.st_gid) != 0) {
+ fprintf(stderr, "chown of \"%s\" failed: %s\n", filename, strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+// Take a string 'str' of 40 hex digits and parse it into the 20
+// byte array 'digest'. 'str' may contain only the digest or be of
+// the form "<digest>:<anything>". Return 0 on success, -1 on any
+// error.
+int ParseSha1(const char* str, uint8_t* digest) {
+ int i;
+ const char* ps = str;
+ uint8_t* pd = digest;
+ for (i = 0; i < SHA_DIGEST_SIZE * 2; ++i, ++ps) {
+ int digit;
+ if (*ps >= '0' && *ps <= '9') {
+ digit = *ps - '0';
+ } else if (*ps >= 'a' && *ps <= 'f') {
+ digit = *ps - 'a' + 10;
+ } else if (*ps >= 'A' && *ps <= 'F') {
+ digit = *ps - 'A' + 10;
+ } else {
+ return -1;
+ }
+ if (i % 2 == 0) {
+ *pd = digit << 4;
+ } else {
+ *pd |= digit;
+ ++pd;
+ }
+ }
+ if (*ps != '\0' && *ps != ':') return -1;
+ return 0;
+}
+
+// Parse arguments (which should be of the form "<sha1>" or
+// "<sha1>:<filename>" into the array *patches, returning the number
+// of Patch objects in *num_patches. Return 0 on success.
+int ParseShaArgs(int argc, char** argv, Patch** patches, int* num_patches) {
+ *num_patches = argc;
+ *patches = malloc(*num_patches * sizeof(Patch));
+
+ int i;
+ for (i = 0; i < *num_patches; ++i) {
+ if (ParseSha1(argv[i], (*patches)[i].sha1) != 0) {
+ fprintf(stderr, "failed to parse sha1 \"%s\"\n", argv[i]);
+ return -1;
+ }
+ if (argv[i][SHA_DIGEST_SIZE*2] == '\0') {
+ (*patches)[i].patch_filename = NULL;
+ } else if (argv[i][SHA_DIGEST_SIZE*2] == ':') {
+ (*patches)[i].patch_filename = argv[i] + (SHA_DIGEST_SIZE*2+1);
+ } else {
+ fprintf(stderr, "failed to parse filename \"%s\"\n", argv[i]);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+// Search an array of Patch objects for one matching the given sha1.
+// Return the Patch object on success, or NULL if no match is found.
+const Patch* FindMatchingPatch(uint8_t* sha1, Patch* patches, int num_patches) {
+ int i;
+ for (i = 0; i < num_patches; ++i) {
+ if (memcmp(patches[i].sha1, sha1, SHA_DIGEST_SIZE) == 0) {
+ return patches+i;
+ }
+ }
+ return NULL;
+}
+
+// Returns 0 if the contents of the file (argv[2]) or the cached file
+// match any of the sha1's on the command line (argv[3:]). Returns
+// nonzero otherwise.
+int CheckMode(int argc, char** argv) {
+ if (argc < 3) {
+ fprintf(stderr, "no filename given\n");
+ return 2;
+ }
+
+ int num_patches;
+ Patch* patches;
+ if (ParseShaArgs(argc-3, argv+3, &patches, &num_patches) != 0) { return 1; }
+
+ FileContents file;
+ file.data = NULL;
+
+ if (LoadFileContents(argv[2], &file) != 0 ||
+ FindMatchingPatch(file.sha1, patches, num_patches) == NULL) {
+ fprintf(stderr, "file \"%s\" doesn't have any of expected "
+ "sha1 sums; checking cache\n", argv[2]);
+
+ free(file.data);
+
+ // If the source file is missing or corrupted, it might be because
+ // we were killed in the middle of patching it. A copy of it
+ // should have been made in CACHE_TEMP_SOURCE. If that file
+ // exists and matches the sha1 we're looking for, the check still
+ // passes.
+
+ if (LoadFileContents(CACHE_TEMP_SOURCE, &file) != 0) {
+ fprintf(stderr, "failed to load cache file\n");
+ return 1;
+ }
+
+ if (FindMatchingPatch(file.sha1, patches, num_patches) == NULL) {
+ fprintf(stderr, "cache bits don't match any sha1 for \"%s\"\n",
+ argv[2]);
+ return 1;
+ }
+ }
+
+ free(file.data);
+ return 0;
+}
+
+int ShowLicenses() {
+ ShowBSDiffLicense();
+ return 0;
+}
+
+// Return the amount of free space (in bytes) on the filesystem
+// containing filename. filename must exist. Return -1 on error.
+size_t FreeSpaceForFile(const char* filename) {
+ struct statfs sf;
+ if (statfs(filename, &sf) != 0) {
+ fprintf(stderr, "failed to statfs %s: %s\n", filename, strerror(errno));
+ return -1;
+ }
+ return sf.f_bsize * sf.f_bfree;
+}
+
+// This program applies binary patches to files in a way that is safe
+// (the original file is not touched until we have the desired
+// replacement for it) and idempotent (it's okay to run this program
+// multiple times).
+//
+// - if the sha1 hash of <file> is <tgt-sha1>, does nothing and exits
+// successfully.
+//
+// - otherwise, if the sha1 hash of <file> is <src-sha1>, applies the
+// bsdiff <patch> to <file> to produce a new file (the type of patch
+// is automatically detected from the file header). If that new
+// file has sha1 hash <tgt-sha1>, moves it to replace <file>, and
+// exits successfully.
+//
+// - otherwise, or if any error is encountered, exits with non-zero
+// status.
+
+int main(int argc, char** argv) {
+ if (argc < 2) {
+ usage:
+ fprintf(stderr, "usage: %s <file> <tgt-sha1> <tgt-size> [<src-sha1>:<patch> ...]\n"
+ " or %s -c <file> [<sha1> ...]\n"
+ " or %s -s <bytes>\n"
+ " or %s -l\n",
+ argv[0], argv[0], argv[0], argv[0]);
+ return 1;
+ }
+
+ if (strncmp(argv[1], "-l", 3) == 0) {
+ return ShowLicenses();
+ }
+
+ if (strncmp(argv[1], "-c", 3) == 0) {
+ return CheckMode(argc, argv);
+ }
+
+ if (strncmp(argv[1], "-s", 3) == 0) {
+ if (argc != 3) {
+ goto usage;
+ }
+ size_t bytes = strtol(argv[2], NULL, 10);
+ if (MakeFreeSpaceOnCache(bytes) < 0) {
+ printf("unable to make %ld bytes available on /cache\n", (long)bytes);
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ uint8_t target_sha1[SHA_DIGEST_SIZE];
+
+ const char* source_filename = argv[1];
+
+ // assume that source_filename (eg "/system/app/Foo.apk") is located
+ // on the same filesystem as its top-level directory ("/system").
+ // We need something that exists for calling statfs().
+ char* source_fs = strdup(argv[1]);
+ char* slash = strchr(source_fs+1, '/');
+ if (slash != NULL) {
+ *slash = '\0';
+ }
+
+ if (ParseSha1(argv[2], target_sha1) != 0) {
+ fprintf(stderr, "failed to parse tgt-sha1 \"%s\"\n", argv[2]);
+ return 1;
+ }
+
+ unsigned long target_size = strtoul(argv[3], NULL, 0);
+
+ int num_patches;
+ Patch* patches;
+ if (ParseShaArgs(argc-4, argv+4, &patches, &num_patches) < 0) { return 1; }
+
+ FileContents copy_file;
+ FileContents source_file;
+ const char* source_patch_filename = NULL;
+ const char* copy_patch_filename = NULL;
+ int made_copy = 0;
+
+ if (LoadFileContents(source_filename, &source_file) == 0) {
+ if (memcmp(source_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) {
+ // The early-exit case: the patch was already applied, this file
+ // has the desired hash, nothing for us to do.
+ fprintf(stderr, "\"%s\" is already target; no patch needed\n",
+ source_filename);
+ return 0;
+ }
+
+ const Patch* to_use =
+ FindMatchingPatch(source_file.sha1, patches, num_patches);
+ if (to_use != NULL) {
+ source_patch_filename = to_use->patch_filename;
+ }
+ }
+
+ if (source_patch_filename == NULL) {
+ free(source_file.data);
+ fprintf(stderr, "source file is bad; trying copy\n");
+
+ if (LoadFileContents(CACHE_TEMP_SOURCE, ©_file) < 0) {
+ // fail.
+ fprintf(stderr, "failed to read copy file\n");
+ return 1;
+ }
+
+ const Patch* to_use =
+ FindMatchingPatch(copy_file.sha1, patches, num_patches);
+ if (to_use != NULL) {
+ copy_patch_filename = to_use->patch_filename;
+ }
+
+ if (copy_patch_filename == NULL) {
+ // fail.
+ fprintf(stderr, "copy file doesn't match source SHA-1s either\n");
+ return 1;
+ }
+ }
+
+ // Is there enough room in the target filesystem to hold the patched file?
+ size_t free_space = FreeSpaceForFile(source_fs);
+ int enough_space = free_space > (target_size * 3 / 2); // 50% margin of error
+ printf("target %ld bytes; free space %ld bytes; enough %d\n",
+ (long)target_size, (long)free_space, enough_space);
+
+ if (!enough_space && source_patch_filename != NULL) {
+ // Using the original source, but not enough free space. First
+ // copy the source file to cache, then delete it from the original
+ // location.
+ if (MakeFreeSpaceOnCache(source_file.size) < 0) {
+ fprintf(stderr, "not enough free space on /cache\n");
+ return 1;
+ }
+
+ if (SaveFileContents(CACHE_TEMP_SOURCE, source_file) < 0) {
+ fprintf(stderr, "failed to back up source file\n");
+ return 1;
+ }
+ made_copy = 1;
+ unlink(source_filename);
+
+ size_t free_space = FreeSpaceForFile(source_fs);
+ printf("(now %ld bytes free for source)\n", (long)free_space);
+ }
+
+ FileContents* source_to_use;
+ const char* patch_filename;
+ if (source_patch_filename != NULL) {
+ source_to_use = &source_file;
+ patch_filename = source_patch_filename;
+ } else {
+ source_to_use = ©_file;
+ patch_filename = copy_patch_filename;
+ }
+
+ // We write the decoded output to "<file>.patch".
+ char* outname = (char*)malloc(strlen(source_filename) + 10);
+ strcpy(outname, source_filename);
+ strcat(outname, ".patch");
+ FILE* output = fopen(outname, "wb");
+ if (output == NULL) {
+ fprintf(