Merge "Make multiple rules to generate a file an error"
diff --git a/core/Makefile b/core/Makefile
index 7bb9d17..2d7f76d 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -47,6 +47,20 @@
unique_product_copy_files_destinations :=
# -----------------------------------------------------------------
+# Define rules to copy headers defined in copy_headers.mk
+# If more than one makefile declared a header, print a warning,
+# then copy the last one defined. This matches the previous make
+# behavior.
+$(foreach dest,$(ALL_COPIED_HEADERS), \
+ $(eval _srcs := $(ALL_COPIED_HEADERS.$(dest).SRC)) \
+ $(eval _src := $(word $(words $(_srcs)),$(_srcs))) \
+ $(if $(call streq,$(_src),$(_srcs)),, \
+ $(warning Duplicate header copy: $(dest)) \
+ $(warning Defined in: $(ALL_COPIED_HEADERS.$(dest).MAKEFILE))) \
+ $(eval $(call copy-one-header,$(_src),$(dest))))
+all_copied_headers: $(ALL_COPIED_HEADERS)
+
+# -----------------------------------------------------------------
# docs/index.html
ifeq (,$(TARGET_BUILD_APPS))
gen := $(OUT_DOCS)/index.html
@@ -468,7 +482,6 @@
# the ramdisk
INTERNAL_RAMDISK_FILES := $(filter $(TARGET_ROOT_OUT)/%, \
$(ALL_PREBUILT) \
- $(ALL_COPIED_HEADERS) \
$(ALL_GENERATED_SOURCES) \
$(ALL_DEFAULT_INSTALLED_MODULES))
@@ -1032,7 +1045,6 @@
INTERNAL_SYSTEMIMAGE_FILES := $(filter $(TARGET_OUT)/%, \
$(ALL_PREBUILT) \
- $(ALL_COPIED_HEADERS) \
$(ALL_GENERATED_SOURCES) \
$(ALL_DEFAULT_INSTALLED_MODULES) \
$(PDK_FUSION_SYSIMG_FILES) \
@@ -1949,7 +1961,6 @@
ifeq ($(strip $(ATREE_FILES)),)
ATREE_FILES := \
$(ALL_PREBUILT) \
- $(ALL_COPIED_HEADERS) \
$(ALL_DEFAULT_INSTALLED_MODULES) \
$(INSTALLED_RAMDISK_TARGET) \
$(ALL_DOCS) \
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 2fe0616..40e546e 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -323,23 +323,22 @@
endif
# Rule to install the module's companion init.rc.
-my_init_rc := $(LOCAL_INIT_RC_$(my_32_64_bit_suffix))
-my_init_rc_src :=
my_init_rc_installed :=
-ifndef my_init_rc
-my_init_rc := $(LOCAL_INIT_RC)
+my_init_rc_pairs :=
+my_init_rc := $(LOCAL_INIT_RC_$(my_32_64_bit_suffix))
+ifneq ($(my_init_rc),)
+my_init_rc_pairs += $(LOCAL_PATH)/$(my_init_rc):$(TARGET_OUT$(partition_tag)_ETC)/init/$(notdir $(my_init_rc))
+endif
+ifneq ($(LOCAL_INIT_RC),)
+my_init_rc_pairs += $(LOCAL_PATH)/$(LOCAL_INIT_RC):$(TARGET_OUT$(partition_tag)_ETC)/init/$(notdir $(LOCAL_INIT_RC))
# Make sure we don't define the rule twice in multilib module.
LOCAL_INIT_RC :=
endif
-ifdef my_init_rc
-my_init_rc_src := $(LOCAL_PATH)/$(my_init_rc)
-my_init_rc_installed := $(TARGET_OUT$(partition_tag)_ETC)/init/$(notdir $(my_init_rc_src))
-$(my_init_rc_installed) : $(my_init_rc_src) | $(ACP)
- @echo "Install: $@"
- $(copy-file-to-new-target)
+ifneq ($(my_init_rc_pairs),)
+my_init_rc_installed := $(call copy-many-files,$(my_init_rc_pairs))
$(my_register_name) : $(my_init_rc_installed)
-endif # my_init_rc
+endif # my_init_rc_pairs
endif # !LOCAL_UNINSTALLABLE_MODULE
###########################################################
@@ -392,7 +391,7 @@
ALL_MODULES.$(my_register_name).BUILT_INSTALLED := \
$(strip $(ALL_MODULES.$(my_register_name).BUILT_INSTALLED) \
$(LOCAL_BUILT_MODULE):$(LOCAL_INSTALLED_MODULE) \
- $(addprefix $(my_init_rc_src):,$(my_init_rc_installed)))
+ $(my_init_rc_pairs))
endif
ifdef LOCAL_PICKUP_FILES
# Files or directories ready to pick up by the build system
diff --git a/core/binary.mk b/core/binary.mk
index 1c7ffda..aab1248 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -1346,6 +1346,21 @@
my_cppflags := $(filter-out $(my_illegal_flags),$(my_cppflags))
my_conlyflags := $(filter-out $(my_illegal_flags),$(my_conlyflags))
+# We can enforce some rules more strictly in the code we own. my_strict
+# indicates if this is code that we can be stricter with. If we have rules that
+# we want to apply to *our* code (but maybe can't for vendor/device specific
+# things), we could extend this to be a ternary value.
+my_strict := true
+ifneq ($(filter external/%,$(LOCAL_PATH)),)
+ my_strict := false
+endif
+
+# Can be used to make some annotations stricter for code we can fix (such as
+# when we mark functions as deprecated).
+ifeq ($(my_strict),true)
+ my_cflags += -DANDROID_STRICT
+endif
+
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_YACCFLAGS := $(LOCAL_YACCFLAGS)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ASFLAGS := $(my_asflags)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CONLYFLAGS := $(my_conlyflags)
diff --git a/core/clang/versions.mk b/core/clang/versions.mk
index 7106899..96872c2 100644
--- a/core/clang/versions.mk
+++ b/core/clang/versions.mk
@@ -1,5 +1,5 @@
## Clang/LLVM release versions.
LLVM_RELEASE_VERSION := 3.8
-LLVM_PREBUILTS_VERSION ?= clang-2577113
+LLVM_PREBUILTS_VERSION ?= clang-2629532
LLVM_PREBUILTS_BASE ?= prebuilts/clang/host
diff --git a/core/combo/arch/arm/armv7-a-neon.mk b/core/combo/arch/arm/armv7-a-neon.mk
index 5dc1fec..5d5b050 100644
--- a/core/combo/arch/arm/armv7-a-neon.mk
+++ b/core/combo/arch/arm/armv7-a-neon.mk
@@ -6,6 +6,8 @@
ARCH_ARM_HAVE_VFP_D32 := true
ARCH_ARM_HAVE_NEON := true
+local_arch_has_lpae := false
+
ifneq (,$(filter cortex-a15 krait denver,$(TARGET_$(combo_2nd_arch_prefix)CPU_VARIANT)))
# TODO: krait is not a cortex-a15, we set the variant to cortex-a15 so that
# hardware divide operations are generated. This should be removed and a
@@ -13,9 +15,7 @@
# core/clang/arm.mk.
arch_variant_cflags := -mcpu=cortex-a15
- # Fake an ARM compiler flag as these processors support LPAE which GCC/clang
- # don't advertise.
- arch_variant_cflags += -D__ARM_FEATURE_LPAE=1
+ local_arch_has_lpae := true
arch_variant_ldflags := \
-Wl,--no-fix-cortex-a8
else
@@ -26,6 +26,8 @@
else
ifneq (,$(filter cortex-a7 cortex-a53 cortex-a53.a57,$(TARGET_$(combo_2nd_arch_prefix)CPU_VARIANT)))
arch_variant_cflags := -mcpu=cortex-a7
+
+ local_arch_has_lpae := true
arch_variant_ldflags := \
-Wl,--no-fix-cortex-a8
else
@@ -37,6 +39,16 @@
endif
endif
+ifeq (true,$(local_arch_has_lpae))
+ # Fake an ARM compiler flag as these processors support LPAE which GCC/clang
+ # don't advertise.
+ # TODO This is a hack and we need to add it for each processor that supports LPAE until some
+ # better solution comes around. See Bug 27340895
+ arch_variant_cflags += -D__ARM_FEATURE_LPAE=1
+endif
+
+local_arch_has_lpae :=
+
arch_variant_cflags += \
-mfloat-abi=softfp \
-mfpu=neon
diff --git a/core/copy_headers.mk b/core/copy_headers.mk
index e16560f..7d5a5d9 100644
--- a/core/copy_headers.mk
+++ b/core/copy_headers.mk
@@ -18,8 +18,10 @@
$(if $(LOCAL_COPY_HEADERS_TO),\
$($(my_prefix)OUT_HEADERS)/$(LOCAL_COPY_HEADERS_TO)/$(notdir $(header)),\
$($(my_prefix)OUT_HEADERS)/$(notdir $(header)))) \
- $(eval $(call copy-one-header,$(_chFrom),$(_chTo))) \
- $(eval all_copied_headers: $(_chTo)) \
+ $(eval ALL_COPIED_HEADERS.$(_chTo).MAKEFILE += $(LOCAL_MODULE_MAKEFILE)) \
+ $(eval ALL_COPIED_HEADERS.$(_chTo).SRC += $(_chFrom)) \
+ $(if $(filter $(_chTo),$(ALL_COPIED_HEADERS)),, \
+ $(eval ALL_COPIED_HEADERS += $(_chTo))) \
)
_chFrom :=
_chTo :=
diff --git a/envsetup.sh b/envsetup.sh
index 61b9ff0..9489d21 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -644,11 +644,18 @@
local T="$1"
test "$WITH_STATIC_ANALYZER" = "0" && unset WITH_STATIC_ANALYZER
if [ -n "$WITH_STATIC_ANALYZER" ]; then
+ # Use scan-build to collect all static analyzer reports into directory
+ # /tmp/scan-build-yyyy-mm-dd-hhmmss-*
+ # The clang compiler passed by --use-analyzer here is not important.
+ # build/core/binary.mk will set CLANG_CXX and CLANG before calling
+ # c++-analyzer and ccc-analyzer.
+ local CLANG_VERSION=$(get_build_var LLVM_PREBUILTS_VERSION)
+ local BUILD_OS=$(get_build_var BUILD_OS)
+ local CLANG_DIR="$T/prebuilts/clang/host/${BUILD_OS}-x86/${CLANG_VERSION}"
echo "\
-$T/prebuilts/misc/linux-x86/analyzer/tools/scan-build/scan-build \
---use-analyzer $T/prebuilts/misc/linux-x86/analyzer/bin/analyzer \
---status-bugs \
---top=$T"
+${CLANG_DIR}/tools/scan-build/bin/scan-build \
+--use-analyzer ${CLANG_DIR}/bin/clang \
+--status-bugs"
fi
}
diff --git a/tools/releasetools/edify_generator.py b/tools/releasetools/edify_generator.py
index f57360a..57f8cda 100644
--- a/tools/releasetools/edify_generator.py
+++ b/tools/releasetools/edify_generator.py
@@ -83,11 +83,17 @@
raise ValueError("must specify an OEM property")
if not value:
raise ValueError("must specify the OEM value")
- cmd = ('file_getprop("/oem/oem.prop", "{name}") == "{value}" || '
- 'abort("This package expects the value \\"{value}\\" for '
- '\\"{name}\\" on the OEM partition; this has value \\"" + '
- 'file_getprop("/oem/oem.prop", "{name}") + "\\".");').format(
- name=name, value=value)
+ if common.OPTIONS.oem_no_mount:
+ cmd = ('getprop("{name}") == "{value}" || '
+ 'abort("This package expects the value \\"{value}\\" for '
+ '\\"{name}\\"; this has value \\"" + '
+ 'getprop("{name}") + "\\".");').format(name=name, value=value)
+ else:
+ cmd = ('file_getprop("/oem/oem.prop", "{name}") == "{value}" || '
+ 'abort("This package expects the value \\"{value}\\" for '
+ '\\"{name}\\" on the OEM partition; this has value \\"" + '
+ 'file_getprop("/oem/oem.prop", "{name}") + "\\".");').format(
+ name=name, value=value)
self.script.append(cmd)
def AssertSomeFingerprint(self, *fp):
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index bea33a3..f51920a 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -54,6 +54,12 @@
Use the file to specify the expected OEM-specific properties
on the OEM partition of the intended device.
+ --oem_no_mount
+ For devices with OEM-specific properties but without an OEM partition,
+ do not mount the OEM partition in the updater-script. This should be
+ very rarely used, since it's expected to have a dedicated OEM partition
+ for OEM-specific properties. Only meaningful when -o is specified.
+
-w (--wipe_user_data)
Generate an OTA package that will wipe the user data partition
when installed.
@@ -63,6 +69,13 @@
the build scripts (used for developer OTA packages which
legitimately need to go back and forth).
+ --downgrade
+ Intentionally generate an incremental OTA that updates from a newer
+ build to an older one (based on timestamp comparison). "post-timestamp"
+ will be replaced by "ota-downgrade=yes" in the metadata file. A data
+ wipe will always be enforced, so "ota-wipe=yes" will also be included in
+ the metadata file.
+
-e (--extra_script) <file>
Insert the contents of file at the end of the update script.
@@ -126,6 +139,7 @@
OPTIONS.patch_threshold = 0.95
OPTIONS.wipe_user_data = False
OPTIONS.omit_prereq = False
+OPTIONS.downgrade = False
OPTIONS.extra_script = None
OPTIONS.aslr_mode = True
OPTIONS.worker_threads = multiprocessing.cpu_count() // 2
@@ -136,6 +150,7 @@
OPTIONS.block_based = False
OPTIONS.updater_binary = None
OPTIONS.oem_source = None
+OPTIONS.oem_no_mount = False
OPTIONS.fallback_to_full = True
OPTIONS.full_radio = False
OPTIONS.full_bootloader = False
@@ -518,7 +533,8 @@
if oem_props is not None and len(oem_props) > 0:
if OPTIONS.oem_source is None:
raise common.ExternalError("OEM source required for this build")
- script.Mount("/oem", recovery_mount_options)
+ if not OPTIONS.oem_no_mount:
+ script.Mount("/oem", recovery_mount_options)
oem_dict = common.LoadDictionaryFromLines(
open(OPTIONS.oem_source).readlines())
@@ -698,8 +714,9 @@
endif;
endif;
""" % bcb_dev)
- script.AddToZip(input_zip, output_zip, input_path=OPTIONS.updater_binary)
+ script.SetProgress(1)
+ script.AddToZip(input_zip, output_zip, input_path=OPTIONS.updater_binary)
metadata["ota-required-cache"] = str(script.required_cache)
WriteMetadata(metadata, output_zip)
@@ -768,18 +785,38 @@
if oem_props is not None and len(oem_props) > 0:
if OPTIONS.oem_source is None:
raise common.ExternalError("OEM source required for this build")
- script.Mount("/oem", recovery_mount_options)
+ if not OPTIONS.oem_no_mount:
+ script.Mount("/oem", recovery_mount_options)
oem_dict = common.LoadDictionaryFromLines(
open(OPTIONS.oem_source).readlines())
metadata = {
"pre-device": GetOemProperty("ro.product.device", oem_props, oem_dict,
OPTIONS.source_info_dict),
- "post-timestamp": GetBuildProp("ro.build.date.utc",
- OPTIONS.target_info_dict),
"ota-type": "BLOCK",
}
+ post_timestamp = GetBuildProp("ro.build.date.utc", OPTIONS.target_info_dict)
+ pre_timestamp = GetBuildProp("ro.build.date.utc", OPTIONS.source_info_dict)
+ is_downgrade = long(post_timestamp) < long(pre_timestamp)
+
+ if OPTIONS.downgrade:
+ metadata["ota-downgrade"] = "yes"
+ if not is_downgrade:
+ raise RuntimeError("--downgrade specified but no downgrade detected: "
+ "pre: %s, post: %s" % (pre_timestamp, post_timestamp))
+ else:
+ if is_downgrade:
+ # Non-fatal here to allow generating such a package which may require
+ # manual work to adjust the post-timestamp. A legit use case is that we
+ # cut a new build C (after having A and B), but want to enfore the
+ # update path of A -> C -> B. Specifying --downgrade may not help since
+ # that would enforce a data wipe for C -> B update.
+ print("\nWARNING: downgrade detected: pre: %s, post: %s.\n"
+ "The package may not be deployed properly. "
+ "Try --downgrade?\n" % (pre_timestamp, post_timestamp))
+ metadata["post-timestamp"] = post_timestamp
+
device_specific = common.DeviceSpecificParams(
source_zip=source_zip,
source_version=source_version,
@@ -1009,6 +1046,7 @@
if OPTIONS.wipe_user_data:
script.Print("Erasing user data...")
script.FormatPartition("/data")
+ metadata["ota-wipe"] = "yes"
if OPTIONS.two_step:
script.AppendExtra("""
@@ -1033,7 +1071,8 @@
if oem_props is not None and len(oem_props) > 0:
if OPTIONS.oem_source is None:
raise common.ExternalError("OEM source required for this build")
- script.Mount("/oem", recovery_mount_options)
+ if not OPTIONS.oem_no_mount:
+ script.Mount("/oem", recovery_mount_options)
oem_dict = common.LoadDictionaryFromLines(
open(OPTIONS.oem_source).readlines())
@@ -1392,11 +1431,30 @@
metadata = {
"pre-device": GetOemProperty("ro.product.device", oem_props, oem_dict,
OPTIONS.source_info_dict),
- "post-timestamp": GetBuildProp("ro.build.date.utc",
- OPTIONS.target_info_dict),
"ota-type": "FILE",
}
+ post_timestamp = GetBuildProp("ro.build.date.utc", OPTIONS.target_info_dict)
+ pre_timestamp = GetBuildProp("ro.build.date.utc", OPTIONS.source_info_dict)
+ is_downgrade = long(post_timestamp) < long(pre_timestamp)
+
+ if OPTIONS.downgrade:
+ metadata["ota-downgrade"] = "yes"
+ if not is_downgrade:
+ raise RuntimeError("--downgrade specified but no downgrade detected: "
+ "pre: %s, post: %s" % (pre_timestamp, post_timestamp))
+ else:
+ if is_downgrade:
+ # Non-fatal here to allow generating such a package which may require
+ # manual work to adjust the post-timestamp. A legit use case is that we
+ # cut a new build C (after having A and B), but want to enfore the
+ # update path of A -> C -> B. Specifying --downgrade may not help since
+ # that would enforce a data wipe for C -> B update.
+ print("\nWARNING: downgrade detected: pre: %s, post: %s.\n"
+ "The package may not be deployed properly. "
+ "Try --downgrade?\n" % (pre_timestamp, post_timestamp))
+ metadata["post-timestamp"] = post_timestamp
+
device_specific = common.DeviceSpecificParams(
source_zip=source_zip,
source_version=source_version,
@@ -1725,6 +1783,7 @@
if OPTIONS.wipe_user_data:
script.Print("Erasing user data...")
script.FormatPartition("/data")
+ metadata["ota-wipe"] = "yes"
if OPTIONS.two_step:
script.AppendExtra("""
@@ -1767,8 +1826,13 @@
OPTIONS.wipe_user_data = True
elif o in ("-n", "--no_prereq"):
OPTIONS.omit_prereq = True
+ elif o == "--downgrade":
+ OPTIONS.downgrade = True
+ OPTIONS.wipe_user_data = True
elif o in ("-o", "--oem_settings"):
OPTIONS.oem_source = a
+ elif o == "--oem_no_mount":
+ OPTIONS.oem_no_mount = True
elif o in ("-e", "--extra_script"):
OPTIONS.extra_script = a
elif o in ("-a", "--aslr_mode"):
@@ -1818,6 +1882,7 @@
"full_bootloader",
"wipe_user_data",
"no_prereq",
+ "downgrade",
"extra_script=",
"worker_threads=",
"aslr_mode=",
@@ -1826,6 +1891,7 @@
"block",
"binary=",
"oem_settings=",
+ "oem_no_mount",
"verify",
"no_fallback_to_full",
"stash_threshold=",
@@ -1837,6 +1903,18 @@
common.Usage(__doc__)
sys.exit(1)
+ if OPTIONS.downgrade:
+ # Sanity check to enforce a data wipe.
+ if not OPTIONS.wipe_user_data:
+ raise ValueError("Cannot downgrade without a data wipe")
+
+ # We should only allow downgrading incrementals (as opposed to full).
+ # Otherwise the device may go back from arbitrary build with this full
+ # OTA package.
+ if OPTIONS.incremental_source is None:
+ raise ValueError("Cannot generate downgradable full OTAs - consider"
+ "using --omit_prereq?")
+
# Load the dict file from the zip directly to have a peek at the OTA type.
# For packages using A/B update, unzipping is not needed.
input_zip = zipfile.ZipFile(args[0], "r")