diff options
-rw-r--r-- | core/Makefile | 11 | ||||
-rw-r--r-- | core/base_rules.mk | 2 | ||||
-rw-r--r-- | core/binary.mk | 29 | ||||
-rw-r--r-- | core/build_id.mk | 2 | ||||
-rw-r--r-- | core/clang/HOST_x86_common.mk | 2 | ||||
-rw-r--r-- | core/clear_vars.mk | 1 | ||||
-rw-r--r-- | core/config.mk | 5 | ||||
-rw-r--r-- | core/generate_extra_images.mk | 8 | ||||
-rw-r--r-- | core/main.mk | 4 | ||||
-rw-r--r-- | core/mtk_target.mk | 13 | ||||
-rw-r--r-- | core/prebuilt_internal.mk | 5 | ||||
-rw-r--r-- | core/product.mk | 4 | ||||
-rw-r--r-- | core/qcom_target.mk | 30 | ||||
-rwxr-xr-x | core/qcom_utils.mk | 3 | ||||
-rw-r--r-- | core/static_java_library.mk | 4 | ||||
-rw-r--r-- | core/tasks/dt_image.mk | 11 | ||||
-rw-r--r-- | core/tasks/kernel.mk | 17 | ||||
-rw-r--r-- | core/tasks/oem_image.mk | 11 | ||||
-rw-r--r-- | core/version_defaults.mk | 10 | ||||
-rw-r--r-- | envsetup.sh | 36 | ||||
-rw-r--r-- | target/product/core_minimal.mk | 4 | ||||
-rwxr-xr-x | tools/buildinfo.sh | 6 | ||||
-rwxr-xr-x | tools/releasetools/add_img_to_target_files.py | 47 | ||||
-rwxr-xr-x | tools/releasetools/build_image.py | 23 | ||||
-rw-r--r-- | tools/releasetools/common.py | 67 | ||||
-rwxr-xr-x | tools/releasetools/img_from_target_files.py | 3 | ||||
-rwxr-xr-x | tools/releasetools/sign_target_files_apks.py | 2 | ||||
-rwxr-xr-x | tools/repopick.py | 46 |
28 files changed, 324 insertions, 82 deletions
diff --git a/core/Makefile b/core/Makefile index 6cfbc2e..b9f7c2e 100644 --- a/core/Makefile +++ b/core/Makefile @@ -248,6 +248,8 @@ endif TARGET_CPU_ABI2="$(TARGET_CPU_ABI2)" \ TARGET_AAPT_CHARACTERISTICS="$(TARGET_AAPT_CHARACTERISTICS)" \ TARGET_UNIFIED_DEVICE="$(TARGET_UNIFIED_DEVICE)" \ + TARGET_SKIP_DEFAULT_LOCALE="$(TARGET_SKIP_DEFAULT_LOCALE)" \ + TARGET_SKIP_PRODUCT_DEVICE="$(TARGET_SKIP_PRODUCT_DEVICE)" \ $(PRODUCT_BUILD_PROP_OVERRIDES) \ bash $(BUILDINFO_SH) >> $@ $(hide) $(foreach file,$(system_prop_file), \ @@ -549,7 +551,7 @@ ifeq ($(TARGET_BOOTIMAGE_USE_EXT2),true) $(error TARGET_BOOTIMAGE_USE_EXT2 is not supported anymore) else ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_BOOT_SIGNER)) # TARGET_BOOTIMAGE_USE_EXT2 != true -$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES) $(BOOT_SIGNER) +$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES) $(BOOT_SIGNER) $(BOOTIMAGE_EXTRA_DEPS) $(call pretty,"Target boot image: $@") $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@ $(BOOT_SIGNER) /boot $@ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pem $@ @@ -1651,6 +1653,7 @@ endif # Depending on the various images guarantees that the underlying # directories are up-to-date. +include $(BUILD_SYSTEM)/tasks/oem_image.mk $(BUILT_TARGET_FILES_PACKAGE): \ $(INSTALLED_BOOTIMAGE_TARGET) \ $(INSTALLED_RADIOIMAGE_TARGET) \ @@ -1659,6 +1662,7 @@ $(BUILT_TARGET_FILES_PACKAGE): \ $(INSTALLED_USERDATAIMAGE_TARGET) \ $(INSTALLED_CACHEIMAGE_TARGET) \ $(INSTALLED_VENDORIMAGE_TARGET) \ + $(INSTALLED_OEMIMAGE_TARGET) \ $(INSTALLED_ANDROID_INFO_TXT_TARGET) \ $(SELINUX_FC) \ $(built_ota_tools) \ @@ -1768,6 +1772,11 @@ ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE $(hide) $(call package_files-copy-root, \ $(TARGET_OUT_VENDOR),$(zip_root)/VENDOR) endif +ifdef BOARD_OEMIMAGE_FILE_SYSTEM_TYPE + @# Contents of the oem image + $(call package_files-copy-root, \ + $(TARGET_OUT_OEM),$(zip_root)/OEM) +endif @# Extra contents of the OTA package $(hide) mkdir -p $(zip_root)/OTA/bin $(hide) $(ACP) $(INSTALLED_ANDROID_INFO_TXT_TARGET) $(zip_root)/OTA/ diff --git a/core/base_rules.mk b/core/base_rules.mk index 202398a..8ed6dcf 100644 --- a/core/base_rules.mk +++ b/core/base_rules.mk @@ -219,7 +219,7 @@ else # build against the platform. LOCAL_AIDL_INCLUDES += $(FRAMEWORKS_BASE_JAVA_SRC_DIRS) endif # LOCAL_SDK_VERSION -$(aidl_java_sources): PRIVATE_AIDL_FLAGS := -b $(addprefix -p,$(aidl_preprocess_import)) -I$(LOCAL_PATH) -I$(LOCAL_PATH)/src $(addprefix -I,$(LOCAL_AIDL_INCLUDES)) +$(aidl_java_sources): PRIVATE_AIDL_FLAGS := -b $(addprefix -p,$(aidl_preprocess_import)) -I$(LOCAL_PATH) -I$(LOCAL_PATH)/src $(addprefix -I,$(LOCAL_AIDL_INCLUDES)) $(LOCAL_AIDL_FLAGS) $(aidl_java_sources): $(intermediates.COMMON)/src/%.java: \ $(TOPDIR)$(LOCAL_PATH)/%.aidl \ diff --git a/core/binary.mk b/core/binary.mk index e25fb31..7610dce 100644 --- a/core/binary.mk +++ b/core/binary.mk @@ -30,6 +30,15 @@ else endif endif +# Many qcom modules don't correctly set a dependency on the kernel headers. Fix it for them, +# but warn the user. +ifneq (,$(findstring $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include,$(LOCAL_C_INCLUDES))) + ifeq (,$(findstring $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr,$(LOCAL_ADDITIONAL_DEPENDENCIES))) + $(warning $(LOCAL_MODULE) uses kernel headers, but does not depend on them!) + LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr + endif +endif + # The following LOCAL_ variables will be modified in this file. # Because the same LOCAL_ variables may be used to define modules for both 1st arch and 2nd arch, # we can't modify them in place. @@ -542,9 +551,10 @@ define copy-proto-files $(if $(PRIVATE_PROTOC_OUTPUT), \ $(if $(call streq,$(PRIVATE_PROTOC_INPUT),$(PRIVATE_PROTOC_OUTPUT)),, \ $(eval proto_generated_path := $(dir $(subst $(PRIVATE_PROTOC_INPUT),$(PRIVATE_PROTOC_OUTPUT),$@))) + $(eval proto_target_files := $(patsubst %.pb$(PRIVATE_PROTOC_SUFFIX), %.pb.*, $@)) @mkdir -p $(dir $(proto_generated_path)) - @echo "Protobuf relocation: $@ => $(proto_generated_path)" - @cp -f $@ $(proto_generated_path) ),) + @echo "Protobuf relocation: $(proto_target_files) => $(proto_generated_path)" + @cp -f $(proto_target_files) $(proto_generated_path) ),) endef @@ -554,28 +564,15 @@ $(proto_generated_sources): PRIVATE_PROTO_INCLUDES := $(TOP) $(proto_generated_sources): PRIVATE_PROTOC_FLAGS := $(LOCAL_PROTOC_FLAGS) $(my_protoc_flags) $(proto_generated_sources): PRIVATE_PROTOC_OUTPUT := $(LOCAL_PROTOC_OUTPUT) $(proto_generated_sources): PRIVATE_PROTOC_INPUT := $(LOCAL_PATH) +$(proto_generated_sources): PRIVATE_PROTOC_SUFFIX := $(my_proto_source_suffix) $(proto_generated_sources): $(proto_generated_sources_dir)/%.pb$(my_proto_source_suffix): %.proto $(PROTOC) $(transform-proto-to-cc) $(copy-proto-files) # This is just a dummy rule to make sure gmake doesn't skip updating the dependents. -$(proto_generated_headers): PRIVATE_PROTOC_OUTPUT := $(LOCAL_PROTOC_OUTPUT) -$(proto_generated_headers): PRIVATE_PROTOC_INPUT := $(LOCAL_PATH) $(proto_generated_headers): $(proto_generated_sources_dir)/%.pb.h: $(proto_generated_sources_dir)/%.pb$(my_proto_source_suffix) @echo "Updated header file $@." $(hide) touch $@ - $(copy-proto-files) - -$(if $(LOCAL_PROTOC_OUTPUT), \ -$(if $(call streq,$(LOCAL_PROTOC_OUTPUT),$(LOCAL_PATH)),, \ - $(eval proto_relocated_headers := $(subst $(LOCAL_PATH),$(LOCAL_PROTOC_OUTPUT),$(proto_generated_headers))) \ - ), ) - -ifdef proto_relocated_headers -$(proto_relocated_headers): $(proto_generated_headers) - echo "Refreshed header file $@." - $(hide) touch $@ -endif $(my_prefix)_$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_proto_defined := true endif # transform-proto-to-cc rule included only once diff --git a/core/build_id.mk b/core/build_id.mk index c2f0b28..8928324 100644 --- a/core/build_id.mk +++ b/core/build_id.mk @@ -18,4 +18,4 @@ # (like "CRB01"). It must be a single word, and is # capitalized by convention. -export BUILD_ID=MHC19J +export BUILD_ID=MOB31K diff --git a/core/clang/HOST_x86_common.mk b/core/clang/HOST_x86_common.mk index 87135e7..31415ef 100644 --- a/core/clang/HOST_x86_common.mk +++ b/core/clang/HOST_x86_common.mk @@ -47,4 +47,4 @@ endif # Linux ifeq ($(HOST_OS),windows) # nothing required here yet -endif +endif
\ No newline at end of file diff --git a/core/clear_vars.mk b/core/clear_vars.mk index 5c53c9f..1a3ce19 100644 --- a/core/clear_vars.mk +++ b/core/clear_vars.mk @@ -103,6 +103,7 @@ LOCAL_APK_LIBRARIES:= LOCAL_RES_LIBRARIES:= LOCAL_MANIFEST_INSTRUMENTATION_FOR:= LOCAL_AIDL_INCLUDES:= +LOCAL_AIDL_FLAGS:= LOCAL_JARJAR_RULES:= LOCAL_ADDITIONAL_JAVA_DIR:= LOCAL_ALLOW_UNDEFINED_SYMBOLS:= diff --git a/core/config.mk b/core/config.mk index f6a1458..facf37c 100644 --- a/core/config.mk +++ b/core/config.mk @@ -187,6 +187,8 @@ FIND_LEAVES_EXCLUDES := $(addprefix --prune=, $(OUT_DIR) $(SCAN_EXCLUDE_DIRS) .r $(call project-set-path-variant,recovery,RECOVERY_VARIANT,bootable/recovery) -include vendor/extra/BoardConfigExtra.mk +-include vendor/cm/config/BoardConfigCM.mk + # The build system exposes several variables for where to find the kernel # headers: # TARGET_DEVICE_KERNEL_HEADERS is automatically created for the current @@ -563,6 +565,9 @@ endif # Rules for QCOM targets include $(BUILD_SYSTEM)/qcom_target.mk +# Rules for MTK targets +include $(BUILD_SYSTEM)/mtk_target.mk + # ############################################################### # Set up final options. # ############################################################### diff --git a/core/generate_extra_images.mk b/core/generate_extra_images.mk index 8ac9867..f7fb0c5 100644 --- a/core/generate_extra_images.mk +++ b/core/generate_extra_images.mk @@ -108,11 +108,11 @@ endif .PHONY: aboot aboot: $(INSTALLED_BOOTLOADER_MODULE) -.PHONY: kernel -kernel: $(INSTALLED_BOOTIMAGE_TARGET) $(INSTALLED_SEC_BOOTIMAGE_TARGET) +.PHONY: sec_bootimage +sec_bootimage: $(INSTALLED_BOOTIMAGE_TARGET) $(INSTALLED_SEC_BOOTIMAGE_TARGET) -.PHONY: recoveryimage -recoveryimage: $(INSTALLED_RECOVERYIMAGE_TARGET) $(INSTALLED_SEC_RECOVERYIMAGE_TARGET) +.PHONY: sec_recoveryimage +sec_recoveryimage: $(INSTALLED_RECOVERYIMAGE_TARGET) $(INSTALLED_SEC_RECOVERYIMAGE_TARGET) .PHONY: persistimage persistimage: $(INSTALLED_PERSISTIMAGE_TARGET) diff --git a/core/main.mk b/core/main.mk index e6794a0..139fa46 100644 --- a/core/main.mk +++ b/core/main.mk @@ -98,6 +98,9 @@ include $(BUILD_SYSTEM)/config.mk # CTS-specific config. -include cts/build/config.mk +# CMTS-specific config. +-include vendor/cmts/build/config.mk + # This allows us to force a clean build - included after the config.mk # 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 @@ -284,6 +287,7 @@ tags_to_install := ifneq (,$(user_variant)) # Target is secure in user builds. ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=1 + ADDITIONAL_DEFAULT_PROPERTIES += security.perf_harden=1 ifeq ($(user_variant),userdebug) # Pick up some extra useful tools diff --git a/core/mtk_target.mk b/core/mtk_target.mk new file mode 100644 index 0000000..7c3ba1f --- /dev/null +++ b/core/mtk_target.mk @@ -0,0 +1,13 @@ +ifeq ($(BOARD_USES_MTK_HARDWARE),true) + mtk_flags := -DMTK_HARDWARE + + TARGET_GLOBAL_CFLAGS += $(mtk_flags) + TARGET_GLOBAL_CPPFLAGS += $(mtk_flags) + CLANG_TARGET_GLOBAL_CFLAGS += $(mtk_flags) + CLANG_TARGET_GLOBAL_CPPFLAGS += $(mtk_flags) + + 2ND_TARGET_GLOBAL_CFLAGS += $(mtk_flags) + 2ND_TARGET_GLOBAL_CPPFLAGS += $(mtk_flags) + 2ND_CLANG_TARGET_GLOBAL_CFLAGS += $(mtk_flags) + 2ND_CLANG_TARGET_GLOBAL_CPPFLAGS += $(mtk_flags) +endif diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk index b5ff3a1..2a4b716 100644 --- a/core/prebuilt_internal.mk +++ b/core/prebuilt_internal.mk @@ -190,6 +190,11 @@ ifeq ($(DONT_DEXPREOPT_PREBUILTS),true) LOCAL_DEX_PREOPT := false endif +# Disable dex-preopt of specific prebuilts to save space, if requested. +ifneq ($(filter $(DEXPREOPT_BLACKLIST),$(LOCAL_MODULE)),) +LOCAL_DEX_PREOPT := false +endif + ####################################### # defines built_odex along with rule to install odex include $(BUILD_SYSTEM)/dex_preopt_odex_install.mk diff --git a/core/product.mk b/core/product.mk index 427fd83..cced554 100644 --- a/core/product.mk +++ b/core/product.mk @@ -327,6 +327,10 @@ _product_stash_var_list += \ GLOBAL_CFLAGS_NO_OVERRIDE \ GLOBAL_CPPFLAGS_NO_OVERRIDE \ +_product_stash_var_list += \ + TARGET_SKIP_DEFAULT_LOCALE \ + TARGET_SKIP_PRODUCT_DEVICE \ + # # Stash values of the variables in _product_stash_var_list. # $(1): Renamed prefix diff --git a/core/qcom_target.mk b/core/qcom_target.mk index 092d832..9b8d6bb 100644 --- a/core/qcom_target.mk +++ b/core/qcom_target.mk @@ -27,12 +27,14 @@ ifeq ($(BOARD_USES_QCOM_HARDWARE),true) qcom_flags += -DQCOM_BSP qcom_flags += -DQTI_BSP + BOARD_USES_ADRENO := true + TARGET_USES_QCOM_BSP := true # Tell HALs that we're compiling an AOSP build with an in-line kernel TARGET_COMPILE_WITH_MSM_KERNEL := true - ifneq ($(filter msm7x30 msm8660 msm8960,$(TARGET_BOARD_PLATFORM)),) + ifneq ($(filter msm7x27a msm7x30 msm8660 msm8960,$(TARGET_BOARD_PLATFORM)),) # Enable legacy graphics functions qcom_flags += -DQCOM_BSP_LEGACY # Enable legacy audio functions @@ -60,6 +62,9 @@ ifeq ($(BOARD_USES_QCOM_HARDWARE),true) ifneq ($(filter msm8909 msm8916,$(TARGET_BOARD_PLATFORM)),) QCOM_HARDWARE_VARIANT := msm8916 else + ifneq ($(filter msm8953 msm8937,$(TARGET_BOARD_PLATFORM)),) + QCOM_HARDWARE_VARIANT := msm8937 + else ifneq ($(filter msm8992 msm8994,$(TARGET_BOARD_PLATFORM)),) QCOM_HARDWARE_VARIANT := msm8994 else @@ -67,17 +72,27 @@ ifeq ($(BOARD_USES_QCOM_HARDWARE),true) endif endif endif + endif endif -$(call project-set-path,qcom-audio,hardware/qcom/audio-caf/$(QCOM_HARDWARE_VARIANT)) - -ifeq ($(SONY_BF64_KERNEL_VARIANT),true) -$(call project-set-path,qcom-display,hardware/qcom/display-caf/sony) -$(call project-set-path,qcom-media,hardware/qcom/media-caf/sony) +# HACK: check to see if build uses standard QC HAL paths by checking for CM path structure +AOSP_VARIANT_MAKEFILE := $(wildcard hardware/qcom/audio/default/Android.mk) +ifeq ("$(AOSP_VARIANT_MAKEFILE)","") +$(call project-set-path,qcom-audio,hardware/qcom/audio) +$(call project-set-path,qcom-display,hardware/qcom/display) +$(call project-set-path,qcom-media,hardware/qcom/media) +$(call set-device-specific-path,CAMERA,camera,hardware/qcom/camera) +$(call set-device-specific-path,GPS,gps,hardware/qcom/gps) +$(call set-device-specific-path,SENSORS,sensors,hardware/qcom/sensors) +$(call set-device-specific-path,LOC_API,loc-api,vendor/qcom/opensource/location) +$(call set-device-specific-path,DATASERVICES,dataservices,vendor/qcom/opensource/dataservices) +$(call project-set-path,ril,hardware/ril) +$(call project-set-path,wlan,hardware/qcom/wlan) +$(call project-set-path,bt-vendor,hardware/qcom/bt) else +$(call project-set-path,qcom-audio,hardware/qcom/audio-caf/$(QCOM_HARDWARE_VARIANT)) $(call project-set-path,qcom-display,hardware/qcom/display-caf/$(QCOM_HARDWARE_VARIANT)) $(call project-set-path,qcom-media,hardware/qcom/media-caf/$(QCOM_HARDWARE_VARIANT)) -endif $(call set-device-specific-path,CAMERA,camera,hardware/qcom/camera) $(call set-device-specific-path,GPS,gps,hardware/qcom/gps) @@ -88,6 +103,7 @@ $(call set-device-specific-path,DATASERVICES,dataservices,vendor/qcom/opensource $(call ril-set-path-variant,ril) $(call wlan-set-path-variant,wlan-caf) $(call bt-vendor-set-path-variant,bt-caf) +endif # AOSP_VARIANT_MAKEFILE else diff --git a/core/qcom_utils.mk b/core/qcom_utils.mk index 5e8a4a2..50e0b4e 100755 --- a/core/qcom_utils.mk +++ b/core/qcom_utils.mk @@ -1,5 +1,6 @@ # Board platforms lists to be used for # TARGET_BOARD_PLATFORM specific featurization +QCOM_BOARD_PLATFORMS += msm7x27a QCOM_BOARD_PLATFORMS += msm7x30 QCOM_BOARD_PLATFORMS += msm8226 QCOM_BOARD_PLATFORMS += msm8610 @@ -9,7 +10,9 @@ QCOM_BOARD_PLATFORMS += msm8916 QCOM_BOARD_PLATFORMS += msm8960 QCOM_BOARD_PLATFORMS += msm8974 QCOM_BOARD_PLATFORMS += mpq8092 +QCOM_BOARD_PLATFORMS += msm8937 QCOM_BOARD_PLATFORMS += msm8952 +QCOM_BOARD_PLATFORMS += msm8953 QCOM_BOARD_PLATFORMS += msm8992 QCOM_BOARD_PLATFORMS += msm8994 QCOM_BOARD_PLATFORMS += msm8996 diff --git a/core/static_java_library.mk b/core/static_java_library.mk index 764ab89..99f4455 100644 --- a/core/static_java_library.mk +++ b/core/static_java_library.mk @@ -140,6 +140,7 @@ $(built_aar): PRIVATE_ANDROID_MANIFEST := $(full_android_manifest) $(built_aar): PRIVATE_CLASSES_JAR := $(LOCAL_BUILT_MODULE) $(built_aar): PRIVATE_RESOURCE_DIR := $(LOCAL_RESOURCE_DIR) $(built_aar): PRIVATE_R_TXT := $(LOCAL_INTERMEDIATE_SOURCE_DIR)/R.txt +$(built_aar): PRIVATE_CONSUMER_PROGUARD_FILE := $(LOCAL_CONSUMER_PROGUARD_FILE) $(built_aar) : $(LOCAL_BUILT_MODULE) @echo "target AAR: $(PRIVATE_MODULE) ($@)" $(hide) rm -rf $(dir $@)aar && mkdir -p $(dir $@)aar/res @@ -148,6 +149,9 @@ $(built_aar) : $(LOCAL_BUILT_MODULE) # Note: Use "cp -n" to honor the resource overlay rules, if multiple res dirs exist. $(hide) $(foreach res,$(PRIVATE_RESOURCE_DIR),cp -Rfn $(res)/* $(dir $@)aar/res;) $(hide) cp $(PRIVATE_R_TXT) $(dir $@)aar/R.txt + $(hide) if [ ! -z "$(PRIVATE_CONSUMER_PROGUARD_FILE)" ]; then \ + echo "Including '$(PRIVATE_CONSUMER_PROGUARD_FILE)'"; \ + cp $(PRIVATE_CONSUMER_PROGUARD_FILE) $(dir $@)aar/proguard.txt; fi $(hide) jar -cMf $@ \ -C $(dir $@)aar . diff --git a/core/tasks/dt_image.mk b/core/tasks/dt_image.mk index ca7e87f..60d45cc 100644 --- a/core/tasks/dt_image.mk +++ b/core/tasks/dt_image.mk @@ -18,8 +18,13 @@ DTBTOOL := $(HOST_OUT_EXECUTABLES)/$(DTBTOOL_NAME)$(HOST_EXECUTABLE_SUFFIX) INSTALLED_DTIMAGE_TARGET := $(PRODUCT_OUT)/dt.img -# Most specific paths must come first in possible_dtb_dirs +ifeq ($(strip $(TARGET_CUSTOM_DTBTOOL)),) +# dtbToolCM will search subdirectories possible_dtb_dirs = $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/ +else +# Most specific paths must come first in possible_dtb_dirs +possible_dtb_dirs = $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/dts/ $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/ +endif dtb_dir = $(firstword $(wildcard $(possible_dtb_dirs))) define build-dtimage-target @@ -34,6 +39,10 @@ $(INSTALLED_DTIMAGE_TARGET): $(DTBTOOL) $(INSTALLED_KERNEL_TARGET) ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_DTIMAGE_TARGET) ALL_MODULES.$(LOCAL_MODULE).INSTALLED += $(INSTALLED_DTIMAGE_TARGET) + +.PHONY: dtimage +dtimage: $(INSTALLED_DTIMAGE_TARGET) + endif endif endif diff --git a/core/tasks/kernel.mk b/core/tasks/kernel.mk index d8185b4..0d8c888 100644 --- a/core/tasks/kernel.mk +++ b/core/tasks/kernel.mk @@ -32,7 +32,9 @@ # TARGET_USES_UNCOMPRESSED_KERNEL = 'true' if Kernel is uncompressed, # optional, defaults to false # TARGET_KERNEL_CROSS_COMPILE_PREFIX = Compiler prefix (e.g. aarch64-linux-android-) -# defaults to arm-eabi- +# defaults to arm-eabi- for arm +# aarch64-linux-android- for arm64 +# x86_64-linux-android- for x86 # # BOARD_KERNEL_IMAGE_NAME = Built image name, optional, # defaults to Image.gz on arm64 @@ -210,10 +212,14 @@ KERNEL_MODULES_OUT := $(TARGET_OUT)/lib/modules endif TARGET_KERNEL_CROSS_COMPILE_PREFIX := $(strip $(TARGET_KERNEL_CROSS_COMPILE_PREFIX)) -ifeq ($(TARGET_KERNEL_CROSS_COMPILE_PREFIX),) -KERNEL_TOOLCHAIN_PREFIX ?= arm-none-eabi- -else +ifneq ($(TARGET_KERNEL_CROSS_COMPILE_PREFIX),) KERNEL_TOOLCHAIN_PREFIX ?= $(TARGET_KERNEL_CROSS_COMPILE_PREFIX) +else ifeq ($(KERNEL_ARCH),arm64) +KERNEL_TOOLCHAIN_PREFIX ?= aarch64-linux-android- +else ifeq ($(KERNEL_ARCH),arm) +KERNEL_TOOLCHAIN_PREFIX ?= arm-none-eabi- +else ifeq ($(KERNEL_ARCH),x86) +KERNEL_TOOLCHAIN_PREFIX ?= x86_64-linux-android- endif ifeq ($(KERNEL_TOOLCHAIN),) @@ -362,3 +368,6 @@ $(file) : $(KERNEL_BIN) | $(ACP) ALL_PREBUILT += $(INSTALLED_KERNEL_TARGET) endif + +.PHONY: kernel +kernel: $(INSTALLED_KERNEL_TARGET) diff --git a/core/tasks/oem_image.mk b/core/tasks/oem_image.mk index 32d56a7..8a06670 100644 --- a/core/tasks/oem_image.mk +++ b/core/tasks/oem_image.mk @@ -15,7 +15,16 @@ # # We build oem.img only if it's asked for. +skip_oem_image := true ifneq ($(filter $(MAKECMDGOALS),oem_image),) + skip_oem_image := false +endif + +ifneq ($(BOARD_OEMIMAGE_FILE_SYSTEM_TYPE),) + skip_oem_image := false +endif + +ifneq ($(skip_oem_image),true) ifndef BOARD_OEMIMAGE_PARTITION_SIZE $(error BOARD_OEMIMAGE_PARTITION_SIZE is not set.) endif @@ -43,4 +52,4 @@ $(INSTALLED_OEMIMAGE_TARGET) : $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_OEMIMAGE_F oem_image : $(INSTALLED_OEMIMAGE_TARGET) $(call dist-for-goals, oem_image, $(INSTALLED_OEMIMAGE_TARGET)) -endif # oem_image in $(MAKECMDGOALS) +endif diff --git a/core/version_defaults.mk b/core/version_defaults.mk index be5833d..03b9011 100644 --- a/core/version_defaults.mk +++ b/core/version_defaults.mk @@ -100,10 +100,12 @@ endif ifeq "" "$(PLATFORM_SECURITY_PATCH)" # Used to indicate the security patch that has been applied to the device. - # Can be an arbitrary string, but must be a single word. - # - # If there is no $PLATFORM_SECURITY_PATCH set, keep it empty. - PLATFORM_SECURITY_PATCH := 2016-03-01 + # It must signify that the build includes all security patches issued up through the designated Android Public Security Bulletin. + # It must be of the form "YYYY-MM-DD" on production devices. + # It must match one of the Android Security Patch Level strings of the Public Security Bulletins. + # + # If there is no $PLATFORM_SECURITY_PATCH set, keep it empty. + PLATFORM_SECURITY_PATCH := 2016-11-05 endif ifeq "" "$(PLATFORM_BASE_OS)" diff --git a/envsetup.sh b/envsetup.sh index f153592..f8ec4ed 100644 --- a/envsetup.sh +++ b/envsetup.sh @@ -1676,13 +1676,13 @@ function godir () { function cmremote() { - git remote rm cmremote 2> /dev/null - GERRIT_REMOTE=$(git config --get remote.github.projectname) - if [ -z "$GERRIT_REMOTE" ] + if ! git rev-parse --git-dir &> /dev/null then - echo Unable to set up the git remote, are you under a git repo? - return 0 + echo ".git directory not found. Please run this from the root directory of the Android repository you wish to set up." + return 1 fi + git remote rm cmremote 2> /dev/null + GERRIT_REMOTE=$(git config --get remote.github.projectname) CMUSER=$(git config --get review.review.cyanogenmod.org.username) if [ -z "$CMUSER" ] then @@ -1690,17 +1690,18 @@ function cmremote() else git remote add cmremote ssh://$CMUSER@review.cyanogenmod.org:29418/$GERRIT_REMOTE fi - echo You can now push to "cmremote". + echo "Remote 'cmremote' created" } function aospremote() { - git remote rm aosp 2> /dev/null - if [ ! -d .git ] + if ! git rev-parse --git-dir &> /dev/null then - echo .git directory not found. Please run this from the root directory of the Android repository you wish to set up. + echo ".git directory not found. Please run this from the root directory of the Android repository you wish to set up." + return 1 fi - PROJECT=`pwd -P | sed s#$ANDROID_BUILD_TOP/##g` + git remote rm aosp 2> /dev/null + PROJECT=$(pwd -P | sed -e "s#$ANDROID_BUILD_TOP\/##; s#-caf.*##; s#\/default##") if (echo $PROJECT | grep -qv "^device") then PFX="platform/" @@ -1711,12 +1712,13 @@ function aospremote() function cafremote() { - git remote rm caf 2> /dev/null - if [ ! -d .git ] + if ! git rev-parse --git-dir &> /dev/null then - echo .git directory not found. Please run this from the root directory of the Android repository you wish to set up. + echo ".git directory not found. Please run this from the root directory of the Android repository you wish to set up." + return 1 fi - PROJECT=`pwd -P | sed s#$ANDROID_BUILD_TOP/##g` + git remote rm caf 2> /dev/null + PROJECT=$(pwd -P | sed -e "s#$ANDROID_BUILD_TOP\/##; s#-caf.*##; s#\/default##") if (echo $PROJECT | grep -qv "^device") then PFX="platform/" @@ -2373,11 +2375,7 @@ function fixup_common_out_dir() { fi } -# Force JAVA_HOME to point to java 1.7 if it isn't already set. -# -# Note that the MacOS path for java 1.7 includes a minor revision number (sigh). -# For some reason, installing the JDK doesn't make it show up in the -# JavaVM.framework/Versions/1.7/ folder. +# Force JAVA_HOME to point to java 1.7/1.8 if it isn't already set. function set_java_home() { # Clear the existing JAVA_HOME value if we set it ourselves, so that # we can reset it later, depending on the version of java the build diff --git a/target/product/core_minimal.mk b/target/product/core_minimal.mk index ecd42b0..e8f2620 100644 --- a/target/product/core_minimal.mk +++ b/target/product/core_minimal.mk @@ -104,10 +104,8 @@ PRODUCT_SYSTEM_SERVER_JARS := \ ethernet-service \ wifi-service -# Adoptable external storage supports both ext4 and f2fs +# Adoptable external storage f2fs support PRODUCT_PACKAGES += \ - e2fsck \ - make_ext4fs \ fsck.f2fs \ mkfs.f2fs \ diff --git a/tools/buildinfo.sh b/tools/buildinfo.sh index 559cd88..fa717b7 100755 --- a/tools/buildinfo.sh +++ b/tools/buildinfo.sh @@ -37,7 +37,7 @@ echo "ro.product.cpu.abilist32=$TARGET_CPU_ABI_LIST_32_BIT" echo "ro.product.cpu.abilist64=$TARGET_CPU_ABI_LIST_64_BIT" echo "ro.product.manufacturer=$PRODUCT_MANUFACTURER" -if [ -n "$PRODUCT_DEFAULT_LOCALE" ] ; then +if [ -n "$PRODUCT_DEFAULT_LOCALE" ] && [ -z "$TARGET_SKIP_DEFAULT_LOCALE" ] ; then echo "ro.product.locale=$PRODUCT_DEFAULT_LOCALE" fi echo "ro.wifi.channels=$PRODUCT_DEFAULT_WIFI_CHANNELS" @@ -46,7 +46,9 @@ echo "ro.board.platform=$TARGET_BOARD_PLATFORM" if [ "$TARGET_UNIFIED_DEVICE" == "" ] ; then echo "# ro.build.product is obsolete; use ro.product.device" echo "ro.build.product=$TARGET_DEVICE" - echo "ro.product.model=$PRODUCT_MODEL" + if [ -z "$TARGET_SKIP_PRODUCT_DEVICE" ] ; then + echo "ro.product.model=$PRODUCT_MODEL" + fi echo "ro.product.device=$TARGET_DEVICE" echo "# Do not try to parse description, fingerprint, or thumbprint" echo "ro.build.description=$PRIVATE_BUILD_DESC" diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py index b132963..51d64b8 100755 --- a/tools/releasetools/add_img_to_target_files.py +++ b/tools/releasetools/add_img_to_target_files.py @@ -47,7 +47,8 @@ OPTIONS.replace_verity_public_key = False OPTIONS.replace_verity_private_key = False OPTIONS.verity_signer_path = None -def AddSystem(output_zip, prefix="IMAGES/", recovery_img=None, boot_img=None): +def AddSystem(output_zip, prefix="IMAGES/", recovery_img=None, boot_img=None, + rebuild_recovery=OPTIONS.rebuild_recovery): """Turn the contents of SYSTEM into a system image and store it in output_zip.""" @@ -61,7 +62,7 @@ def AddSystem(output_zip, prefix="IMAGES/", recovery_img=None, boot_img=None): ofile.write(data) ofile.close() - if OPTIONS.rebuild_recovery: + if rebuild_recovery: print("Building new recovery patch") common.MakeRecoveryPatch(OPTIONS.input_tmp, output_sink, recovery_img, boot_img, info_dict=OPTIONS.info_dict) @@ -100,6 +101,29 @@ def BuildVendor(input_dir, info_dict, block_list=None): file containing it.""" return CreateImage(input_dir, info_dict, "vendor", block_list=block_list) +def AddOem(output_zip, prefix="IMAGES/"): + """Turn the contents of OEM into a oem image and store in it + output_zip.""" + + prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "oem.img") + if os.path.exists(prebuilt_path): + print("oem.img already exists in %s, no need to rebuild..." % prefix) + return + + block_list = common.MakeTempFile(prefix="oem-blocklist-", suffix=".map") + imgname = BuildOem(OPTIONS.input_tmp, OPTIONS.info_dict, + block_list=block_list) + with open(imgname, "rb") as f: + common.ZipWriteStr(output_zip, prefix + "oem.img", f.read()) + with open(block_list, "rb") as f: + common.ZipWriteStr(output_zip, prefix + "oem.map", f.read()) + + +def BuildOem(input_dir, info_dict, block_list=None): + """Build the (sparse) oem image and return the name of a temp + file containing it.""" + return CreateImage(input_dir, info_dict, "oem", block_list=block_list) + def CreateImage(input_dir, info_dict, what, block_list=None): print("creating " + what + ".img...") @@ -299,7 +323,7 @@ def AddCache(output_zip, prefix="IMAGES/"): os.rmdir(temp_dir) -def AddImagesToTargetFiles(filename): +def AddImagesToTargetFiles(filename, rebuild_recovery=OPTIONS.rebuild_recovery): OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename) if not OPTIONS.add_missing: @@ -314,6 +338,12 @@ def AddImagesToTargetFiles(filename): except KeyError: has_vendor = False + try: + input_zip.getinfo("OEM/") + has_oem = True + except KeyError: + has_oem = False + OPTIONS.info_dict = common.LoadInfoDict(input_zip) if "selinux_fc" in OPTIONS.info_dict: OPTIONS.info_dict["selinux_fc"] = os.path.join( @@ -331,7 +361,7 @@ def AddImagesToTargetFiles(filename): boot_image = None if os.path.exists(prebuilt_path): print("boot.img already exists in IMAGES/, no need to rebuild...") - if OPTIONS.rebuild_recovery: + if rebuild_recovery: boot_image = common.GetBootableImage( "IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT") else: @@ -345,7 +375,7 @@ def AddImagesToTargetFiles(filename): prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "recovery.img") if os.path.exists(prebuilt_path): print("recovery.img already exists in IMAGES/, no need to rebuild...") - if OPTIONS.rebuild_recovery: + if rebuild_recovery: recovery_image = common.GetBootableImage( "IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp, "RECOVERY") else: @@ -355,7 +385,8 @@ def AddImagesToTargetFiles(filename): recovery_image.AddToZip(output_zip) banner("system") - AddSystem(output_zip, recovery_img=recovery_image, boot_img=boot_image) + AddSystem(output_zip, recovery_img=recovery_image, boot_img=boot_image, + rebuild_recovery = rebuild_recovery) if has_vendor: banner("vendor") AddVendor(output_zip) @@ -365,6 +396,10 @@ def AddImagesToTargetFiles(filename): AddUserdataExtra(output_zip) banner("cache") AddCache(output_zip) + if has_oem: + banner("oem") + AddOem(output_zip) + common.ZipClose(output_zip) diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py index efaf7eb..d712083 100755 --- a/tools/releasetools/build_image.py +++ b/tools/releasetools/build_image.py @@ -106,15 +106,32 @@ def BuildVerityTree(sparse_image_path, verity_image_path, prop_dict): def BuildVerityMetadata(image_size, verity_metadata_path, root_hash, salt, block_device, signer_path, key): + verity_key = os.getenv("PRODUCT_VERITY_KEY", None) + verity_key_password = None + + if verity_key and os.path.exists(verity_key+".pk8"): + verity_key_passwords = {} + verity_key_passwords.update(common.PasswordManager().GetPasswords(verity_key.split())) + verity_key_password = verity_key_passwords[verity_key] + cmd_template = ( "system/extras/verity/build_verity_metadata.py %s %s %s %s %s %s %s") cmd = cmd_template % (image_size, verity_metadata_path, root_hash, salt, block_device, signer_path, key) print(cmd) - status, output = getstatusoutput(cmd) - if status: - print("Could not build verity metadata! Error: %s" % output) + runcmd = ["system/extras/verity/build_verity_metadata.py", image_size, verity_metadata_path, root_hash, salt, block_device, signer_path, key]; + if verity_key_password is not None: + sp = subprocess.Popen(runcmd, stdin=subprocess.PIPE) + sp.communicate(verity_key_password) + else: + sp = subprocess.Popen(runcmd) + + sp.wait() + + if sp.returncode != 0: + print("Could not build verity metadata!") return False + return True def Append2Simg(sparse_image_path, unsparse_image_path, error_message): diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py index 26cc674..32bbc68 100644 --- a/tools/releasetools/common.py +++ b/tools/releasetools/common.py @@ -338,6 +338,9 @@ def BuildBootableImage(sourcedir, fs_config_file, info_dict=None): ramdisk_img = tempfile.NamedTemporaryFile() img = tempfile.NamedTemporaryFile() + bootimg_key = os.getenv("PRODUCT_PRIVATE_KEY", None) + verity_key = os.getenv("PRODUCT_VERITY_KEY", None) + custom_boot_signer = os.getenv("PRODUCT_BOOT_SIGNER", None) if os.access(fs_config_file, os.F_OK): cmd = ["mkbootfs", "-f", fs_config_file, os.path.join(sourcedir, "RAMDISK")] @@ -404,8 +407,9 @@ def BuildBootableImage(sourcedir, fs_config_file, info_dict=None): fn = os.path.join(sourcedir, "pagesize") if os.access(fn, os.F_OK): + kernel_pagesize=open(fn).read().rstrip("\n") cmd.append("--pagesize") - cmd.append(open(fn).read().rstrip("\n")) + cmd.append(kernel_pagesize) args = info_dict.get("mkbootimg_args", None) if args and args.strip(): @@ -425,6 +429,50 @@ def BuildBootableImage(sourcedir, fs_config_file, info_dict=None): assert p.returncode == 0, "mkbootimg of %s image failed" % ( os.path.basename(sourcedir),) + if custom_boot_signer and bootimg_key and os.path.exists(bootimg_key): + print("Signing bootable image with custom boot signer...") + img_secure = tempfile.NamedTemporaryFile() + p = Run([custom_boot_signer, img.name, img_secure.name], stdout=subprocess.PIPE) + p.communicate() + assert p.returncode == 0, "signing of bootable image failed" + shutil.copyfile(img_secure.name, img.name) + img_secure.close() + elif bootimg_key and os.path.exists(bootimg_key) and kernel_pagesize > 0: + print("Signing bootable image...") + bootimg_key_passwords = {} + bootimg_key_passwords.update(PasswordManager().GetPasswords(bootimg_key.split())) + bootimg_key_password = bootimg_key_passwords[bootimg_key] + if bootimg_key_password is not None: + bootimg_key_password += "\n" + img_sha256 = tempfile.NamedTemporaryFile() + img_sig = tempfile.NamedTemporaryFile() + img_sig_padded = tempfile.NamedTemporaryFile() + img_secure = tempfile.NamedTemporaryFile() + p = Run(["openssl", "dgst", "-sha256", "-binary", "-out", img_sha256.name, img.name], + stdout=subprocess.PIPE) + p.communicate() + assert p.returncode == 0, "signing of bootable image failed" + p = Run(["openssl", "rsautl", "-sign", "-in", img_sha256.name, "-inkey", bootimg_key, "-out", + img_sig.name, "-passin", "stdin"], stdin=subprocess.PIPE, stdout=subprocess.PIPE) + p.communicate(bootimg_key_password) + assert p.returncode == 0, "signing of bootable image failed" + p = Run(["dd", "if=/dev/zero", "of=%s" % img_sig_padded.name, "bs=%s" % kernel_pagesize, + "count=1"], stdout=subprocess.PIPE) + p.communicate() + assert p.returncode == 0, "signing of bootable image failed" + p = Run(["dd", "if=%s" % img_sig.name, "of=%s" % img_sig_padded.name, "conv=notrunc"], + stdout=subprocess.PIPE) + p.communicate() + assert p.returncode == 0, "signing of bootable image failed" + p = Run(["cat", img.name, img_sig_padded.name], stdout=img_secure.file.fileno()) + p.communicate() + assert p.returncode == 0, "signing of bootable image failed" + shutil.copyfile(img_secure.name, img.name) + img_sha256.close() + img_sig.close() + img_sig_padded.close() + img_secure.close() + if (info_dict.get("boot_signer", None) == "true" and info_dict.get("verity_key", None)): path = "/" + os.path.basename(sourcedir).lower() @@ -433,8 +481,21 @@ def BuildBootableImage(sourcedir, fs_config_file, info_dict=None): cmd.extend([path, img.name, info_dict["verity_key"] + ".pk8", info_dict["verity_key"] + ".x509.pem", img.name]) - p = Run(cmd, stdout=subprocess.PIPE) - p.communicate() + verity_key_password = None + + if verity_key and os.path.exists(verity_key+".pk8") and kernel_pagesize > 0: + verity_key_passwords = {} + verity_key_passwords.update(PasswordManager().GetPasswords(verity_key.split())) + verity_key_password = verity_key_passwords[verity_key] + + if verity_key_password is not None: + verity_key_password += "\n" + p = Run(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) + p.communicate(verity_key_password) + else: + p = Run(cmd) + p.communicate() + assert p.returncode == 0, "boot_signer of %s image failed" % path # Sign the image if vboot is non-empty. diff --git a/tools/releasetools/img_from_target_files.py b/tools/releasetools/img_from_target_files.py index d486a7a..33375ca 100755 --- a/tools/releasetools/img_from_target_files.py +++ b/tools/releasetools/img_from_target_files.py @@ -111,6 +111,7 @@ def main(argv): if os.path.exists(images_path): # If this is a new target-files, it already contains the images, # and all we have to do is copy them to the output zip. + # Skip oem.img files since they are not needed in fastboot images. images = os.listdir(images_path) if images: for image in images: @@ -118,6 +119,8 @@ def main(argv): continue if not image.endswith(".img"): continue + if image == "oem.img": + continue common.ZipWrite( output_zip, os.path.join(images_path, image), image) done = True diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py index abdb845..54460e6 100755 --- a/tools/releasetools/sign_target_files_apks.py +++ b/tools/releasetools/sign_target_files_apks.py @@ -518,7 +518,7 @@ def main(argv): common.ZipClose(input_zip) common.ZipClose(output_zip) - add_img_to_target_files.AddImagesToTargetFiles(args[1]) + add_img_to_target_files.AddImagesToTargetFiles(args[1], rebuild_recovery=True) print("done.") diff --git a/tools/repopick.py b/tools/repopick.py index 1840a56..cfbb8a8 100755 --- a/tools/repopick.py +++ b/tools/repopick.py @@ -209,7 +209,8 @@ if __name__ == '__main__': manifest = subprocess.check_output(['repo', 'manifest']) xml_root = ElementTree.fromstring(manifest) projects = xml_root.findall('project') - default_revision = xml_root.findall('default')[0].get('revision').split('/')[-1] + remotes = xml_root.findall('remote') + default_revision = xml_root.findall('default')[0].get('revision') #dump project data into the a list of dicts with the following data: #{project: {path, revision}} @@ -219,10 +220,15 @@ if __name__ == '__main__': path = project.get('path') revision = project.get('revision') if revision is None: - revision = default_revision + for remote in remotes: + if remote.get('name') == project.get('remote'): + revision = remote.get('revision') + if revision is None: + revision = default_revision if not name in project_name_to_data: project_name_to_data[name] = {} + revision = revision.split('refs/heads/')[-1] project_name_to_data[name][revision] = path # get data on requested changes @@ -235,8 +241,14 @@ if __name__ == '__main__': reviews = fetch_query(args.gerrit, args.query) change_numbers = sorted([str(r['number']) for r in reviews]) if args.change_number: - reviews = fetch_query(args.gerrit, ' OR '.join('change:{0}'.format(x.split('/')[0]) for x in args.change_number)) - change_numbers = args.change_number + for c in args.change_number: + if '-' in c: + templist = c.split('-') + for i in range(int(templist[0]), int(templist[1]) + 1): + change_numbers.append(str(i)) + else: + change_numbers.append(c) + reviews = fetch_query(args.gerrit, ' OR '.join('change:{0}'.format(x.split('/')[0]) for x in change_numbers)) # make list of things to actually merge mergables = [] @@ -264,6 +276,7 @@ if __name__ == '__main__': 'subject': review['subject'], 'project': review['project'], 'branch': review['branch'], + 'change_id': review['change_id'], 'change_number': review['number'], 'status': review['status'], 'fetch': None @@ -306,6 +319,31 @@ if __name__ == '__main__': if args.start_branch: subprocess.check_output(['repo', 'start', args.start_branch[0], project_path]) + # Determine the maximum commits to check already picked changes + check_picked_count = 10 + branch_commits_count = int(subprocess.check_output(['git', 'rev-list', '--count', 'HEAD'], cwd=project_path)) + if branch_commits_count <= check_picked_count: + check_picked_count = branch_commits_count - 1 + + # Check if change is already picked to HEAD...HEAD~check_picked_count + found_change = False + for i in range(0, check_picked_count): + if subprocess.call(['git', 'cat-file', '-e', 'HEAD~{0}'.format(i)], cwd=project_path, stderr=open(os.devnull, 'wb')): + continue + output = subprocess.check_output(['git', 'show', '-q', 'HEAD~{0}'.format(i)], cwd=project_path).split() + if 'Change-Id:' in output: + head_change_id = '' + for j,t in enumerate(reversed(output)): + if t == 'Change-Id:': + head_change_id = output[len(output) - j] + break + if head_change_id.strip() == item['change_id']: + print('Skipping {0} - already picked in {1} as HEAD~{2}'.format(item['id'], project_path, i)) + found_change = True + break + if found_change: + continue + # Print out some useful info if not args.quiet: print('--> Subject: "{0}"'.format(item['subject'])) |