Merge "Rename otatools dependency from futility to futility-host"
diff --git a/Changes.md b/Changes.md
index 3ad2641..8979e30 100644
--- a/Changes.md
+++ b/Changes.md
@@ -860,6 +860,39 @@
the makefile system. If you need one of them, you'll have to set up your own
version.
+## Soong config variables
+
+### Soong config string variables must list all values they can be set to
+
+In order to facilitate the transition to bazel, all soong_config_string_variables
+must only be set to a value listed in their `values` property, or an empty string.
+It is a build error otherwise.
+
+Example Android.bp:
+```
+soong_config_string_variable {
+ name: "my_string_variable",
+ values: [
+ "foo",
+ "bar",
+ ],
+}
+
+soong_config_module_type {
+ name: "my_cc_defaults",
+ module_type: "cc_defaults",
+ config_namespace: "my_namespace",
+ variables: ["my_string_variable"],
+ properties: [
+ "shared_libs",
+ "static_libs",
+ ],
+}
+```
+Product config:
+```
+$(call soong_config_set,my_namespace,my_string_variable,baz) # Will be an error as baz is not listed in my_string_variable's values.
+```
[build/soong/Changes.md]: https://android.googlesource.com/platform/build/soong/+/master/Changes.md
[build/soong/docs/best_practices.md#headers]: https://android.googlesource.com/platform/build/soong/+/master/docs/best_practices.md#headers
diff --git a/OWNERS b/OWNERS
index 8a1cc34..57d8994 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,4 +1,9 @@
include platform/build/soong:/OWNERS
+# Since this file affects all Android developers, lock it down. There is still
+# round the world timzeone coverage.
+per-file envsetup.sh = joeo@google.com, jingwen@google.com, lberki@google.com
+per-file shell_utils.sh = joeo@google.com, jingwen@google.com, lberki@google.com
+
# Finalization scripts
per-file finalize* = smoreland@google.com, alexbuy@google.com
diff --git a/core/BUILD.bazel b/core/BUILD.bazel
new file mode 100644
index 0000000..3e69e62
--- /dev/null
+++ b/core/BUILD.bazel
@@ -0,0 +1,4 @@
+# Export tradefed templates for tests.
+exports_files(
+ glob(["*.xml"]),
+)
diff --git a/core/Makefile b/core/Makefile
index 0ccea68..b05a099 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -181,6 +181,7 @@
ifeq ($(HOST_OS),linux)
$(call dist-for-goals,sdk,$(API_FINGERPRINT))
+$(call dist-for-goals,droidcore,$(API_FINGERPRINT))
endif
INSTALLED_RECOVERYIMAGE_TARGET :=
@@ -306,6 +307,8 @@
# $(7): module archive
# $(8): staging dir for stripped modules
# $(9): module directory name
+# $(10): extra modules that might be dependency of modules in this partition, but should not be copied to output dir
+# $(11): mount point for extra modules
# Returns a list of src:dest pairs to install the modules using copy-many-files.
define build-image-kernel-modules
$(if $(9), \
@@ -317,7 +320,7 @@
$(eval _src := $(8)/$(notdir $(module))) \
$(eval $(call copy-and-strip-kernel-module,$(module),$(_src)))) \
$(_src):$(2)/lib/modules/$(_dir)$(notdir $(module))) \
- $(eval $(call build-image-kernel-modules-depmod,$(1),$(3),$(4),$(5),$(6),$(7),$(2),$(9))) \
+ $(eval $(call build-image-kernel-modules-depmod,$(1),$(3),$(4),$(5),$(6),$(7),$(2),$(9),$(10),$(11))) \
$(4)/$(DEPMOD_STAGING_SUBDIR)/modules.dep:$(2)/lib/modules/$(_dir)modules.dep \
$(4)/$(DEPMOD_STAGING_SUBDIR)/modules.alias:$(2)/lib/modules/$(_dir)modules.alias \
$(4)/$(DEPMOD_STAGING_SUBDIR)/modules.softdep:$(2)/lib/modules/$(_dir)modules.softdep \
@@ -332,6 +335,8 @@
# $(6): module archive
# $(7): output dir
# $(8): module directory name
+# $(9): extra modules which should not be copied to output dir, but might be dependency of modules in this partition
+# $(10): mount point for extra modules
# TODO(b/144844424): If a module archive is being used, this step (which
# generates obj/PACKAGING/.../modules.dep) also unzips the module archive into
# the output directory. This should be moved to a module with a
@@ -341,8 +346,11 @@
$(3)/$(DEPMOD_STAGING_SUBDIR)/modules.dep: .KATI_IMPLICIT_OUTPUTS := $(3)/$(DEPMOD_STAGING_SUBDIR)/modules.alias $(3)/$(DEPMOD_STAGING_SUBDIR)/modules.softdep $(3)/$(DEPMOD_STAGING_SUBDIR)/$(5)
$(3)/$(DEPMOD_STAGING_SUBDIR)/modules.dep: $(DEPMOD)
$(3)/$(DEPMOD_STAGING_SUBDIR)/modules.dep: PRIVATE_MODULES := $(strip $(1))
+$(3)/$(DEPMOD_STAGING_SUBDIR)/modules.dep: PRIVATE_EXTRA_MODULES := $(strip $(9))
$(3)/$(DEPMOD_STAGING_SUBDIR)/modules.dep: PRIVATE_MOUNT_POINT := $(2)
+$(3)/$(DEPMOD_STAGING_SUBDIR)/modules.dep: PRIVATE_EXTRA_MOUNT_POINT := $(10)
$(3)/$(DEPMOD_STAGING_SUBDIR)/modules.dep: PRIVATE_MODULE_DIR := $(3)/$(DEPMOD_STAGING_SUBDIR)/$(2)/lib/modules/$(8)
+$(3)/$(DEPMOD_STAGING_SUBDIR)/modules.dep: PRIVATE_EXTRA_MODULE_DIR := $(3)/$(DEPMOD_STAGING_SUBDIR)/$(10)/lib/modules/$(8)
$(3)/$(DEPMOD_STAGING_SUBDIR)/modules.dep: PRIVATE_STAGING_DIR := $(3)
$(3)/$(DEPMOD_STAGING_SUBDIR)/modules.dep: PRIVATE_LOAD_MODULES := $(strip $(4))
$(3)/$(DEPMOD_STAGING_SUBDIR)/modules.dep: PRIVATE_LOAD_FILE := $(3)/$(DEPMOD_STAGING_SUBDIR)/$(5)
@@ -364,6 +372,20 @@
basename $$$$MODULE >> $$(PRIVATE_LOAD_FILE); \
done; \
)
+ # The ln -sf + find -delete sequence is to remove any modules in
+ # PRIVATE_EXTRA_MODULES which have same basename as MODULES in PRIVATE_MODULES
+ # Basically, it computes a set difference. When there is a duplicate module
+ # present in both directories, we want modules in PRIVATE_MODULES to take
+ # precedence. Since depmod does not provide any guarantee about ordering of
+ # dependency resolution, we achieve this by maually removing any duplicate
+ # modules with lower priority.
+ $(if $(9),\
+ mkdir -p $$(PRIVATE_EXTRA_MODULE_DIR); \
+ find $$(PRIVATE_EXTRA_MODULE_DIR) -maxdepth 1 -type f -name "*.ko" -delete; \
+ cp $$(PRIVATE_EXTRA_MODULES) $$(PRIVATE_EXTRA_MODULE_DIR); \
+ ln -sf $$(PRIVATE_MODULE_DIR)/*.ko $$(PRIVATE_EXTRA_MODULE_DIR); \
+ find $$(PRIVATE_EXTRA_MODULE_DIR) -type l -delete; \
+ )
$(DEPMOD) -b $$(PRIVATE_STAGING_DIR) 0.0
# Turn paths in modules.dep into absolute paths
sed -i.tmp -e 's|\([^: ]*lib/modules/[^: ]*\)|/\1|g' $$(PRIVATE_STAGING_DIR)/$$(DEPMOD_STAGING_SUBDIR)/modules.dep
@@ -437,6 +459,9 @@
# $(4): module load filename
# $(5): stripped staging directory
# $(6): kernel module directory name (top is an out of band value for no directory)
+# $(7): list of extra modules that might be dependency of modules in this partition
+# $(8): mount point for extra modules. e.g. system
+
define build-image-kernel-modules-dir
$(if $(filter top,$(6)),\
$(eval _kver :=)$(eval _sep :=),\
@@ -447,7 +472,9 @@
$(if $(strip $(BOARD_$(1)_KERNEL_MODULES$(_sep)$(_kver))$(BOARD_$(1)_KERNEL_MODULES_ARCHIVE$(_sep)$(_kver))),\
$(if $(BOARD_$(1)_KERNEL_MODULES_LOAD$(_sep)$(_kver)),,\
$(eval BOARD_$(1)_KERNEL_MODULES_LOAD$(_sep)$(_kver) := $(BOARD_$(1)_KERNEL_MODULES$(_sep)$(_kver)))) \
- $(call copy-many-files,$(call build-image-kernel-modules,$(BOARD_$(1)_KERNEL_MODULES$(_sep)$(_kver)),$(2),$(3),$(call intermediates-dir-for,PACKAGING,depmod_$(1)$(_sep)$(_kver)),$(BOARD_$(1)_KERNEL_MODULES_LOAD$(_sep)$(_kver)),$(4),$(BOARD_$(1)_KERNEL_MODULES_ARCHIVE$(_sep)$(_kver)),$(_stripped_staging_dir),$(_kver)))) \
+ $(if $(filter false,$(BOARD_$(1)_KERNEL_MODULES_LOAD$(_sep)$(_kver))),\
+ $(eval BOARD_$(1)_KERNEL_MODULES_LOAD$(_sep)$(_kver) :=),) \
+ $(call copy-many-files,$(call build-image-kernel-modules,$(BOARD_$(1)_KERNEL_MODULES$(_sep)$(_kver)),$(2),$(3),$(call intermediates-dir-for,PACKAGING,depmod_$(1)$(_sep)$(_kver)),$(BOARD_$(1)_KERNEL_MODULES_LOAD$(_sep)$(_kver)),$(4),$(BOARD_$(1)_KERNEL_MODULES_ARCHIVE$(_sep)$(_kver)),$(_stripped_staging_dir),$(_kver),$(7),$(8)))) \
$(if $(_kver), \
$(eval _dir := $(_kver)/), \
$(eval _dir :=)) \
@@ -482,6 +509,15 @@
endef
# $(1): kernel module directory name (top is an out of band value for no directory)
+define build-vendor-kernel-ramdisk-recovery-load
+$(if $(filter top,$(1)),\
+ $(eval _kver :=)$(eval _sep :=),\
+ $(eval _kver := $(1))$(eval _sep :=_))\
+ $(if $(BOARD_VENDOR_KERNEL_RAMDISK_RECOVERY_KERNEL_MODULES_LOAD$(_sep)$(_kver)),\
+ $(call copy-many-files,$(call module-load-list-copy-paths,$(call intermediates-dir-for,PACKAGING,vendor_kernel_ramdisk_recovery_module_list$(_sep)$(_kver)),$(BOARD_VENDOR_KERNEL_RAMDISK_KERNEL_MODULES$(_sep)$(_kver)),$(BOARD_VENDOR_KERNEL_RAMDISK_RECOVERY_KERNEL_MODULES_LOAD$(_sep)$(_kver)),modules.load.recovery,$(TARGET_VENDOR_KERNEL_RAMDISK_OUT))))
+endef
+
+# $(1): kernel module directory name (top is an out of band value for no directory)
define build-vendor-charger-load
$(if $(filter top,$(1)),\
$(eval _kver :=)$(eval _sep :=),\
@@ -532,6 +568,14 @@
endif
BOARD_KERNEL_MODULE_DIRS += top
+
+# Default to not generating modules.dep for kernel modules on system
+# side. We should only load these modules if they are depended by vendor
+# side modules.
+ifeq ($(BOARD_SYSTEM_KERNEL_MODULES_LOAD),)
+ BOARD_SYSTEM_KERNEL_MODULES_LOAD := false
+endif
+
$(foreach kmd,$(BOARD_KERNEL_MODULE_DIRS), \
$(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,RECOVERY,$(TARGET_RECOVERY_ROOT_OUT),,modules.load.recovery,$(RECOVERY_STRIPPED_MODULE_STAGING_DIR),$(kmd))) \
$(eval vendor_ramdisk_fragment := $(KERNEL_MODULE_DIR_VENDOR_RAMDISK_FRAGMENT_$(kmd))) \
@@ -544,13 +588,28 @@
$(eval $(result_var) += $(call build-image-kernel-modules-dir,VENDOR_RAMDISK,$(output_dir),,modules.load,$(VENDOR_RAMDISK_STRIPPED_MODULE_STAGING_DIR),$(kmd))) \
$(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,VENDOR_KERNEL_RAMDISK,$(TARGET_VENDOR_KERNEL_RAMDISK_OUT),,modules.load,$(VENDOR_KERNEL_RAMDISK_STRIPPED_MODULE_STAGING_DIR),$(kmd))) \
$(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-vendor-ramdisk-recovery-load,$(kmd))) \
- $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,VENDOR,$(if $(filter true,$(BOARD_USES_VENDOR_DLKMIMAGE)),$(TARGET_OUT_VENDOR_DLKM),$(TARGET_OUT_VENDOR)),vendor,modules.load,$(VENDOR_STRIPPED_MODULE_STAGING_DIR),$(kmd))) \
+ $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-vendor-kernel-ramdisk-recovery-load,$(kmd))) \
+ $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,VENDOR,$(if $(filter true,$(BOARD_USES_VENDOR_DLKMIMAGE)),$(TARGET_OUT_VENDOR_DLKM),$(TARGET_OUT_VENDOR)),vendor,modules.load,$(VENDOR_STRIPPED_MODULE_STAGING_DIR),$(kmd),$(BOARD_SYSTEM_KERNEL_MODULES),system)) \
$(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-vendor-charger-load,$(kmd))) \
$(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,ODM,$(if $(filter true,$(BOARD_USES_ODM_DLKMIMAGE)),$(TARGET_OUT_ODM_DLKM),$(TARGET_OUT_ODM)),odm,modules.load,,$(kmd))) \
+ $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,SYSTEM,$(if $(filter true,$(BOARD_USES_SYSTEM_DLKMIMAGE)),$(TARGET_OUT_SYSTEM_DLKM),$(TARGET_OUT_SYSTEM)),system,modules.load,,$(kmd))) \
$(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),\
$(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-recovery-as-boot-load,$(kmd))),\
$(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,GENERIC_RAMDISK,$(TARGET_RAMDISK_OUT),,modules.load,,$(kmd)))))
+ifeq ($(BOARD_SYSTEM_KERNEL_MODULES),)
+ifneq ($(BOARD_SYSTEM_DLKM_SRC),)
+ifneq ($(wildcard $(BOARD_SYSTEM_DLKM_SRC)/*),)
+ SYSTEM_KERNEL_MODULES := $(shell find $(BOARD_SYSTEM_DLKM_SRC) -type f)
+ SRC_SYSTEM_KERNEL_MODULES := $(SYSTEM_KERNEL_MODULES)
+ DST_SYSTEM_KERNEL_MODULES := $(patsubst $(BOARD_SYSTEM_DLKM_SRC)/%,:$(TARGET_OUT_SYSTEM_DLKM)/%,$(SRC_SYSTEM_KERNEL_MODULES))
+ SYSTEM_KERNEL_MODULE_COPY_PAIRS := $(join $(SRC_SYSTEM_KERNEL_MODULES),$(DST_SYSTEM_KERNEL_MODULES))
+ ALL_DEFAULT_INSTALLED_MODULES += $(call copy-many-files,$(SYSTEM_KERNEL_MODULE_COPY_PAIRS))
+endif
+endif
+endif
+
+
# -----------------------------------------------------------------
# Cert-to-package mapping. Used by the post-build signing tools.
# Use a macro to add newline to each echo command
@@ -705,12 +764,6 @@
$(call dist-for-goals,droidcore-unbundled,$(WALL_WERROR))
# -----------------------------------------------------------------
-# C/C++ flag information for modules
-$(call dist-for-goals,droidcore-unbundled,$(SOONG_MODULES_CFLAG_ARTIFACTS))
-
-$(foreach a,$(SOONG_MODULES_CFLAG_ARTIFACTS),$(call declare-0p-target,$(call word-colon,1,$(a))))
-
-# -----------------------------------------------------------------
# Modules missing profile files
PGO_PROFILE_MISSING := $(PRODUCT_OUT)/pgo_profile_file_missing.txt
$(PGO_PROFILE_MISSING):
@@ -889,16 +942,19 @@
RAMDISK_EXT := .gz
endif
+# This file contains /dev nodes description added to the generic ramdisk
+RAMDISK_NODE_LIST := $(PRODUCT_OUT)/ramdisk_node_list
+
# We just build this directly to the install location.
INSTALLED_RAMDISK_TARGET := $(BUILT_RAMDISK_TARGET)
$(INSTALLED_RAMDISK_TARGET): PRIVATE_DIRS := debug_ramdisk dev metadata mnt proc second_stage_resources sys
-$(INSTALLED_RAMDISK_TARGET): $(MKBOOTFS) $(INTERNAL_RAMDISK_FILES) $(INSTALLED_FILES_FILE_RAMDISK) | $(COMPRESSION_COMMAND_DEPS)
+$(INSTALLED_RAMDISK_TARGET): $(MKBOOTFS) $(RAMDISK_NODE_LIST) $(INTERNAL_RAMDISK_FILES) $(INSTALLED_FILES_FILE_RAMDISK) | $(COMPRESSION_COMMAND_DEPS)
$(call pretty,"Target ramdisk: $@")
$(hide) mkdir -p $(addprefix $(TARGET_RAMDISK_OUT)/,$(PRIVATE_DIRS))
ifeq (true,$(BOARD_USES_GENERIC_KERNEL_IMAGE))
$(hide) mkdir -p $(addprefix $(TARGET_RAMDISK_OUT)/first_stage_ramdisk/,$(PRIVATE_DIRS))
endif
- $(hide) $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_RAMDISK_OUT) | $(COMPRESSION_COMMAND) > $@
+ $(hide) $(MKBOOTFS) -n $(RAMDISK_NODE_LIST) -d $(TARGET_OUT) $(TARGET_RAMDISK_OUT) | $(COMPRESSION_COMMAND) > $@
$(call declare-1p-container,$(INSTALLED_RAMDISK_TARGET),)
$(call declare-container-license-deps,$(INSTALLED_RAMDISK_TARGET),$(INTERNAL_RAMDISK_FILE),$(PRODUCT_OUT)/:/)
@@ -1233,7 +1289,7 @@
$(AVBTOOL) add_hash_footer \
--image $@ \
$(call get-partition-size-argument,$(BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE)) \
- --partition_name boot $(INTERNAL_AVB_INIT_BOOT_SIGNING_ARGS) \
+ --partition_name init_boot $(INTERNAL_AVB_INIT_BOOT_SIGNING_ARGS) \
$(BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS)
$(call declare-1p-container,$(INSTALLED_INIT_BOOT_IMAGE_TARGET),)
@@ -2949,6 +3005,8 @@
$(ALL_DEFAULT_INSTALLED_MODULES)))
define fsverity-generate-metadata
+$(call declare-0p-target,$(1).fsv_meta)
+
$(1).fsv_meta: PRIVATE_SRC := $(1)
$(1).fsv_meta: PRIVATE_FSVERITY := $(HOST_OUT_EXECUTABLES)/fsverity
$(1).fsv_meta: $(HOST_OUT_EXECUTABLES)/fsverity_metadata_generator $(HOST_OUT_EXECUTABLES)/fsverity $(1)
@@ -2987,12 +3045,10 @@
$$(fsverity-metadata-targets-$(2))
rm -rf $$(PRIVATE_ASSETS)
mkdir -p $$(PRIVATE_ASSETS)
-ifdef fsverity-metadata-targets-$(2)
$$< --fsverity-path $$(PRIVATE_FSVERITY) \
--base-dir $$(PRODUCT_OUT) \
--output $$(PRIVATE_ASSETS)/build_manifest.pb \
$$(PRIVATE_INPUTS)
-endif # fsverity-metadata-targets-$(2)
$$(PRIVATE_AAPT2) link -o $$@ \
-A $$(PRIVATE_ASSETS) \
-I $$(PRIVATE_FRAMEWORK_RES) \
@@ -3071,12 +3127,15 @@
# Install system linker configuration
# Collect all available stub libraries installed in system and install with predefined linker configuration
+# Also append LLNDK libraries in the APEX as required libs
SYSTEM_LINKER_CONFIG := $(TARGET_OUT)/etc/linker.config.pb
SYSTEM_LINKER_CONFIG_SOURCE := $(call intermediates-dir-for,ETC,system_linker_config)/system_linker_config
$(SYSTEM_LINKER_CONFIG): PRIVATE_SYSTEM_LINKER_CONFIG_SOURCE := $(SYSTEM_LINKER_CONFIG_SOURCE)
$(SYSTEM_LINKER_CONFIG) : $(INTERNAL_SYSTEMIMAGE_FILES) $(SYSTEM_LINKER_CONFIG_SOURCE) | conv_linker_config
$(HOST_OUT_EXECUTABLES)/conv_linker_config systemprovide --source $(PRIVATE_SYSTEM_LINKER_CONFIG_SOURCE) \
--output $@ --value "$(STUB_LIBRARIES)" --system "$(TARGET_OUT)"
+ $(HOST_OUT_EXECUTABLES)/conv_linker_config append --source $@ --output $@ --key requireLibs \
+ --value "$(foreach lib,$(LLNDK_MOVED_TO_APEX_LIBRARIES), $(lib).so)"
$(call declare-1p-target,$(SYSTEM_LINKER_CONFIG),)
$(call declare-license-deps,$(SYSTEM_LINKER_CONFIG),$(INTERNAL_SYSTEMIMAGE_FILES) $(SYSTEM_LINKER_CONFIG_SOURCE))
@@ -3454,6 +3513,18 @@
INTERNAL_VENDORIMAGE_FILES += $(call create-partition-compat-symlink,$(TARGET_OUT_VENDOR)/lib/modules,/vendor_dlkm/lib/modules,vendor_dlkm.img)
endif
+# Install vendor/etc/linker.config.pb when PRODUCT_VENDOR_LINKER_CONFIG_FRAGMENTS is set
+ifneq ($(strip $(PRODUCT_VENDOR_LINKER_CONFIG_FRAGMENTS)),)
+vendor_linker_config_file := $(TARGET_OUT_VENDOR)/etc/linker.config.pb
+$(vendor_linker_config_file): private_linker_config_fragments := $(PRODUCT_VENDOR_LINKER_CONFIG_FRAGMENTS)
+$(vendor_linker_config_file): $(PRODUCT_VENDOR_LINKER_CONFIG_FRAGMENTS) | $(HOST_OUT_EXECUTABLES)/conv_linker_config
+ $(HOST_OUT_EXECUTABLES)/conv_linker_config proto \
+ --source $(call normalize-path-list,$(private_linker_config_fragments)) \
+ --output $@
+$(call define declare-0p-target,$(vendor_linker_config_file),)
+INTERNAL_VENDORIMAGE_FILES += $(vendor_linker_config_file)
+endif
+
INSTALLED_FILES_FILE_VENDOR := $(PRODUCT_OUT)/installed-files-vendor.txt
INSTALLED_FILES_JSON_VENDOR := $(INSTALLED_FILES_FILE_VENDOR:.txt=.json)
$(INSTALLED_FILES_FILE_VENDOR): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_VENDOR)
@@ -3850,7 +3921,6 @@
$(INSTALLED_FILES_FILE_SYSTEM_DLKM): $(INTERNAL_SYSTEM_DLKMIMAGE_FILES) $(FILESLIST) $(FILESLIST_UTIL)
@echo Installed file list: $@
mkdir -p $(dir $@)
- if [ -d "$(BOARD_SYSTEM_DLKM_SRC)" ]; then rsync -rupE $(BOARD_SYSTEM_DLKM_SRC)/ $(TARGET_OUT_SYSTEM_DLKM); fi
rm -f $@
$(FILESLIST) $(TARGET_OUT_SYSTEM_DLKM) > $(@:.txt=.json)
$(FILESLIST_UTIL) -c $(@:.txt=.json) > $@
@@ -3932,14 +4002,19 @@
INSTALLED_PVMFWIMAGE_TARGET := $(PRODUCT_OUT)/pvmfw.img
INSTALLED_PVMFW_EMBEDDED_AVBKEY_TARGET := $(PRODUCT_OUT)/pvmfw_embedded.avbpubkey
+INSTALLED_PVMFW_BINARY_TARGET := $(call module-installed-files,pvmfw_bin)
INTERNAL_PVMFWIMAGE_FILES := $(call module-target-built-files,pvmfw_img)
-INTERNAL_PVMFW_EMBEDDED_AVBKEY := $(call module-target-built-files,pvmfw_sign_key)
+INTERNAL_PVMFW_EMBEDDED_AVBKEY := $(call module-target-built-files,pvmfw_embedded_key)
+INTERNAL_PVMFW_SYMBOL := $(TARGET_OUT_EXECUTABLES_UNSTRIPPED)/pvmfw
$(call declare-1p-container,$(INSTALLED_PVMFWIMAGE_TARGET),)
$(call declare-container-license-deps,$(INSTALLED_PVMFWIMAGE_TARGET),$(INTERNAL_PVMFWIMAGE_FILES),$(PRODUCT_OUT)/:/)
UNMOUNTED_NOTICE_VENDOR_DEPS += $(INSTALLED_PVMFWIMAGE_TARGET)
+# Place the unstripped pvmfw image to the symbols directory
+$(INTERNAL_PVMFWIMAGE_FILES): |$(INTERNAL_PVMFW_SYMBOL)
+
$(eval $(call copy-one-file,$(INTERNAL_PVMFWIMAGE_FILES),$(INSTALLED_PVMFWIMAGE_TARGET)))
$(INSTALLED_PVMFWIMAGE_TARGET): $(INSTALLED_PVMFW_EMBEDDED_AVBKEY_TARGET)
@@ -4036,7 +4111,8 @@
INTERNAL_AVB_PARTITIONS_IN_CHAINED_VBMETA_IMAGES := \
$(BOARD_AVB_VBMETA_SYSTEM) \
- $(BOARD_AVB_VBMETA_VENDOR)
+ $(BOARD_AVB_VBMETA_VENDOR) \
+ $(foreach partition,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS),$(BOARD_AVB_VBMETA_$(call to-upper,$(partition))))
# Not allowing the same partition to appear in multiple groups.
ifneq ($(words $(sort $(INTERNAL_AVB_PARTITIONS_IN_CHAINED_VBMETA_IMAGES))),$(words $(INTERNAL_AVB_PARTITIONS_IN_CHAINED_VBMETA_IMAGES)))
@@ -4342,6 +4418,11 @@
$(eval $(call check-and-set-avb-args,vbmeta_vendor))
endif
+ifdef BOARD_AVB_VBMETA_CUSTOM_PARTITIONS
+$(foreach partition,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS),$(eval $(call check-and-set-avb-args,vbmeta_$(partition))))
+$(foreach partition,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS),$(eval BOARD_AVB_MAKE_VBMETA_$(call to-upper,$(partition))_IMAGE_ARGS += --padding_size 4096))
+endif
+
ifneq ($(strip $(BOARD_CUSTOMIMAGES_PARTITION_LIST)),)
$(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
$(eval $(call check-and-set-custom-avb-chain-args,$(partition))))
@@ -4370,6 +4451,13 @@
--rollback_index $(BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX)
endif
+ifdef BOARD_AVB_VBMETA_CUSTOM_PARTITIONS
+ $(foreach partition,$(call to-upper,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS)), \
+ $(if $(BOARD_AVB_VBMETA_$(partition)_ROLLBACK_INDEX),$(eval \
+ BOARD_AVB_MAKE_VBMETA_$(partition)_IMAGE_ARGS += \
+ --rollback_index $(BOARD_AVB_VBMETA_$(partition)_ROLLBACK_INDEX))))
+endif
+
# $(1): the directory to extract public keys to
define extract-avb-chain-public-keys
$(if $(BOARD_AVB_BOOT_KEY_PATH),\
@@ -4426,7 +4514,11 @@
$(if $(BOARD_CUSTOMIMAGES_PARTITION_LIST),\
$(hide) $(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
$(AVBTOOL) extract_public_key --key $(BOARD_AVB_$(call to-upper,$(partition))_KEY_PATH) \
- --output $(1)/$(partition).avbpubkey;))
+ --output $(1)/$(partition).avbpubkey;)) \
+ $(if $(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS),\
+ $(hide) $(foreach partition,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS), \
+ $(AVBTOOL) extract_public_key --key $(BOARD_AVB_VBMETA_$(call to-upper,$(partition))_KEY_PATH) \
+ --output $(1)/vbmeta_$(partition).avbpubkey;))
endef
# Builds a chained VBMeta image. This VBMeta image will contain the descriptors for the partitions
@@ -4438,13 +4530,13 @@
# $(1): VBMeta image name, such as "vbmeta_system", "vbmeta_vendor" etc.
# $(2): Output filename.
define build-chained-vbmeta-image
- $(call pretty,"Target chained vbmeta image: $@")
- $(hide) $(AVBTOOL) make_vbmeta_image \
- $(INTERNAL_AVB_$(call to-upper,$(1))_SIGNING_ARGS) \
- $(BOARD_AVB_MAKE_$(call to-upper,$(1))_IMAGE_ARGS) \
- $(foreach image,$(BOARD_AVB_$(call to-upper,$(1))), \
- --include_descriptors_from_image $(call images-for-partitions,$(image))) \
- --output $@
+ $(call pretty,"Target chained vbmeta image: $@")
+ $(hide) $(AVBTOOL) make_vbmeta_image \
+ $(INTERNAL_AVB_$(call to-upper,$(1))_SIGNING_ARGS) \
+ $(BOARD_AVB_MAKE_$(call to-upper,$(1))_IMAGE_ARGS) \
+ $(foreach image,$(BOARD_AVB_$(call to-upper,$(1))), \
+ --include_descriptors_from_image $(call images-for-partitions,$(image))) \
+ --output $@
endef
ifdef BUILDING_SYSTEM_IMAGE
@@ -4472,7 +4564,26 @@
$(call declare-1p-container,$(INSTALLED_VBMETA_VENDORIMAGE_TARGET),)
-UNMOUNTED_NOTICE_VENDOR_DEPS+= $(INSTALLED_VBMETA_VENDORIMAGE_TARGET)
+UNMOUNTED_NOTICE_VENDOR_DEPS += $(INSTALLED_VBMETA_VENDORIMAGE_TARGET)
+endif
+
+ifdef BOARD_AVB_VBMETA_CUSTOM_PARTITIONS
+define declare-custom-vbmeta-target
+INSTALLED_VBMETA_$(call to-upper,$(1))IMAGE_TARGET := $(PRODUCT_OUT)/vbmeta_$(call to-lower,$(1)).img
+$$(INSTALLED_VBMETA_$(call to-upper,$(1))IMAGE_TARGET): \
+ $(AVBTOOL) \
+ $(call images-for-partitions,$(BOARD_AVB_VBMETA_$(call to-upper,$(1)))) \
+ $(BOARD_AVB_VBMETA_$(call to-upper,$(1))_KEY_PATH)
+ $$(call build-chained-vbmeta-image,vbmeta_$(call to-lower,$(1)))
+
+$(call declare-1p-container,$(INSTALLED_VBMETA_$(call to-upper,$(1))IMAGE_TARGET),)
+
+UNMOUNTED_NOTICE_VENDOR_DEPS += $(INSTALLED_VBMETA_$(call to-upper,$(1))IMAGE_TARGET)
+endef
+
+$(foreach partition,\
+ $(call to-upper,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS)),\
+ $(eval $(call declare-custom-vbmeta-target,$(partition))))
endif
define build-vbmetaimage-target
@@ -4492,6 +4603,7 @@
$(INSTALLED_VBMETAIMAGE_TARGET): PRIVATE_AVB_VBMETA_SIGNING_ARGS := \
--algorithm $(BOARD_AVB_ALGORITHM) --key $(BOARD_AVB_KEY_PATH)
+
$(INSTALLED_VBMETAIMAGE_TARGET): \
$(AVBTOOL) \
$(INSTALLED_BOOTIMAGE_TARGET) \
@@ -4512,8 +4624,10 @@
$(INSTALLED_RECOVERYIMAGE_TARGET) \
$(INSTALLED_VBMETA_SYSTEMIMAGE_TARGET) \
$(INSTALLED_VBMETA_VENDORIMAGE_TARGET) \
+ $(foreach partition,$(call to-upper,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS)),$(INSTALLED_VBMETA_$(partition)IMAGE_TARGET)) \
$(BOARD_AVB_VBMETA_SYSTEM_KEY_PATH) \
$(BOARD_AVB_VBMETA_VENDOR_KEY_PATH) \
+ $(foreach partition,$(call to-upper,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS)),$(BOARD_AVB_VBMETA_$(partition)_KEY_PATH)) \
$(BOARD_AVB_KEY_PATH)
$(build-vbmetaimage-target)
@@ -4542,6 +4656,7 @@
$(INTERNAL_VENDOR_DLKMIMAGE_FILES) \
$(INTERNAL_ODM_DLKMIMAGE_FILES) \
$(INTERNAL_SYSTEM_DLKMIMAGE_FILES) \
+ $(INTERNAL_PVMFWIMAGE_FILES) \
# -----------------------------------------------------------------
# Check VINTF of build
@@ -4554,35 +4669,39 @@
APEX_OUT := $(PRODUCT_OUT)/apex
# -----------------------------------------------------------------
-# Create apex-info-file.xsd
+# Create apex-info-file.xml
-APEX_DIRS := \
+apex_dirs := \
$(TARGET_OUT)/apex/% \
$(TARGET_OUT_SYSTEM_EXT)/apex/% \
$(TARGET_OUT_VENDOR)/apex/% \
$(TARGET_OUT_ODM)/apex/% \
$(TARGET_OUT_PRODUCT)/apex/% \
-apex_vintf_files := $(sort $(filter $(APEX_DIRS), $(INTERNAL_ALLIMAGES_FILES)))
-APEX_INFO_FILE := $(APEX_OUT)/apex-info-list.xml
+apex_files := $(sort $(filter $(apex_dirs), $(INTERNAL_ALLIMAGES_FILES)))
+APEX_INFO_FILE := $(APEX_OUT)/apex-info-list.xml
-$(APEX_INFO_FILE): $(HOST_OUT_EXECUTABLES)/dump_apex_info $(apex_vintf_files)
+# dump_apex_info scans $(PRODUCT_OUT)/apex and writes apex-info-list.xml there.
+# This relies on the fact that rules for .apex files install the contents in $(PRODUCT_OUT)/apex.
+$(APEX_INFO_FILE): $(HOST_OUT_EXECUTABLES)/dump_apex_info $(apex_files)
@echo "Creating apex-info-file in $(PRODUCT_OUT) "
- $< --root_dir $(PRODUCT_OUT) --out_file $@
+ $< --root_dir $(PRODUCT_OUT)
-apex_vintf_files :=
+apex_files :=
+apex_dirs :=
# The build system only writes VINTF metadata to */etc/vintf paths. Legacy paths aren't needed here
# because they are only used for prebuilt images.
+# APEX files in /vendor/apex can have VINTF fragments as well.
check_vintf_common_srcs_patterns := \
$(TARGET_OUT)/etc/vintf/% \
$(TARGET_OUT_VENDOR)/etc/vintf/% \
$(TARGET_OUT_ODM)/etc/vintf/% \
$(TARGET_OUT_PRODUCT)/etc/vintf/% \
$(TARGET_OUT_SYSTEM_EXT)/etc/vintf/% \
+ $(TARGET_OUT_VENDOR)/apex/% \
check_vintf_common_srcs := $(sort $(filter $(check_vintf_common_srcs_patterns),$(INTERNAL_ALLIMAGES_FILES)))
-check_vintf_common_srcs += $(APEX_INFO_FILE)
check_vintf_common_srcs_patterns :=
check_vintf_has_system :=
@@ -4623,7 +4742,8 @@
# -- Check vendor manifest / matrix including fragments (excluding other device manifests / matrices)
check_vintf_vendor_deps := $(filter $(TARGET_OUT_VENDOR)/etc/vintf/%, $(check_vintf_common_srcs))
-ifneq ($(check_vintf_vendor_deps),)
+check_vintf_vendor_deps += $(filter $(TARGET_OUT_VENDOR)/apex/%, $(check_vintf_common_srcs))
+ifneq ($(strip $(check_vintf_vendor_deps)),)
check_vintf_has_vendor := true
check_vintf_vendor_log := $(intermediates)/check_vintf_vendor.log
check_vintf_all_deps += $(check_vintf_vendor_log)
@@ -4634,9 +4754,9 @@
$(if $(DEVICE_MANIFEST_FILE),EMPTY_VENDOR_SKU_PLACEHOLDER,\
$(if $(DEVICE_MANIFEST_SKUS),,EMPTY_VENDOR_SKU_PLACEHOLDER)) \
$(DEVICE_MANIFEST_SKUS)
-$(check_vintf_vendor_log): $(HOST_OUT_EXECUTABLES)/checkvintf $(check_vintf_vendor_deps)
+$(check_vintf_vendor_log): $(HOST_OUT_EXECUTABLES)/checkvintf $(check_vintf_vendor_deps) $(APEX_INFO_FILE)
$(foreach vendor_sku,$(PRIVATE_VENDOR_SKUS), \
- ( $< --check-one --dirmap /vendor:$(TARGET_OUT_VENDOR) \
+ ( $< --check-one --dirmap /vendor:$(TARGET_OUT_VENDOR) --dirmap /apex:$(APEX_OUT) \
--property ro.boot.product.vendor.sku=$(filter-out EMPTY_VENDOR_SKU_PLACEHOLDER,$(vendor_sku)) \
> $@ 2>&1 ) || ( cat $@ && exit 1 ); )
$(call declare-0p-target,$(check_vintf_vendor_log))
@@ -4750,7 +4870,7 @@
check_vintf_all_deps += $(check_vintf_compatible_log)
check_vintf_compatible_args :=
-check_vintf_compatible_deps := $(check_vintf_common_srcs)
+check_vintf_compatible_deps := $(check_vintf_common_srcs) $(APEX_INFO_FILE)
ifeq ($(PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS),true)
ifneq (,$(BUILT_KERNEL_VERSION_FILE)$(BUILT_KERNEL_CONFIGS_FILE))
@@ -4770,7 +4890,6 @@
ifdef PRODUCT_SHIPPING_API_LEVEL
check_vintf_compatible_args += --property ro.product.first_api_level=$(PRODUCT_SHIPPING_API_LEVEL)
endif # PRODUCT_SHIPPING_API_LEVEL
-check_vintf_compatible_args += --apex-info-file $(APEX_INFO_FILE)
$(check_vintf_compatible_log): PRIVATE_CHECK_VINTF_ARGS := $(check_vintf_compatible_args)
$(check_vintf_compatible_log): PRIVATE_CHECK_VINTF_DEPS := $(check_vintf_compatible_deps)
@@ -4968,6 +5087,7 @@
img2simg \
img_from_target_files \
imgdiff \
+ initrd_bootconfig \
libconscrypt_openjdk_jni \
lpmake \
lpunpack \
@@ -5013,9 +5133,11 @@
INTERNAL_OTATOOLS_MODULES += \
apexer \
apex_compression_tool \
+ blkid_static \
deapexer \
debugfs_static \
dump_apex_info \
+ fsck.erofs \
merge_zips \
resize2fs \
soong_zip \
@@ -5045,6 +5167,12 @@
$(sort $(shell find build/make/target/product/security -type f -name "*.x509.pem" -o \
-name "*.pk8"))
+ifneq (,$(wildcard packages/modules))
+INTERNAL_OTATOOLS_PACKAGE_FILES += \
+ $(sort $(shell find packages/modules -type f -name "*.x509.pem" -o -name "*.pk8" -o -name \
+ "key.pem"))
+endif
+
ifneq (,$(wildcard device))
INTERNAL_OTATOOLS_PACKAGE_FILES += \
$(sort $(shell find device $(wildcard vendor) -type f -name "*.pk8" -o -name "verifiedboot*" -o \
@@ -5252,6 +5380,15 @@
$(hide) echo "avb_vbmeta_vendor_algorithm=$(BOARD_AVB_VBMETA_VENDOR_ALGORITHM)" >> $@
$(hide) echo "avb_vbmeta_vendor_rollback_index_location=$(BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX_LOCATION)" >> $@
endif # BOARD_AVB_VBMETA_VENDOR_KEY_PATH
+ifneq (,$(strip $(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS)))
+ $(hide) echo "avb_custom_vbmeta_images_partition_list=$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS)" >> $@
+ $(hide) $(foreach partition,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS),\
+ echo "avb_vbmeta_$(partition)=$(BOARD_AVB_VBMETA_$(call to-upper,$(partition)))" >> $@ ;\
+ echo "avb_vbmeta_$(partition)_args=$(BOARD_AVB_MAKE_VBMETA_$(call to-upper,$(partition))_IMAGE_ARGS)" >> $@ ;\
+ echo "avb_vbmeta_$(partition)_key_path=$(BOARD_AVB_VBMETA_$(call to-upper,$(partition))_KEY_PATH)" >> $@ ;\
+ echo "avb_vbmeta_$(partition)_algorithm=$(BOARD_AVB_VBMETA_$(call to-upper,$(partition))_ALGORITHM)" >> $@ ;\
+ echo "avb_vbmeta_$(partition)_rollback_index_location=$(BOARD_AVB_VBMETA_$(call to-upper,$(partition))_ROLLBACK_INDEX_LOCATION)" >> $@ ;)
+endif # BOARD_AVB_VBMETA_CUSTOM_PARTITIONS
endif # BOARD_AVB_ENABLE
ifdef BOARD_BPT_INPUT_FILES
$(hide) echo "board_bpt_enable=true" >> $@
@@ -5622,6 +5759,7 @@
$(INSTALLED_CACHEIMAGE_TARGET) \
$(INSTALLED_DTBOIMAGE_TARGET) \
$(INSTALLED_PVMFWIMAGE_TARGET) \
+ $(INSTALLED_PVMFW_BINARY_TARGET) \
$(INSTALLED_PVMFW_EMBEDDED_AVBKEY_TARGET) \
$(INSTALLED_CUSTOMIMAGES_TARGET) \
$(INSTALLED_ANDROID_INFO_TXT_TARGET) \
@@ -5972,6 +6110,8 @@
$(hide) mkdir -p $(zip_root)/PREBUILT_IMAGES
$(hide) cp $(INSTALLED_PVMFWIMAGE_TARGET) $(zip_root)/PREBUILT_IMAGES/
$(hide) cp $(INSTALLED_PVMFW_EMBEDDED_AVBKEY_TARGET) $(zip_root)/PREBUILT_IMAGES/
+ $(hide) mkdir -p $(zip_root)/PVMFW
+ $(hide) cp $(INSTALLED_PVMFW_BINARY_TARGET) $(zip_root)/PVMFW/
endif
ifdef BOARD_PREBUILT_BOOTLOADER
$(hide) mkdir -p $(zip_root)/IMAGES
@@ -6824,16 +6964,26 @@
$(HOST_OUT_EXECUTABLES)/atree \
$(HOST_OUT_EXECUTABLES)/line_endings
+# The name of the subdir within the platforms dir of the sdk. One of:
+# - android-<SDK_INT> (stable base dessert SDKs)
+# - android-<CODENAME> (stable extension SDKs)
+# - android-<SDK_INT>-ext<EXT_INT> (codename SDKs)
+sdk_platform_dir_name := $(strip \
+ $(if $(filter REL,$(PLATFORM_VERSION_CODENAME)), \
+ $(if $(filter $(PLATFORM_SDK_EXTENSION_VERSION),$(PLATFORM_BASE_SDK_EXTENSION_VERSION)), \
+ android-$(PLATFORM_SDK_VERSION), \
+ android-$(PLATFORM_SDK_VERSION)-ext$(PLATFORM_SDK_EXTENSION_VERSION) \
+ ), \
+ android-$(PLATFORM_VERSION_CODENAME) \
+ ) \
+)
+
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)
-$(INTERNAL_SDK_TARGET): PRIVATE_PLATFORM_NAME := \
- $(strip $(if $(filter $(PLATFORM_SDK_EXTENSION_VERSION),$(PLATFORM_BASE_SDK_EXTENSION_VERSION)),\
- android-$(PLATFORM_SDK_VERSION),\
- android-$(PLATFORM_SDK_VERSION)-ext$(PLATFORM_SDK_EXTENSION_VERSION)) \
-)
+$(INTERNAL_SDK_TARGET): PRIVATE_PLATFORM_NAME := $(sdk_platform_dir_name)
# Set SDK_GNU_ERROR to non-empty to fail when a GNU target is built.
#
#SDK_GNU_ERROR := true
diff --git a/core/OWNERS b/core/OWNERS
index d48ceab..762d2a7 100644
--- a/core/OWNERS
+++ b/core/OWNERS
@@ -1,4 +1,5 @@
-per-file *dex_preopt*.* = ngeoffray@google.com,skvadrik@google.com
+per-file *dex_preopt*.* = jiakaiz@google.com,ngeoffray@google.com,skvadrik@google.com
+per-file art_*.* = jiakaiz@google.com,ngeoffray@google.com,skvadrik@google.com
per-file verify_uses_libraries.sh = ngeoffray@google.com,skvadrik@google.com
# For global Proguard rules
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index 9f305cf..bf113ee 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -87,6 +87,10 @@
# Apex build mode variables
ifdef APEX_BUILD_FOR_PRE_S_DEVICES
$(call add_soong_config_var_value,ANDROID,library_linking_strategy,prefer_static)
+else
+ifdef KEEP_APEX_INHERIT
+$(call add_soong_config_var_value,ANDROID,library_linking_strategy,prefer_static)
+endif
endif
ifeq (true,$(MODULE_BUILD_FROM_SOURCE))
@@ -98,10 +102,14 @@
$(call soong_config_set,messaging,build_variant_eng,true)
endif
-# TODO(b/203088572): Remove when Java optimizations enabled by default for
-# SystemUI.
+# Enable SystemUI optimizations by default unless explicitly set.
+SYSTEMUI_OPTIMIZE_JAVA ?= true
$(call add_soong_config_var,ANDROID,SYSTEMUI_OPTIMIZE_JAVA)
+ifdef PRODUCT_AVF_ENABLED
+$(call add_soong_config_var_value,ANDROID,avf_enabled,$(PRODUCT_AVF_ENABLED))
+endif
+
# Enable system_server optimizations by default unless explicitly set or if
# there may be dependent runtime jars.
# TODO(b/240588226): Remove the off-by-default exceptions after handling
diff --git a/core/art_config.mk b/core/art_config.mk
new file mode 100644
index 0000000..1ea05db
--- /dev/null
+++ b/core/art_config.mk
@@ -0,0 +1,46 @@
+# ART configuration that has to be determined after product config is resolved.
+#
+# Inputs:
+# PRODUCT_ENABLE_UFFD_GC: See comments in build/make/core/product.mk.
+# OVERRIDE_ENABLE_UFFD_GC: Overrides PRODUCT_ENABLE_UFFD_GC. Can be passed from the commandline for
+# debugging purposes.
+# BOARD_API_LEVEL: See comments in build/make/core/main.mk.
+# BOARD_SHIPPING_API_LEVEL: See comments in build/make/core/main.mk.
+# PRODUCT_SHIPPING_API_LEVEL: See comments in build/make/core/product.mk.
+#
+# Outputs:
+# ENABLE_UFFD_GC: Whether to use userfaultfd GC.
+
+config_enable_uffd_gc := \
+ $(firstword $(OVERRIDE_ENABLE_UFFD_GC) $(PRODUCT_ENABLE_UFFD_GC))
+
+ifeq (,$(filter-out default,$(config_enable_uffd_gc)))
+ ENABLE_UFFD_GC := true
+
+ # Disable userfaultfd GC if the device doesn't support it (i.e., if
+ # `min(ro.board.api_level ?? ro.board.first_api_level ?? MAX_VALUE,
+ # ro.product.first_api_level ?? ro.build.version.sdk ?? MAX_VALUE) < 31`)
+ # This logic aligns with how `ro.vendor.api_level` is calculated in
+ # `system/core/init/property_service.cpp`.
+ # We omit the check on `ro.build.version.sdk` here because we are on the latest build system.
+ board_api_level := $(firstword $(BOARD_API_LEVEL) $(BOARD_SHIPPING_API_LEVEL))
+ ifneq (,$(board_api_level))
+ ifeq (true,$(call math_lt,$(board_api_level),31))
+ ENABLE_UFFD_GC := false
+ endif
+ endif
+
+ ifneq (,$(PRODUCT_SHIPPING_API_LEVEL))
+ ifeq (true,$(call math_lt,$(PRODUCT_SHIPPING_API_LEVEL),31))
+ ENABLE_UFFD_GC := false
+ endif
+ endif
+else ifeq (true,$(config_enable_uffd_gc))
+ ENABLE_UFFD_GC := true
+else ifeq (false,$(config_enable_uffd_gc))
+ ENABLE_UFFD_GC := false
+else
+ $(error Unknown PRODUCT_ENABLE_UFFD_GC value: $(config_enable_uffd_gc))
+endif
+
+ADDITIONAL_PRODUCT_PROPERTIES += ro.dalvik.vm.enable_uffd_gc=$(ENABLE_UFFD_GC)
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 00f5f21..ec5a21e 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -600,7 +600,11 @@
# Manually handle the case where the
# output file is in the recovery or ramdisk partition.
ifneq (,$(filter $(TARGET_RECOVERY_ROOT_OUT)/%,$(my_module_path)))
- my_init_rc_path := $(TARGET_RECOVERY_ROOT_OUT)/system/etc
+ ifneq (,$(filter $(TARGET_RECOVERY_ROOT_OUT)/first_stage_ramdisk/%,$(my_module_path)))
+ my_init_rc_path := $(TARGET_RECOVERY_ROOT_OUT)/first_stage_ramdisk/system/etc
+ else
+ my_init_rc_path := $(TARGET_RECOVERY_ROOT_OUT)/system/etc
+ endif
else ifneq (,$(filter $(TARGET_RAMDISK_OUT)/%,$(my_module_path)))
my_init_rc_path := $(TARGET_RAMDISK_OUT)/system/etc
else
@@ -712,6 +716,15 @@
## Compatibility suite files.
###########################################################
ifdef LOCAL_COMPATIBILITY_SUITE
+
+ifneq (,$(LOCAL_FULL_TEST_CONFIG))
+ test_config := $(LOCAL_FULL_TEST_CONFIG)
+else ifneq (,$(LOCAL_TEST_CONFIG))
+ test_config := $(LOCAL_PATH)/$(LOCAL_TEST_CONFIG)
+else
+ test_config := $(wildcard $(LOCAL_PATH)/AndroidTest.xml)
+endif
+
ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
# If we are building a native test or benchmark and its stem variants are not defined,
@@ -758,13 +771,6 @@
# Auto-generate build config.
-ifneq (,$(LOCAL_FULL_TEST_CONFIG))
- test_config := $(LOCAL_FULL_TEST_CONFIG)
-else ifneq (,$(LOCAL_TEST_CONFIG))
- test_config := $(LOCAL_PATH)/$(LOCAL_TEST_CONFIG)
-else
- test_config := $(wildcard $(LOCAL_PATH)/AndroidTest.xml)
-endif
ifeq (,$(test_config))
ifneq (true,$(is_native))
is_instrumentation_test := true
@@ -843,16 +849,6 @@
endif
endif # $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
-# HACK: pretend a soong LOCAL_FULL_TEST_CONFIG is autogenerated by setting the flag in
-# module-info.json
-# TODO: (b/113029686) Add explicit flag from Soong to determine if a test was
-# autogenerated.
-ifneq (,$(filter $(SOONG_OUT_DIR)%,$(LOCAL_FULL_TEST_CONFIG)))
- ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
- ALL_MODULES.$(my_register_name).auto_test_config := true
- endif
-endif
-
ifeq ($(use_testcase_folder),true)
ifneq ($(my_test_data_file_pairs),)
@@ -893,6 +889,17 @@
$(eval my_compat_dist_test_data_$(suite) := ))
endif # LOCAL_UNINSTALLABLE_MODULE
+
+# HACK: pretend a soong LOCAL_FULL_TEST_CONFIG is autogenerated by setting the flag in
+# module-info.json
+# TODO: (b/113029686) Add explicit flag from Soong to determine if a test was
+# autogenerated.
+ifneq (,$(filter $(SOONG_OUT_DIR)%,$(LOCAL_FULL_TEST_CONFIG)))
+ ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+ ALL_MODULES.$(my_register_name).auto_test_config := true
+ endif
+endif
+
endif # LOCAL_COMPATIBILITY_SUITE
my_supported_variant :=
diff --git a/core/binary.mk b/core/binary.mk
index 1ad9be8..6f1d814 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -19,7 +19,11 @@
# supply that, for example, when building libc itself.
ifdef LOCAL_IS_HOST_MODULE
ifeq ($(LOCAL_SYSTEM_SHARED_LIBRARIES),none)
+ ifdef USE_HOST_MUSL
+ my_system_shared_libraries := libc_musl
+ else
my_system_shared_libraries :=
+ endif
else
my_system_shared_libraries := $(LOCAL_SYSTEM_SHARED_LIBRARIES)
endif
@@ -54,6 +58,9 @@
my_cppflags := $(LOCAL_CPPFLAGS)
my_cflags_no_override := $(GLOBAL_CLANG_CFLAGS_NO_OVERRIDE)
my_cppflags_no_override := $(GLOBAL_CLANG_CPPFLAGS_NO_OVERRIDE)
+ifeq ($(my_32_64_bit_suffix), 64)
+ my_cflags_no_override += $(GLOBAL_CLANG_CFLAGS_64_NO_OVERRIDE)
+endif
ifdef is_third_party
my_cflags_no_override += $(GLOBAL_CLANG_EXTERNAL_CFLAGS_NO_OVERRIDE)
my_cppflags_no_override += $(GLOBAL_CLANG_EXTERNAL_CFLAGS_NO_OVERRIDE)
@@ -348,9 +355,11 @@
else # LOCAL_IS_HOST_MODULE
# Add -ldl, -lpthread, -lm and -lrt to host builds to match the default behavior of
# device builds
- my_ldlibs += -ldl -lpthread -lm
- ifneq ($(HOST_OS),darwin)
- my_ldlibs += -lrt
+ ifndef USE_HOST_MUSL
+ my_ldlibs += -ldl -lpthread -lm
+ ifneq ($(HOST_OS),darwin)
+ my_ldlibs += -lrt
+ endif
endif
endif
diff --git a/core/clang/config.mk b/core/clang/config.mk
index 28a75ec..d03c541 100644
--- a/core/clang/config.mk
+++ b/core/clang/config.mk
@@ -2,7 +2,7 @@
LLVM_READOBJ := $(LLVM_PREBUILTS_BASE)/$(BUILD_OS)-x86/$(LLVM_PREBUILTS_VERSION)/bin/llvm-readobj
-LLVM_RTLIB_PATH := $(LLVM_PREBUILTS_BASE)/linux-x86/$(LLVM_PREBUILTS_VERSION)/lib64/clang/$(LLVM_RELEASE_VERSION)/lib/linux/
+LLVM_RTLIB_PATH := $(LLVM_PREBUILTS_BASE)/linux-x86/$(LLVM_PREBUILTS_VERSION)/lib/clang/$(LLVM_RELEASE_VERSION)/lib/linux/
define convert-to-clang-flags
$(strip $(filter-out $(CLANG_CONFIG_UNKNOWN_CFLAGS),$(1)))
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 8fe5214..e325760 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -153,7 +153,6 @@
LOCAL_JAR_PROCESSOR_ARGS:=
LOCAL_JAVACFLAGS:=
LOCAL_JAVA_LANGUAGE_VERSION:=
-LOCAL_JAVA_LAYERS_FILE:=
LOCAL_JAVA_LIBRARIES:=
LOCAL_JAVA_RESOURCE_DIRS:=
LOCAL_JAVA_RESOURCE_FILES:=
diff --git a/core/combo/arch/x86/goldmont-plus.mk b/core/combo/arch/x86/goldmont-plus.mk
new file mode 100644
index 0000000..4ce2053
--- /dev/null
+++ b/core/combo/arch/x86/goldmont-plus.mk
@@ -0,0 +1,7 @@
+# This file contains feature macro definitions specific to the
+# goldmont-plus arch variant.
+#
+# See build/make/core/combo/arch/x86/x86-atom.mk for differences.
+#
+
+ARCH_X86_HAVE_SSE4_1 := true
diff --git a/core/combo/arch/x86/goldmont.mk b/core/combo/arch/x86/goldmont.mk
new file mode 100644
index 0000000..b5a6ff2
--- /dev/null
+++ b/core/combo/arch/x86/goldmont.mk
@@ -0,0 +1,7 @@
+# This file contains feature macro definitions specific to the
+# goldmont arch variant.
+#
+# See build/make/core/combo/arch/x86/x86-atom.mk for differences.
+#
+
+ARCH_X86_HAVE_SSE4_1 := true
diff --git a/core/combo/arch/x86/tremont.mk b/core/combo/arch/x86/tremont.mk
new file mode 100644
index 0000000..b80d228
--- /dev/null
+++ b/core/combo/arch/x86/tremont.mk
@@ -0,0 +1,7 @@
+# This file contains feature macro definitions specific to the
+# tremont arch variant.
+#
+# See build/make/core/combo/arch/x86/x86-atom.mk for differences.
+#
+
+ARCH_X86_HAVE_SSE4_1 := true
diff --git a/core/combo/arch/x86_64/goldmont-plus.mk b/core/combo/arch/x86_64/goldmont-plus.mk
new file mode 100644
index 0000000..4ce2053
--- /dev/null
+++ b/core/combo/arch/x86_64/goldmont-plus.mk
@@ -0,0 +1,7 @@
+# This file contains feature macro definitions specific to the
+# goldmont-plus arch variant.
+#
+# See build/make/core/combo/arch/x86/x86-atom.mk for differences.
+#
+
+ARCH_X86_HAVE_SSE4_1 := true
diff --git a/core/combo/arch/x86_64/goldmont.mk b/core/combo/arch/x86_64/goldmont.mk
new file mode 100644
index 0000000..b5a6ff2
--- /dev/null
+++ b/core/combo/arch/x86_64/goldmont.mk
@@ -0,0 +1,7 @@
+# This file contains feature macro definitions specific to the
+# goldmont arch variant.
+#
+# See build/make/core/combo/arch/x86/x86-atom.mk for differences.
+#
+
+ARCH_X86_HAVE_SSE4_1 := true
diff --git a/core/combo/arch/x86_64/tremont.mk b/core/combo/arch/x86_64/tremont.mk
new file mode 100644
index 0000000..b80d228
--- /dev/null
+++ b/core/combo/arch/x86_64/tremont.mk
@@ -0,0 +1,7 @@
+# This file contains feature macro definitions specific to the
+# tremont arch variant.
+#
+# See build/make/core/combo/arch/x86/x86-atom.mk for differences.
+#
+
+ARCH_X86_HAVE_SSE4_1 := true
diff --git a/core/config.mk b/core/config.mk
index e8b984d..025a3a1 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -166,6 +166,8 @@
$(KATI_obsolete_var PRODUCT_SUPPORTS_BOOT_SIGNER,VB 1.0 and related variables are no longer supported)
$(KATI_obsolete_var PRODUCT_VERITY_SIGNING_KEY,VB 1.0 and related variables are no longer supported)
$(KATI_obsolete_var BOARD_PREBUILT_PVMFWIMAGE,pvmfw.bin is now built in AOSP and custom versions are no longer supported)
+$(KATI_obsolete_var BOARD_BUILD_SYSTEM_ROOT_IMAGE)
+
# Used to force goals to build. Only use for conditionally defined goals.
.PHONY: FORCE
FORCE:
@@ -429,6 +431,9 @@
$(hide) $(HOST_NM) -gP $(1) | cut -f1-2 -d" " | (grep -v U$$ >> $(2) || true)
endef
+# Pick a Java compiler.
+include $(BUILD_SYSTEM)/combo/javac.mk
+
ifeq ($(CALLED_FROM_SETUP),true)
include $(BUILD_SYSTEM)/ccache.mk
include $(BUILD_SYSTEM)/goma.mk
@@ -451,9 +456,6 @@
WITH_TIDY_ONLY :=
endif
-# 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.
@@ -612,7 +614,7 @@
JARJAR := $(HOST_OUT_JAVA_LIBRARIES)/jarjar.jar
DATA_BINDING_COMPILER := $(HOST_OUT_JAVA_LIBRARIES)/databinding-compiler.jar
FAT16COPY := build/make/tools/fat16copy.py
-CHECK_ELF_FILE := build/make/tools/check_elf_file.py
+CHECK_ELF_FILE := $(HOST_OUT_EXECUTABLES)/check_elf_file$(HOST_EXECUTABLE_SUFFIX)
LPMAKE := $(HOST_OUT_EXECUTABLES)/lpmake$(HOST_EXECUTABLE_SUFFIX)
ADD_IMG_TO_TARGET_FILES := $(HOST_OUT_EXECUTABLES)/add_img_to_target_files$(HOST_EXECUTABLE_SUFFIX)
BUILD_IMAGE := $(HOST_OUT_EXECUTABLES)/build_image$(HOST_EXECUTABLE_SUFFIX)
@@ -693,6 +695,14 @@
PRODUCT_FULL_TREBLE_OVERRIDE ?=
$(foreach req,$(requirements),$(eval $(req)_OVERRIDE ?=))
+ifneq ($(PRODUCT_SEPOLICY_SPLIT),true)
+# WARNING: DO NOT CHANGE: if you are downstream of AOSP, and you change this, without
+# letting upstream know it's important to you, we may do cleanup which breaks this
+# significantly. Please let us know if you are changing this.
+# TODO(b/257176017) - unsplit sepolicy is no longer supported
+PRODUCT_SEPOLICY_SPLIT := true
+endif
+
# TODO(b/114488870): disallow PRODUCT_FULL_TREBLE_OVERRIDE from being used.
.KATI_READONLY := \
PRODUCT_FULL_TREBLE_OVERRIDE \
@@ -714,8 +724,13 @@
endif
# Starting in Android U, non-VNDK devices not supported
+# WARNING: DO NOT CHANGE: if you are downstream of AOSP, and you change this, without
+# letting upstream know it's important to you, we may do cleanup which breaks this
+# significantly. Please let us know if you are changing this.
ifndef BOARD_VNDK_VERSION
+# READ WARNING - DO NOT CHANGE
BOARD_VNDK_VERSION := current
+# READ WARNING - DO NOT CHANGE
endif
ifdef PRODUCT_PRODUCT_VNDK_VERSION
@@ -866,11 +881,6 @@
endif
endif
-# TODO(b/241346584): Mark BOARD_BUILD_SYSTEM_ROOT_IMAGE as KATI_obsolete_var after all users are removed
-ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
- $(error BOARD_BUILD_SYSTEM_ROOT_IMAGE is deprecated)
-endif
-
ifeq ($(PRODUCT_USE_DYNAMIC_PARTITIONS),true)
ifneq ($(PRODUCT_USE_DYNAMIC_PARTITION_SIZE),true)
$(error PRODUCT_USE_DYNAMIC_PARTITION_SIZE must be true for devices with dynamic partitions)
@@ -1052,14 +1062,6 @@
BOARD_PREBUILT_HIDDENAPI_DIR ?=
.KATI_READONLY := BOARD_PREBUILT_HIDDENAPI_DIR
-ifdef USE_HOST_MUSL
- ifneq (,$(or $(BUILD_BROKEN_USES_BUILD_HOST_EXECUTABLE),\
- $(BUILD_BROKEN_USES_BUILD_HOST_SHARED_LIBRARY),\
- $(BUILD_BROKEN_USES_BUILD_HOST_STATIC_LIBRARY)))
- $(error USE_HOST_MUSL can't be set when native host builds are enabled in Make with BUILD_BROKEN_USES_BUILD_HOST_*)
- endif
-endif
-
# ###############################################################
# Set up final options.
# ###############################################################
diff --git a/core/definitions.mk b/core/definitions.mk
index 98fdd6c..a0337c2 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -595,12 +595,10 @@
## license metadata.
###########################################################
define declare-copy-target-license-metadata
-$(strip $(if $(filter $(OUT_DIR)%,$(2)),$(eval _dir:=$(call license-metadata-dir,$(1)))\
+$(strip $(if $(filter $(OUT_DIR)%,$(2)),\
$(eval _tgt:=$(strip $(1)))\
- $(eval _meta := $(call append-path,$(_dir),$(patsubst $(OUT_DIR)%,out%,$(_tgt).meta_lic)))\
$(eval ALL_COPIED_TARGETS.$(_tgt).SOURCES := $(ALL_COPIED_TARGETS.$(_tgt).SOURCES) $(filter $(OUT_DIR)%,$(2)))\
- $(eval ALL_COPIED_TARGETS += $(_tgt)),\
- $(eval ALL_TARGETS.$(1).META_LIC:=$(module_license_metadata))))
+ $(eval ALL_COPIED_TARGETS += $(_tgt))))
endef
###########################################################
@@ -746,11 +744,10 @@
$(strip $(eval _dep:=))
$(strip $(foreach s,$(ALL_COPIED_TARGETS.$(1).SOURCES),\
$(eval _dmeta:=$(ALL_TARGETS.$(s).META_LIC))\
- $(if $(filter 0p,$(_dmeta)),\
- $(if $(filter-out 0p,$(_dep)),,$(eval ALL_TARGETS.$(1).META_LIC:=0p)),\
- $(if $(_dep),\
- $(if $(filter-out $(_dep),$(_dmeta)),$(error cannot copy target from multiple modules: $(1) from $(_dep) and $(_dmeta))),
- $(eval _dep:=$(_dmeta))))))
+ $(if $(filter-out 0p,$(_dep)),\
+ $(if $(filter-out $(_dep),$(_dmeta)),$(error cannot copy target from multiple modules: $(1) from $(_dep) and $(_dmeta))),\
+ $(eval _dep:=$(_dmeta)))))
+$(if $(filter 0p,$(_dep)),$(eval ALL_TARGETS.$(1).META_LIC:=0p))
$(strip $(if $(strip $(_dep)),,$(error cannot copy target from unknown module: $(1) from $(ALL_COPIED_TARGETS.$(1).SOURCES))))
ifneq (0p,$(ALL_TARGETS.$(1).META_LIC))
@@ -772,6 +769,11 @@
-o $$@
endif
+
+$(eval _dep:=)
+$(eval _dmeta:=)
+$(eval _meta:=)
+$(eval _dir:=)
endef
###########################################################
@@ -2121,6 +2123,7 @@
$(PRIVATE_HOST_GLOBAL_LDFLAGS) \
) \
$(PRIVATE_LDFLAGS) \
+ $(PRIVATE_CRTBEGIN) \
$(PRIVATE_ALL_OBJECTS) \
-Wl,--whole-archive \
$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES) \
@@ -2129,8 +2132,10 @@
$(PRIVATE_ALL_STATIC_LIBRARIES) \
$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
$(if $(filter true,$(NATIVE_COVERAGE)),$(PRIVATE_HOST_LIBPROFILE_RT)) \
+ $(PRIVATE_LIBCRT_BUILTINS) \
$(PRIVATE_ALL_SHARED_LIBRARIES) \
-o $@ \
+ $(PRIVATE_CRTEND) \
$(PRIVATE_LDLIBS)
endef
endif
@@ -2264,6 +2269,7 @@
ifneq ($(HOST_CUSTOM_LD_COMMAND),true)
define transform-host-o-to-executable-inner
$(hide) $(PRIVATE_CXX_LINK) \
+ $(PRIVATE_CRTBEGIN) \
$(PRIVATE_ALL_OBJECTS) \
-Wl,--whole-archive \
$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES) \
@@ -2272,6 +2278,7 @@
$(PRIVATE_ALL_STATIC_LIBRARIES) \
$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
$(if $(filter true,$(NATIVE_COVERAGE)),$(PRIVATE_HOST_LIBPROFILE_RT)) \
+ $(PRIVATE_LIBCRT_BUILTINS) \
$(PRIVATE_ALL_SHARED_LIBRARIES) \
$(foreach path,$(PRIVATE_RPATHS), \
-Wl,-rpath,\$$ORIGIN/$(path)) \
@@ -2280,6 +2287,7 @@
) \
$(PRIVATE_LDFLAGS) \
-o $@ \
+ $(PRIVATE_CRTEND) \
$(PRIVATE_LDLIBS)
endef
endif
@@ -2604,8 +2612,6 @@
$(if $(PRIVATE_SRCJARS),\@$(PRIVATE_SRCJAR_LIST_FILE)) \
|| ( rm -rf $(PRIVATE_CLASS_INTERMEDIATES_DIR) ; exit 41 ) \
fi
-$(if $(PRIVATE_JAVA_LAYERS_FILE), $(hide) build/make/tools/java-layers.py \
- $(PRIVATE_JAVA_LAYERS_FILE) @$(PRIVATE_JAVA_SOURCE_LIST),)
$(if $(PRIVATE_JAR_EXCLUDE_FILES), $(hide) find $(PRIVATE_CLASS_INTERMEDIATES_DIR) \
-name $(word 1, $(PRIVATE_JAR_EXCLUDE_FILES)) \
$(addprefix -o -name , $(wordlist 2, 999, $(PRIVATE_JAR_EXCLUDE_FILES))) \
diff --git a/core/dex_preopt.mk b/core/dex_preopt.mk
index 593ad66..88ec47f 100644
--- a/core/dex_preopt.mk
+++ b/core/dex_preopt.mk
@@ -62,10 +62,24 @@
boot_zip := $(PRODUCT_OUT)/boot.zip
bootclasspath_jars := $(DEXPREOPT_BOOTCLASSPATH_DEX_FILES)
+
+# TODO remove system_server_jars usages from boot.zip and depend directly on system_server.zip file.
+
+# Use "/system" path for JARs with "platform:" prefix.
+# These JARs counterintuitively use "platform" prefix but they will
+# be actually installed to /system partition.
+platform_system_server_jars = $(filter platform:%, $(PRODUCT_SYSTEM_SERVER_JARS))
system_server_jars := \
- $(foreach m,$(PRODUCT_SYSTEM_SERVER_JARS),\
+ $(foreach m,$(platform_system_server_jars),\
$(PRODUCT_OUT)/system/framework/$(call word-colon,2,$(m)).jar)
+# For the remaining system server JARs use the partition signified by the prefix.
+# For example, prefix "system_ext:" will use "/system_ext" path.
+other_system_server_jars = $(filter-out $(platform_system_server_jars), $(PRODUCT_SYSTEM_SERVER_JARS))
+system_server_jars += \
+ $(foreach m,$(other_system_server_jars),\
+ $(PRODUCT_OUT)/$(call word-colon,1,$(m))/framework/$(call word-colon,2,$(m)).jar)
+
$(boot_zip): PRIVATE_BOOTCLASSPATH_JARS := $(bootclasspath_jars)
$(boot_zip): PRIVATE_SYSTEM_SERVER_JARS := $(system_server_jars)
$(boot_zip): $(bootclasspath_jars) $(system_server_jars) $(SOONG_ZIP) $(MERGE_ZIPS) $(DEXPREOPT_IMAGE_ZIP_boot) $(DEXPREOPT_IMAGE_ZIP_art)
@@ -79,5 +93,34 @@
$(call dist-for-goals, droidcore, $(boot_zip))
+# Build the system_server.zip which contains the Apex system server jars and standalone system server jars
+system_server_zip := $(PRODUCT_OUT)/system_server.zip
+apex_system_server_jars := \
+ $(foreach m,$(PRODUCT_APEX_SYSTEM_SERVER_JARS),\
+ $(PRODUCT_OUT)/apex/$(call word-colon,1,$(m))/javalib/$(call word-colon,2,$(m)).jar)
+
+apex_standalone_system_server_jars := \
+ $(foreach m,$(PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS),\
+ $(PRODUCT_OUT)/apex/$(call word-colon,1,$(m))/javalib/$(call word-colon,2,$(m)).jar)
+
+standalone_system_server_jars := \
+ $(foreach m,$(PRODUCT_STANDALONE_SYSTEM_SERVER_JARS),\
+ $(PRODUCT_OUT)/apex/$(call word-colon,1,$(m))/javalib/$(call word-colon,2,$(m)).jar)
+
+$(system_server_zip): PRIVATE_SYSTEM_SERVER_JARS := $(system_server_jars)
+$(system_server_zip): PRIVATE_APEX_SYSTEM_SERVER_JARS := $(apex_system_server_jars)
+$(system_server_zip): PRIVATE_APEX_STANDALONE_SYSTEM_SERVER_JARS := $(apex_standalone_system_server_jars)
+$(system_server_zip): PRIVATE_STANDALONE_SYSTEM_SERVER_JARS := $(standalone_system_server_jars)
+$(system_server_zip): $(system_server_jars) $(apex_system_server_jars) $(apex_standalone_system_server_jars) $(standalone_system_server_jars) $(SOONG_ZIP)
+ @echo "Create system server package: $@"
+ rm -f $@
+ $(SOONG_ZIP) -o $@ \
+ -C $(PRODUCT_OUT) $(addprefix -f ,$(PRIVATE_SYSTEM_SERVER_JARS)) \
+ -C $(PRODUCT_OUT) $(addprefix -f ,$(PRIVATE_APEX_SYSTEM_SERVER_JARS)) \
+ -C $(PRODUCT_OUT) $(addprefix -f ,$(PRIVATE_APEX_STANDALONE_SYSTEM_SERVER_JARS)) \
+ -C $(PRODUCT_OUT) $(addprefix -f ,$(PRIVATE_STANDALONE_SYSTEM_SERVER_JARS))
+
+$(call dist-for-goals, droidcore, $(system_server_zip))
+
endif #PRODUCT_USES_DEFAULT_ART_CONFIG
endif #WITH_DEXPREOPT
diff --git a/core/dex_preopt_config.mk b/core/dex_preopt_config.mk
index c11b7f4..e36e2eb 100644
--- a/core/dex_preopt_config.mk
+++ b/core/dex_preopt_config.mk
@@ -130,6 +130,7 @@
$(call add_json_str, Dex2oatXmx, $(DEX2OAT_XMX))
$(call add_json_str, Dex2oatXms, $(DEX2OAT_XMS))
$(call add_json_str, EmptyDirectory, $(OUT_DIR)/empty)
+ $(call add_json_bool, EnableUffdGc, $(filter true,$(ENABLE_UFFD_GC)))
ifdef TARGET_ARCH
$(call add_json_map, CpuVariant)
diff --git a/core/dumpvar.mk b/core/dumpvar.mk
index 6f3d14f..4f313bf 100644
--- a/core/dumpvar.mk
+++ b/core/dumpvar.mk
@@ -3,18 +3,6 @@
# what to add to the path given the config we have chosen.
ifeq ($(CALLED_FROM_SETUP),true)
-ifneq ($(filter /%,$(SOONG_HOST_OUT_EXECUTABLES)),)
-ABP := $(SOONG_HOST_OUT_EXECUTABLES)
-else
-ABP := $(PWD)/$(SOONG_HOST_OUT_EXECUTABLES)
-endif
-ifneq ($(filter /%,$(HOST_OUT_EXECUTABLES)),)
-ABP := $(ABP):$(HOST_OUT_EXECUTABLES)
-else
-ABP := $(ABP):$(PWD)/$(HOST_OUT_EXECUTABLES)
-endif
-
-ANDROID_BUILD_PATHS := $(ABP)
ANDROID_PREBUILTS := prebuilt/$(HOST_PREBUILT_TAG)
ANDROID_GCC_PREBUILTS := prebuilts/gcc/$(HOST_PREBUILT_TAG)
ANDROID_CLANG_PREBUILTS := prebuilts/clang/host/$(HOST_PREBUILT_TAG)
diff --git a/core/envsetup.mk b/core/envsetup.mk
index fc4afd9..7dd9b12 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -135,15 +135,17 @@
HOST_OS := darwin
endif
-HOST_OS_EXTRA := $(shell uname -rsm)
-ifeq ($(HOST_OS),linux)
- ifneq ($(wildcard /etc/os-release),)
- HOST_OS_EXTRA += $(shell source /etc/os-release; echo $$PRETTY_NAME)
+ifeq ($(CALLED_FROM_SETUP),true)
+ HOST_OS_EXTRA := $(shell uname -rsm)
+ ifeq ($(HOST_OS),linux)
+ ifneq ($(wildcard /etc/os-release),)
+ HOST_OS_EXTRA += $(shell source /etc/os-release; echo $$PRETTY_NAME)
+ endif
+ else ifeq ($(HOST_OS),darwin)
+ HOST_OS_EXTRA += $(shell sw_vers -productVersion)
endif
-else ifeq ($(HOST_OS),darwin)
- HOST_OS_EXTRA += $(shell sw_vers -productVersion)
+ HOST_OS_EXTRA := $(subst $(space),-,$(HOST_OS_EXTRA))
endif
-HOST_OS_EXTRA := $(subst $(space),-,$(HOST_OS_EXTRA))
# BUILD_OS is the real host doing the build.
BUILD_OS := $(HOST_OS)
diff --git a/core/host_executable_internal.mk b/core/host_executable_internal.mk
index 0cf62a4..2ff9ff2 100644
--- a/core/host_executable_internal.mk
+++ b/core/host_executable_internal.mk
@@ -39,6 +39,21 @@
endif
my_libdir :=
+my_crtbegin :=
+my_crtend :=
+my_libcrt_builtins :=
+ifdef USE_HOST_MUSL
+ my_crtbegin := $(SOONG_$(LOCAL_2ND_ARCH_VAR_PREFIX)HOST_OBJECT_libc_musl_crtbegin_dynamic)
+ my_crtend := $(SOONG_$(LOCAL_2ND_ARCH_VAR_PREFIX)HOST_OBJECT_libc_musl_crtend)
+ my_libcrt_builtins := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)LIBCRT_BUILTINS)
+ $(LOCAL_BUILT_MODULE): PRIVATE_LDFLAGS += -Wl,--no-dynamic-linker
+endif
+
+$(LOCAL_BUILT_MODULE): PRIVATE_CRTBEGIN := $(my_crtbegin)
+$(LOCAL_BUILT_MODULE): PRIVATE_CRTEND := $(my_crtend)
+$(LOCAL_BUILT_MODULE): PRIVATE_LIBCRT_BUILTINS := $(my_libcrt_builtins)
+$(LOCAL_BUILT_MODULE): $(my_crtbegin) $(my_crtend) $(my_libcrt_builtins)
+
$(LOCAL_BUILT_MODULE): $(all_objects) $(all_libraries) $(CLANG_CXX)
$(transform-host-o-to-executable)
diff --git a/core/host_java_library.mk b/core/host_java_library.mk
index 0f95202..89aa53c 100644
--- a/core/host_java_library.mk
+++ b/core/host_java_library.mk
@@ -56,10 +56,6 @@
include $(BUILD_SYSTEM)/java_common.mk
-# The layers file allows you to enforce a layering between java packages.
-# Run build/make/tools/java-layers.py for more details.
-layers_file := $(addprefix $(LOCAL_PATH)/, $(LOCAL_JAVA_LAYERS_FILE))
-
# List of dependencies for anything that needs all java sources in place
java_sources_deps := \
$(java_sources) \
@@ -72,7 +68,6 @@
# TODO(b/143658984): goma can't handle the --system argument to javac.
#$(full_classes_compiled_jar): .KATI_NINJA_POOL := $(GOMA_POOL)
-$(full_classes_compiled_jar): PRIVATE_JAVA_LAYERS_FILE := $(layers_file)
$(full_classes_compiled_jar): PRIVATE_JAVACFLAGS := $(LOCAL_JAVACFLAGS) $(annotation_processor_flags)
$(full_classes_compiled_jar): PRIVATE_JAR_EXCLUDE_FILES :=
$(full_classes_compiled_jar): PRIVATE_JAR_PACKAGES :=
diff --git a/core/host_shared_library_internal.mk b/core/host_shared_library_internal.mk
index da20874..ae8b798 100644
--- a/core/host_shared_library_internal.mk
+++ b/core/host_shared_library_internal.mk
@@ -36,6 +36,17 @@
my_host_libprofile_rt := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)LIBPROFILE_RT)
$(LOCAL_BUILT_MODULE): PRIVATE_HOST_LIBPROFILE_RT := $(my_host_libprofile_rt)
+ifdef USE_HOST_MUSL
+ my_crtbegin := $(SOONG_$(LOCAL_2ND_ARCH_VAR_PREFIX)HOST_OBJECT_libc_musl_crtbegin_so)
+ my_crtend := $(SOONG_$(LOCAL_2ND_ARCH_VAR_PREFIX)HOST_OBJECT_libc_musl_crtend_so)
+ my_libcrt_builtins := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)LIBCRT_BUILTINS)
+endif
+
+$(LOCAL_BUILT_MODULE): PRIVATE_CRTBEGIN := $(my_crtbegin)
+$(LOCAL_BUILT_MODULE): PRIVATE_CRTEND := $(my_crtend)
+$(LOCAL_BUILT_MODULE): PRIVATE_LIBCRT_BUILTINS := $(my_libcrt_builtins)
+$(LOCAL_BUILT_MODULE): $(my_crtbegin) $(my_crtend) $(my_libcrt_builtins)
+
$(LOCAL_BUILT_MODULE): \
$(all_objects) \
$(all_libraries) \
diff --git a/core/java.mk b/core/java.mk
index 01951c0..b13ef4d 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -200,10 +200,6 @@
$(eval $(call copy-one-file,$(full_classes_jar),$(full_classes_stubs_jar)))
ALL_MODULES.$(my_register_name).STUBS := $(full_classes_stubs_jar)
-# The layers file allows you to enforce a layering between java packages.
-# Run build/make/tools/java-layers.py for more details.
-layers_file := $(addprefix $(LOCAL_PATH)/, $(LOCAL_JAVA_LAYERS_FILE))
-$(full_classes_compiled_jar): PRIVATE_JAVA_LAYERS_FILE := $(layers_file)
$(full_classes_compiled_jar): PRIVATE_WARNINGS_ENABLE := $(LOCAL_WARNINGS_ENABLE)
# Compile the java files to a .jar file.
diff --git a/core/java_host_unit_test_config_template.xml b/core/java_host_unit_test_config_template.xml
index d8795f9..5d8b254 100644
--- a/core/java_host_unit_test_config_template.xml
+++ b/core/java_host_unit_test_config_template.xml
@@ -23,5 +23,14 @@
<test class="com.android.tradefed.testtype.IsolatedHostTest" >
<option name="jar" value="{MODULE}.jar" />
+ <option name="java-flags" value="--add-modules=jdk.compiler"/>
+ <option name="java-flags" value="--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED"/>
+ <option name="java-flags" value="--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED"/>
+ <option name="java-flags" value="--add-exports=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED"/>
+ <option name="java-flags" value="--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED"/>
+ <option name="java-flags" value="--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED"/>
+ <option name="java-flags" value="--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED"/>
+ <option name="java-flags" value="--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED"/>
+ <option name="java-flags" value="--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED"/>
</test>
</configuration>
diff --git a/core/main.mk b/core/main.mk
index 2e39601..3866037 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -92,6 +92,9 @@
-include test/catbox/tools/build/config.mk
# CTS-Root-specific config.
-include test/cts-root/tools/build/config.mk
+# WVTS-specific config.
+-include test/wvts/tools/build/config.mk
+
# Clean rules
.PHONY: clean-dex-files
@@ -493,6 +496,8 @@
# Typical build; include any Android.mk files we can find.
#
+include $(BUILD_SYSTEM)/art_config.mk
+
# Bring in dex_preopt.mk
# This creates some modules so it needs to be included after
# should-install-to-system is defined (in order for base_rules.mk to function
@@ -1600,6 +1605,9 @@
.PHONY: vbmetavendorimage
vbmetavendorimage: $(INSTALLED_VBMETA_VENDORIMAGE_TARGET)
+.PHONY: vbmetacustomimages
+vbmetacustomimages: $(foreach partition,$(call to-upper,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS)),$(INSTALLED_VBMETA_$(partition)IMAGE_TARGET))
+
# The droidcore-unbundled target depends on the subset of targets necessary to
# perform a full system build (either unbundled or not).
.PHONY: droidcore-unbundled
diff --git a/core/product.mk b/core/product.mk
index 277fa74..f4d5a4f 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -24,6 +24,8 @@
_product_single_value_vars += PRODUCT_NAME
_product_single_value_vars += PRODUCT_MODEL
+_product_single_value_vars += PRODUCT_NAME_FOR_ATTESTATION
+_product_single_value_vars += PRODUCT_MODEL_FOR_ATTESTATION
# The resoure configuration options to use for this product.
_product_list_vars += PRODUCT_LOCALES
@@ -43,6 +45,7 @@
_product_single_value_vars += PRODUCT_DEVICE
_product_single_value_vars += PRODUCT_MANUFACTURER
_product_single_value_vars += PRODUCT_BRAND
+_product_single_value_vars += PRODUCT_BRAND_FOR_ATTESTATION
# These PRODUCT_SYSTEM_* flags, if defined, are used in place of the
# corresponding PRODUCT_* flags for the sysprops on /system.
@@ -263,6 +266,9 @@
# This flag implies PRODUCT_USE_DYNAMIC_PARTITIONS.
_product_single_value_vars += PRODUCT_RETROFIT_DYNAMIC_PARTITIONS
+# List of tags that will be used to gate blueprint modules from the build graph
+_product_list_vars += PRODUCT_INCLUDE_TAGS
+
# When this is true, various build time as well as runtime debugfs restrictions are enabled.
_product_single_value_vars += PRODUCT_SET_DEBUGFS_RESTRICTIONS
@@ -367,6 +373,24 @@
# BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE but not an explicitly set value.
_product_single_value_vars += PRODUCT_MODULE_BUILD_FROM_SOURCE
+# If true, installs a full version of com.android.virt APEX.
+_product_single_value_vars += PRODUCT_AVF_ENABLED
+
+# List of .json files to be merged/compiled into vendor/etc/linker.config.pb
+_product_list_vars += PRODUCT_VENDOR_LINKER_CONFIG_FRAGMENTS
+
+# Whether to use userfaultfd GC.
+# Possible values are:
+# - "default" or empty: both the build system and the runtime determine whether to use userfaultfd
+# GC based on the vendor API level
+# - "true": forces the build system to use userfaultfd GC regardless of the vendor API level; the
+# runtime determines whether to use userfaultfd GC based on the kernel support. Note that the
+# device may have to re-compile everything on the first boot if the kernel doesn't support
+# userfaultfd
+# - "false": disallows the build system and the runtime to use userfaultfd GC even if the device
+# supports it
+_product_single_value_vars += PRODUCT_ENABLE_UFFD_GC
+
.KATI_READONLY := _product_single_value_vars _product_list_vars
_product_var_list :=$= $(_product_single_value_vars) $(_product_list_vars)
diff --git a/core/product_config.mk b/core/product_config.mk
index e03ae2b..7055a1e 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -274,6 +274,14 @@
current_product_makefile :=
#############################################################################
+# Check product include tag allowlist
+BLUEPRINT_INCLUDE_TAGS_ALLOWLIST := com.android.mainline_go com.android.mainline
+.KATI_READONLY := BLUEPRINT_INCLUDE_TAGS_ALLOWLIST
+$(foreach include_tag,$(PRODUCT_INCLUDE_TAGS), \
+ $(if $(filter $(include_tag),$(BLUEPRINT_INCLUDE_TAGS_ALLOWLIST)),,\
+ $(call pretty-error, $(include_tag) is not in BLUEPRINT_INCLUDE_TAGS_ALLOWLIST: $(BLUEPRINT_INCLUDE_TAGS_ALLOWLIST))))
+#############################################################################
+
# Quick check and assign default values
TARGET_DEVICE := $(PRODUCT_DEVICE)
diff --git a/core/product_config.rbc b/core/product_config.rbc
index 7a5e501..97c1d00 100644
--- a/core/product_config.rbc
+++ b/core/product_config.rbc
@@ -59,6 +59,12 @@
if _options.format == "pretty":
print(attr, "=", repr(value))
elif _options.format == "make":
+ value = list(value)
+ for i, x in enumerate(value):
+ if type(x) == "tuple" and len(x) == 1:
+ value[i] = "@inherit:" + x[0] + ".mk"
+ elif type(x) != "string":
+ fail("Wasn't a list of strings:", attr, " value:", value)
print(attr, ":=", " ".join(value))
elif _options.format == "pretty":
print(attr, "=", repr(value))
@@ -456,6 +462,9 @@
def __words(string_or_list):
if type(string_or_list) == "list":
+ for x in string_or_list:
+ if type(x) != "string":
+ return string_or_list
string_or_list = " ".join(string_or_list)
return _mkstrip(string_or_list).split()
@@ -830,6 +839,41 @@
return [ __mkpatsubst_word(parsed_percent, parsed_src, x) + ":" + __mkpatsubst_word(parsed_percent, parsed_dest, x) for x in words]
+__zero_values = {
+ "string": "",
+ "list": [],
+ "int": 0,
+ "float": 0,
+ "bool": False,
+ "dict": {},
+ "NoneType": None,
+ "tuple": (),
+}
+def __zero_value(x):
+ t = type(x)
+ if t in __zero_values:
+ return __zero_values[t]
+ else:
+ fail("Unknown type: "+t)
+
+
+def _clear_var_list(g, h, var_list):
+ cfg = __h_cfg(h)
+ for v in __words(var_list):
+ # Set these variables to their zero values rather than None
+ # or removing them from the dictionary because if they were
+ # removed entirely, ?= would set their value, when it would not
+ # after a make-based clear_var_list call.
+ if v in g:
+ g[v] = __zero_value(g[v])
+ if v in cfg:
+ cfg[v] = __zero_value(cfg[v])
+
+ if v not in cfg and v not in g:
+ # Cause the variable to appear set like the make version does
+ g[v] = ""
+
+
def __get_options():
"""Returns struct containing runtime global settings."""
settings = dict(
@@ -873,6 +917,7 @@
addsuffix = _addsuffix,
board_platform_in = _board_platform_in,
board_platform_is = _board_platform_is,
+ clear_var_list = _clear_var_list,
copy_files = _copy_files,
copy_if_exists = _copy_if_exists,
cfg = __h_cfg,
diff --git a/core/proguard.flags b/core/proguard.flags
index 53f63d8..d790061 100644
--- a/core/proguard.flags
+++ b/core/proguard.flags
@@ -9,14 +9,19 @@
# Add this flag in your package's own configuration if it's needed.
#-flattenpackagehierarchy
-# Keep classes and methods that have @VisibleForTesting annotations, except in
-# intermediate libraries that export those annotations (e.g., androidx, guava).
-# This avoids keeping library-specific test code that isn't actually needed
-# for platform testing.
+# Keep classes and members with the platform-defined @VisibleForTesting annotation.
+-keep @com.android.internal.annotations.VisibleForTesting class *
+-keepclassmembers class * {
+ @com.android.internal.annotations.VisibleForTesting *;
+}
+
+# Keep classes and members with non-platform @VisibleForTesting annotations, but
+# only within platform-defined packages. This avoids keeping external, library-specific
+# test code that isn't actually needed for platform testing.
# TODO(b/239961360): Migrate away from androidx.annotation.VisibleForTesting
# and com.google.common.annotations.VisibleForTesting use in platform code.
--keep @**.VisibleForTesting class !androidx.**,!com.google.common.**,*
--keepclassmembers class !androidx.**,!com.google.common.**,* {
+-keep @**.VisibleForTesting class android.**,com.android.**,com.google.android.**
+-keepclassmembers class android.**,com.android.**,com.google.android.** {
@**.VisibleForTesting *;
}
diff --git a/core/rbe.mk b/core/rbe.mk
index 65abde5..6754b0a 100644
--- a/core/rbe.mk
+++ b/core/rbe.mk
@@ -81,11 +81,11 @@
endif
ifdef RBE_R8
- R8_WRAPPER := $(strip $(RBE_WRAPPER) --labels=type=compile,compiler=r8 --exec_strategy=$(r8_exec_strategy) --platform=$(java_r8_d8_platform) --inputs=$(OUT_DIR)/soong/host/linux-x86/framework/r8-compat-proguard.jar,build/make/core/proguard_basic_keeps.flags --toolchain_inputs=$(JAVA))
+ R8_WRAPPER := $(strip $(RBE_WRAPPER) --labels=type=compile,compiler=r8 --exec_strategy=$(r8_exec_strategy) --platform=$(java_r8_d8_platform) --inputs=$(OUT_DIR)/host/linux-x86/framework/r8.jar,build/make/core/proguard_basic_keeps.flags --toolchain_inputs=$(firstword $(JAVA)))
endif
ifdef RBE_D8
- D8_WRAPPER := $(strip $(RBE_WRAPPER) --labels=type=compile,compiler=d8 --exec_strategy=$(d8_exec_strategy) --platform=$(java_r8_d8_platform) --inputs=$(OUT_DIR)/soong/host/linux-x86/framework/d8.jar --toolchain_inputs=$(JAVA))
+ D8_WRAPPER := $(strip $(RBE_WRAPPER) --labels=type=compile,compiler=d8 --exec_strategy=$(d8_exec_strategy) --platform=$(java_r8_d8_platform) --inputs=$(OUT_DIR)/host/linux-x86/framework/d8.jar --toolchain_inputs=$(firstword $(JAVA)))
endif
rbe_dir :=
diff --git a/core/soong_config.mk b/core/soong_config.mk
index b000df6..091fa34 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -9,6 +9,7 @@
endif
endif
+include $(BUILD_SYSTEM)/art_config.mk
include $(BUILD_SYSTEM)/dex_preopt_config.mk
ifeq ($(WRITE_SOONG_VARIABLES),true)
@@ -248,9 +249,9 @@
$(call add_json_list, MissingUsesLibraries, $(INTERNAL_PLATFORM_MISSING_USES_LIBRARIES))
$(call add_json_map, VendorVars)
-$(foreach namespace,$(SOONG_CONFIG_NAMESPACES),\
+$(foreach namespace,$(sort $(SOONG_CONFIG_NAMESPACES)),\
$(call add_json_map, $(namespace))\
- $(foreach key,$(SOONG_CONFIG_$(namespace)),\
+ $(foreach key,$(sort $(SOONG_CONFIG_$(namespace))),\
$(call add_json_str,$(key),$(subst ",\",$(SOONG_CONFIG_$(namespace)_$(key)))))\
$(call end_json_map))
$(call end_json_map)
@@ -265,6 +266,10 @@
$(call add_json_bool, CompressedApex, $(filter true,$(PRODUCT_COMPRESSED_APEX)))
+ifndef APEX_BUILD_FOR_PRE_S_DEVICES
+$(call add_json_bool, TrimmedApex, $(filter true,$(PRODUCT_TRIMMED_APEX)))
+endif
+
$(call add_json_bool, BoardUsesRecoveryAsBoot, $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)))
$(call add_json_list, BoardKernelBinaries, $(BOARD_KERNEL_BINARIES))
@@ -299,6 +304,8 @@
$(call add_json_bool, IgnorePrefer32OnDevice, $(filter true,$(IGNORE_PREFER32_ON_DEVICE)))
+$(call add_json_list, IncludeTags, $(PRODUCT_INCLUDE_TAGS))
+
$(call json_end)
$(file >$(SOONG_VARIABLES).tmp,$(json_contents))
diff --git a/core/sysprop.mk b/core/sysprop.mk
index b51818a..b7f0651 100644
--- a/core/sysprop.mk
+++ b/core/sysprop.mk
@@ -46,6 +46,10 @@
echo "ro.product.$(1).manufacturer=$(PRODUCT_MANUFACTURER)" >> $(2);\
echo "ro.product.$(1).model=$(PRODUCT_MODEL)" >> $(2);\
echo "ro.product.$(1).name=$(TARGET_PRODUCT)" >> $(2);\
+ # Attestation specific properties for AOSP/GSI build running on device.
+ echo "ro.product.model_for_attestation=$(PRODUCT_MODEL_FOR_ATTESTATION)" >> $(2);\
+ echo "ro.product.brand_for_attestation=$(PRODUCT_BRAND_FOR_ATTESTATION)" >> $(2);\
+ echo "ro.product.name_for_attestation=$(PRODUCT_NAME_FOR_ATTESTATION)" >> $(2);\
)\
$(if $(filter true,$(ZYGOTE_FORCE_64)),\
$(if $(filter vendor,$(1)),\
diff --git a/core/tasks/OWNERS b/core/tasks/OWNERS
index 594930d..372ff8b 100644
--- a/core/tasks/OWNERS
+++ b/core/tasks/OWNERS
@@ -1 +1,2 @@
per-file art-host-tests.mk = dshi@google.com,dsrbecky@google.com,jdesprez@google.com,rpl@google.com
+per-file catbox.mk = smara@google.com,schinchalkar@google.com,kaneesh@google.com
diff --git a/core/tasks/general-tests.mk b/core/tasks/general-tests.mk
index 5726ee2..8dbc76f 100644
--- a/core/tasks/general-tests.mk
+++ b/core/tasks/general-tests.mk
@@ -87,7 +87,8 @@
$(SOONG_ZIP) -d -o $@ \
-P host -C $(PRIVATE_INTERMEDIATES_DIR) -D $(PRIVATE_INTERMEDIATES_DIR)/tools \
-P host -C $(HOST_OUT) -l $(PRIVATE_INTERMEDIATES_DIR)/host.list \
- -P target -C $(PRODUCT_OUT) -l $(PRIVATE_INTERMEDIATES_DIR)/target.list
+ -P target -C $(PRODUCT_OUT) -l $(PRIVATE_INTERMEDIATES_DIR)/target.list \
+ -sha256
$(SOONG_ZIP) -d -o $(PRIVATE_general_tests_configs_zip) \
-P host -C $(HOST_OUT) -l $(PRIVATE_INTERMEDIATES_DIR)/host-test-configs.list \
-P target -C $(PRODUCT_OUT) -l $(PRIVATE_INTERMEDIATES_DIR)/target-test-configs.list
diff --git a/core/tasks/host-unit-tests.mk b/core/tasks/host-unit-tests.mk
index ed2f2a6..733a2e2 100644
--- a/core/tasks/host-unit-tests.mk
+++ b/core/tasks/host-unit-tests.mk
@@ -41,7 +41,7 @@
grep $(TARGET_OUT_TESTCASES) $@.list > $@-target.list || true
$(hide) $(SOONG_ZIP) -d -o $@ -P host -C $(HOST_OUT) -l $@-host.list \
-P target -C $(PRODUCT_OUT) -l $@-target.list \
- -P host/testcases -C $(HOST_OUT) -l $@-host-libs.list
+ -P host/testcases -C $(HOST_OUT) -l $@-host-libs.list -sha256
rm -f $@.list $@-host.list $@-target.list $@-host-libs.list
host-unit-tests: $(host_unit_tests_zip)
diff --git a/core/tasks/module-info.mk b/core/tasks/module-info.mk
index dbd1e84..e83d408 100644
--- a/core/tasks/module-info.mk
+++ b/core/tasks/module-info.mk
@@ -41,3 +41,9 @@
$(call dist-for-goals, general-tests, $(MODULE_INFO_JSON))
$(call dist-for-goals, droidcore-unbundled, $(MODULE_INFO_JSON))
+
+# On every build, generate an all_modules.txt file to be used for autocompleting
+# the m command. After timing this using $(shell date +"%s.%3N"), it only adds
+# 0.01 seconds to the internal master build, and will only rerun on builds that
+# rerun kati.
+$(file >$(PRODUCT_OUT)/all_modules.txt,$(subst $(space),$(newline),$(ALL_MODULES)))
diff --git a/core/tasks/sts-lite.mk b/core/tasks/sts-lite.mk
new file mode 100644
index 0000000..dee25d4
--- /dev/null
+++ b/core/tasks/sts-lite.mk
@@ -0,0 +1,40 @@
+# Copyright (C) 2022 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.
+
+ifneq ($(wildcard test/sts/README-sts-sdk.md),)
+test_suite_name := sts-lite
+test_suite_tradefed := sts-tradefed
+test_suite_readme := test/sts/README-sts-sdk.md
+sts_sdk_zip := $(HOST_OUT)/$(test_suite_name)/sts-sdk.zip
+
+include $(BUILD_SYSTEM)/tasks/tools/compatibility.mk
+
+sts_sdk_samples := $(call intermediates-dir-for,ETC,sts-sdk-samples.zip)/sts-sdk-samples.zip
+
+$(sts_sdk_zip): STS_LITE_ZIP := $(compatibility_zip)
+$(sts_sdk_zip): STS_SDK_SAMPLES := $(sts_sdk_samples)
+$(sts_sdk_zip): $(MERGE_ZIPS) $(ZIP2ZIP) $(compatibility_zip) $(sts_sdk_samples)
+ rm -f $@ $(STS_LITE_ZIP)_filtered
+ $(ZIP2ZIP) -i $(STS_LITE_ZIP) -o $(STS_LITE_ZIP)_filtered \
+ -x android-sts-lite/tools/sts-tradefed-tests.jar \
+ 'android-sts-lite/tools/*:sts-test/libs/' \
+ 'android-sts-lite/testcases/*:sts-test/utils/'
+ $(MERGE_ZIPS) $@ $(STS_LITE_ZIP)_filtered $(STS_SDK_SAMPLES)
+ rm -f $(STS_LITE_ZIP)_filtered
+
+.PHONY: sts-sdk
+sts-sdk: $(sts_sdk_zip)
+$(call dist-for-goals, sts-sdk, $(sts_sdk_zip))
+
+endif
diff --git a/core/tasks/tools/compatibility.mk b/core/tasks/tools/compatibility.mk
index a5f162a..9400890 100644
--- a/core/tasks/tools/compatibility.mk
+++ b/core/tasks/tools/compatibility.mk
@@ -51,7 +51,7 @@
$(test_suite_jdk): PRIVATE_SUBDIR := $(test_suite_subdir)
$(test_suite_jdk): $(shell find $(test_suite_jdk_dir) -type f | sort)
$(test_suite_jdk): $(SOONG_ZIP)
- $(SOONG_ZIP) -o $@ -P $(PRIVATE_SUBDIR)/jdk -C $(PRIVATE_JDK_DIR) -D $(PRIVATE_JDK_DIR)
+ $(SOONG_ZIP) -o $@ -P $(PRIVATE_SUBDIR)/jdk -C $(PRIVATE_JDK_DIR) -D $(PRIVATE_JDK_DIR) -sha256
$(call declare-license-metadata,$(test_suite_jdk),SPDX-license-identifier-GPL-2.0-with-classpath-exception,permissive,\
$(test_suite_jdk_dir)/legal/java.base/LICENSE,JDK,prebuilts/jdk/$(notdir $(patsubst %/,%,$(dir $(test_suite_jdk_dir)))))
@@ -123,7 +123,7 @@
cp $(PRIVATE_TOOLS) $(PRIVATE_OUT_DIR)/tools
$(if $(PRIVATE_DYNAMIC_CONFIG),$(hide) cp $(PRIVATE_DYNAMIC_CONFIG) $(PRIVATE_OUT_DIR)/testcases/$(PRIVATE_SUITE_NAME).dynamic)
find $(PRIVATE_RESOURCES) | sort >$@.list
- $(SOONG_ZIP) -d -o $@.tmp -C $(dir $@) -l $@.list
+ $(SOONG_ZIP) -d -o $@.tmp -C $(dir $@) -l $@.list -sha256
$(MERGE_ZIPS) $@ $@.tmp $(PRIVATE_JDK)
rm -f $@.tmp
# Build a list of tests
diff --git a/core/tasks/wvts.mk b/core/tasks/wvts.mk
new file mode 100644
index 0000000..a79f613
--- /dev/null
+++ b/core/tasks/wvts.mk
@@ -0,0 +1,30 @@
+# Copyright (C) 2022 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.
+
+# Widevine test suite for non-GMS partners: go/android-wvts
+ifneq ($(wildcard test/wvts/tools/wvts-tradefed/README),)
+test_suite_name := wvts
+test_suite_tradefed := wvts-tradefed
+test_suite_dynamic_config := test/wvts/tools/wvts-tradefed/DynamicConfig.xml
+test_suite_readme := test/wvts/tools/wvts-tradefed/README
+
+$(call declare-1p-target,$(test_suite_dynamic_config),wvts)
+$(call declare-1p-target,$(test_suite_readme),wvts)
+
+include $(BUILD_SYSTEM)/tasks/tools/compatibility.mk
+
+.PHONY: wvts
+wvts: $(compatibility_zip) $(compatibility_tests_list_zip)
+$(call dist-for-goals, wvts, $(compatibility_zip) $(compatibility_tests_list_zip))
+endif
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index a7d023f..a664b9d 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -103,7 +103,7 @@
# 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 := 2022-10-05
+ PLATFORM_SECURITY_PATCH := 2023-02-05
endif
include $(BUILD_SYSTEM)/version_util.mk
diff --git a/envsetup.sh b/envsetup.sh
index bc206c4..0272624 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -1,3 +1,55 @@
+# Copyright (C) 2022 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.
+
+# gettop is duplicated here and in shell_utils.mk, because it's difficult
+# to find shell_utils.make without it for all the novel ways this file can be
+# sourced. Other common functions should only be in one place or the other.
+function _gettop_once
+{
+ local TOPFILE=build/make/core/envsetup.mk
+ if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then
+ # The following circumlocution ensures we remove symlinks from TOP.
+ (cd "$TOP"; PWD= /bin/pwd)
+ else
+ if [ -f $TOPFILE ] ; then
+ # The following circumlocution (repeated below as well) ensures
+ # that we record the true directory name and not one that is
+ # faked up with symlink names.
+ PWD= /bin/pwd
+ else
+ local HERE=$PWD
+ local T=
+ while [ \( ! \( -f $TOPFILE \) \) -a \( "$PWD" != "/" \) ]; do
+ \cd ..
+ T=`PWD= /bin/pwd -P`
+ done
+ \cd "$HERE"
+ if [ -f "$T/$TOPFILE" ]; then
+ echo "$T"
+ fi
+ fi
+ fi
+}
+T=$(_gettop_once)
+if [ ! "$T" ]; then
+ echo "Couldn't locate the top of the tree. Always source build/envsetup.sh from the root of the tree." >&2
+ return 1
+fi
+IMPORTING_ENVSETUP=true source $T/build/make/shell_utils.sh
+
+
+# Help
function hmm() {
cat <<EOF
@@ -27,6 +79,7 @@
- ggrep: Greps on all local Gradle files.
- gogrep: Greps on all local Go files.
- jgrep: Greps on all local Java files.
+- jsongrep: Greps on all local Json files.
- ktgrep: Greps on all local Kotlin files.
- resgrep: Greps on all local res/*.xml files.
- mangrep: Greps on all local AndroidManifest.xml files.
@@ -35,6 +88,8 @@
- rsgrep: Greps on all local Rust files.
- sepgrep: Greps on all local sepolicy files.
- sgrep: Greps on all local source files.
+- tomlgrep: Greps on all local Toml files.
+- pygrep: Greps on all local Python files.
- godir: Go to the directory containing a file.
- allmod: List all modules.
- gomod: Go to the directory containing a module.
@@ -173,7 +228,10 @@
return 1
}
-function setpaths()
+
+# Add directories to PATH that are dependent on the lunch target.
+# For directories that are not lunch-specific, add them in set_global_paths
+function set_lunch_paths()
{
local T=$(gettop)
if [ ! "$T" ]; then
@@ -185,93 +243,80 @@
# #
# 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. #
+ # This function sets ANDROID_LUNCH_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. #
# #
##################################################################
- # Note: on windows/cygwin, ANDROID_BUILD_PATHS will contain spaces
+ # Note: on windows/cygwin, ANDROID_LUNCH_BUILD_PATHS will contain spaces
# due to "C:\Program Files" being in the path.
- # out with the old
- if [ -n "$ANDROID_BUILD_PATHS" ] ; then
- export PATH=${PATH/$ANDROID_BUILD_PATHS/}
+ # Handle compat with the old ANDROID_BUILD_PATHS variable.
+ # TODO: Remove this after we think everyone has lunched again.
+ if [ -z "$ANDROID_LUNCH_BUILD_PATHS" -a -n "$ANDROID_BUILD_PATHS" ] ; then
+ ANDROID_LUNCH_BUILD_PATHS="$ANDROID_BUILD_PATHS"
+ ANDROID_BUILD_PATHS=
fi
if [ -n "$ANDROID_PRE_BUILD_PATHS" ] ; then
export PATH=${PATH/$ANDROID_PRE_BUILD_PATHS/}
# strip leading ':', if any
export PATH=${PATH/:%/}
+ ANDROID_PRE_BUILD_PATHS=
fi
- # and in with the new
+ # Out with the old...
+ if [ -n "$ANDROID_LUNCH_BUILD_PATHS" ] ; then
+ export PATH=${PATH/$ANDROID_LUNCH_BUILD_PATHS/}
+ fi
- export ANDROID_DEV_SCRIPTS=$T/development/scripts:$T/prebuilts/devtools/tools
+ # And in with the new...
+ ANDROID_LUNCH_BUILD_PATHS=$(get_abs_build_var SOONG_HOST_OUT_EXECUTABLES)
+ ANDROID_LUNCH_BUILD_PATHS+=:$(get_abs_build_var HOST_OUT_EXECUTABLES)
- # add kernel specific binaries
- case $(uname -s) in
- Linux)
- export ANDROID_DEV_SCRIPTS=$ANDROID_DEV_SCRIPTS:$T/prebuilts/misc/linux-x86/dtc:$T/prebuilts/misc/linux-x86/libufdt
- ;;
- *)
- ;;
- esac
-
- ANDROID_BUILD_PATHS=$(get_build_var ANDROID_BUILD_PATHS)
- ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS:$ANDROID_DEV_SCRIPTS
-
- # Append llvm binutils prebuilts path to ANDROID_BUILD_PATHS.
+ # Append llvm binutils prebuilts path to ANDROID_LUNCH_BUILD_PATHS.
local ANDROID_LLVM_BINUTILS=$(get_abs_build_var ANDROID_CLANG_PREBUILTS)/llvm-binutils-stable
- ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS:$ANDROID_LLVM_BINUTILS
+ ANDROID_LUNCH_BUILD_PATHS+=:$ANDROID_LLVM_BINUTILS
# Set up ASAN_SYMBOLIZER_PATH for SANITIZE_HOST=address builds.
export ASAN_SYMBOLIZER_PATH=$ANDROID_LLVM_BINUTILS/llvm-symbolizer
- # If prebuilts/android-emulator/<system>/ exists, prepend it to our PATH
- # to ensure that the corresponding 'emulator' binaries are used.
- case $(uname -s) in
- Darwin)
- ANDROID_EMULATOR_PREBUILTS=$T/prebuilts/android-emulator/darwin-x86_64
- ;;
- Linux)
- ANDROID_EMULATOR_PREBUILTS=$T/prebuilts/android-emulator/linux-x86_64
- ;;
- *)
- ANDROID_EMULATOR_PREBUILTS=
- ;;
- esac
- if [ -n "$ANDROID_EMULATOR_PREBUILTS" -a -d "$ANDROID_EMULATOR_PREBUILTS" ]; then
- ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS:$ANDROID_EMULATOR_PREBUILTS
- export ANDROID_EMULATOR_PREBUILTS
- fi
-
- # Append asuite prebuilts path to ANDROID_BUILD_PATHS.
+ # Append asuite prebuilts path to ANDROID_LUNCH_BUILD_PATHS.
local os_arch=$(get_build_var HOST_PREBUILT_TAG)
- local ACLOUD_PATH="$T/prebuilts/asuite/acloud/$os_arch"
- local AIDEGEN_PATH="$T/prebuilts/asuite/aidegen/$os_arch"
- local ATEST_PATH="$T/prebuilts/asuite/atest/$os_arch"
- ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS:$ACLOUD_PATH:$AIDEGEN_PATH:$ATEST_PATH
-
- export ANDROID_BUILD_PATHS=$(tr -s : <<<"${ANDROID_BUILD_PATHS}:")
- export PATH=$ANDROID_BUILD_PATHS$PATH
-
- # out with the duplicate old
- if [ -n $ANDROID_PYTHONPATH ]; then
- export PYTHONPATH=${PYTHONPATH//$ANDROID_PYTHONPATH/}
- fi
- # and in with the new
- export ANDROID_PYTHONPATH=$T/development/python-packages:
- if [ -n $VENDOR_PYTHONPATH ]; then
- ANDROID_PYTHONPATH=$ANDROID_PYTHONPATH$VENDOR_PYTHONPATH
- fi
- export PYTHONPATH=$ANDROID_PYTHONPATH$PYTHONPATH
+ ANDROID_LUNCH_BUILD_PATHS+=:$T/prebuilts/asuite/acloud/$os_arch
+ ANDROID_LUNCH_BUILD_PATHS+=:$T/prebuilts/asuite/aidegen/$os_arch
+ ANDROID_LUNCH_BUILD_PATHS+=:$T/prebuilts/asuite/atest/$os_arch
export ANDROID_JAVA_HOME=$(get_abs_build_var ANDROID_JAVA_HOME)
export JAVA_HOME=$ANDROID_JAVA_HOME
export ANDROID_JAVA_TOOLCHAIN=$(get_abs_build_var ANDROID_JAVA_TOOLCHAIN)
- export ANDROID_PRE_BUILD_PATHS=$ANDROID_JAVA_TOOLCHAIN:
- export PATH=$ANDROID_PRE_BUILD_PATHS$PATH
+ ANDROID_LUNCH_BUILD_PATHS+=:$ANDROID_JAVA_TOOLCHAIN
+
+ # Fix up PYTHONPATH
+ if [ -n $ANDROID_PYTHONPATH ]; then
+ export PYTHONPATH=${PYTHONPATH//$ANDROID_PYTHONPATH/}
+ fi
+ # //development/python-packages contains both a pseudo-PYTHONPATH which
+ # mimics an already assembled venv, but also contains real Python packages
+ # that are not in that layout until they are installed. We can fake it for
+ # the latter type by adding the package source directories to the PYTHONPATH
+ # directly. For the former group, we only need to add the python-packages
+ # directory itself.
+ #
+ # This could be cleaned up by converting the remaining packages that are in
+ # the first category into a typical python source layout (that is, another
+ # layer of directory nesting) and automatically adding all subdirectories of
+ # python-packages to the PYTHONPATH instead of manually curating this. We
+ # can't convert the packages like adb to the other style because doing so
+ # would prevent exporting type info from those packages.
+ #
+ # http://b/266688086
+ export ANDROID_PYTHONPATH=$T/development/python-packages/adb:$T/development/python-packages:
+ if [ -n $VENDOR_PYTHONPATH ]; then
+ ANDROID_PYTHONPATH=$ANDROID_PYTHONPATH$VENDOR_PYTHONPATH
+ fi
+ export PYTHONPATH=$ANDROID_PYTHONPATH$PYTHONPATH
unset ANDROID_PRODUCT_OUT
export ANDROID_PRODUCT_OUT=$(get_abs_build_var PRODUCT_OUT)
@@ -289,25 +334,67 @@
unset ANDROID_TARGET_OUT_TESTCASES
export ANDROID_TARGET_OUT_TESTCASES=$(get_abs_build_var TARGET_OUT_TESTCASES)
- # needed for building linux on MacOS
- # TODO: fix the path
- #export HOST_EXTRACFLAGS="-I "$T/system/kernel_headers/host_include
+ # Finally, set PATH
+ export PATH=$ANDROID_LUNCH_BUILD_PATHS:$PATH
}
-function bazel()
+# Add directories to PATH that are NOT dependent on the lunch target.
+# For directories that are lunch-specific, add them in set_lunch_paths
+function set_global_paths()
{
- if which bazel &>/dev/null; then
- >&2 echo "NOTE: bazel() function sourced from Android's envsetup.sh is being used instead of $(which bazel)"
- >&2 echo
- fi
-
- local T="$(gettop)"
+ local T=$(gettop)
if [ ! "$T" ]; then
- >&2 echo "Couldn't locate the top of the Android tree. Try setting TOP. This bazel() function cannot be used outside of the AOSP directory."
+ echo "Couldn't locate the top of the tree. Try setting TOP."
return
fi
- "$T/tools/bazel" "$@"
+ ##################################################################
+ # #
+ # Read me before you modify this code #
+ # #
+ # This function sets ANDROID_GLOBAL_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 envsetup.sh can be sourced #
+ # more than once and still have working paths. #
+ # #
+ ##################################################################
+
+ # Out with the old...
+ if [ -n "$ANDROID_GLOBAL_BUILD_PATHS" ] ; then
+ export PATH=${PATH/$ANDROID_GLOBAL_BUILD_PATHS/}
+ fi
+
+ # And in with the new...
+ ANDROID_GLOBAL_BUILD_PATHS=$T/build/bazel/bin
+ ANDROID_GLOBAL_BUILD_PATHS+=:$T/development/scripts
+ ANDROID_GLOBAL_BUILD_PATHS+=:$T/prebuilts/devtools/tools
+
+ # add kernel specific binaries
+ if [ $(uname -s) = Linux ] ; then
+ ANDROID_GLOBAL_BUILD_PATHS+=:$T/prebuilts/misc/linux-x86/dtc
+ ANDROID_GLOBAL_BUILD_PATHS+=:$T/prebuilts/misc/linux-x86/libufdt
+ fi
+
+ # If prebuilts/android-emulator/<system>/ exists, prepend it to our PATH
+ # to ensure that the corresponding 'emulator' binaries are used.
+ case $(uname -s) in
+ Darwin)
+ ANDROID_EMULATOR_PREBUILTS=$T/prebuilts/android-emulator/darwin-x86_64
+ ;;
+ Linux)
+ ANDROID_EMULATOR_PREBUILTS=$T/prebuilts/android-emulator/linux-x86_64
+ ;;
+ *)
+ ANDROID_EMULATOR_PREBUILTS=
+ ;;
+ esac
+ if [ -n "$ANDROID_EMULATOR_PREBUILTS" -a -d "$ANDROID_EMULATOR_PREBUILTS" ]; then
+ ANDROID_GLOBAL_BUILD_PATHS+=:$ANDROID_EMULATOR_PREBUILTS
+ export ANDROID_EMULATOR_PREBUILTS
+ fi
+
+ # Finally, set PATH
+ export PATH=$ANDROID_GLOBAL_BUILD_PATHS:$PATH
}
function printconfig()
@@ -322,7 +409,7 @@
function set_stuff_for_environment()
{
- setpaths
+ set_lunch_paths
set_sequence_number
export ANDROID_BUILD_TOP=$(gettop)
@@ -426,9 +513,7 @@
# Lunch must be run in the topdir, but this way we get a clear error
# message, instead of FileNotFound.
local T=$(multitree_gettop)
- if [ -n "$T" ]; then
- "$T/orchestrator/build/orchestrator/core/lunch.py" "$@"
- else
+ if [ -z "$T" ]; then
_multitree_lunch_error
return 1
fi
@@ -912,33 +997,6 @@
destroy_build_var_cache
}
-function gettop
-{
- local TOPFILE=build/make/core/envsetup.mk
- if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then
- # The following circumlocution ensures we remove symlinks from TOP.
- (cd "$TOP"; PWD= /bin/pwd)
- else
- if [ -f $TOPFILE ] ; then
- # The following circumlocution (repeated below as well) ensures
- # that we record the true directory name and not one that is
- # faked up with symlink names.
- PWD= /bin/pwd
- else
- local HERE=$PWD
- local T=
- while [ \( ! \( -f $TOPFILE \) \) -a \( "$PWD" != "/" \) ]; do
- \cd ..
- T=`PWD= /bin/pwd -P`
- done
- \cd "$HERE"
- if [ -f "$T/$TOPFILE" ]; then
- echo "$T"
- fi
- fi
- fi
-}
-
# TODO: Merge into gettop as part of launching multitree
function multitree_gettop
{
@@ -1195,6 +1253,18 @@
-exec grep --color -n "$@" {} +
}
+function jsongrep()
+{
+ find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.json" \
+ -exec grep --color -n "$@" {} +
+}
+
+function tomlgrep()
+{
+ find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.toml" \
+ -exec grep --color -n "$@" {} +
+}
+
function ktgrep()
{
find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.kt" \
@@ -1239,6 +1309,12 @@
-exec grep --color -n "$@" {} +
}
+function pygrep()
+{
+ find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.py" \
+ -exec grep --color -n "$@" {} +
+}
+
case `uname -s` in
Darwin)
function mgrep()
@@ -1564,12 +1640,10 @@
fi
}
-# List all modules for the current device, as cached in module-info.json. If any build change is
-# made and it should be reflected in the output, you should run 'refreshmod' first.
+# List all modules for the current device, as cached in all_modules.txt. If any build change is
+# made and it should be reflected in the output, you should run `m nothing` first.
function allmod() {
- verifymodinfo || return 1
-
- python3 -c "import json; print('\n'.join(sorted(json.load(open('$ANDROID_PRODUCT_OUT/module-info.json')).keys())))"
+ cat $ANDROID_PRODUCT_OUT/all_modules.txt 2>/dev/null
}
# Return the Bazel label of a Soong module if it is converted with bp2build.
@@ -1586,9 +1660,9 @@
#
# For a snappy result, use the latest generated version in soong_injection,
# and ask users to run m bp2build if it doesn't exist.
- converted_json="out/soong/soong_injection/metrics/converted_modules_path_map.json"
+ converted_json="$(get_abs_build_var OUT_DIR)/soong/soong_injection/metrics/converted_modules_path_map.json"
- if [ ! -f $(gettop)/${converted_json} ]; then
+ if [ ! -f ${converted_json} ]; then
echo "bp2build files not found. Have you ran 'm bp2build'?" >&2
return 1
fi
@@ -1748,7 +1822,7 @@
function _complete_android_module_names() {
local word=${COMP_WORDS[COMP_CWORD]}
- COMPREPLY=( $(QUIET_VERIFYMODINFO=true allmod | grep -E "^$word") )
+ COMPREPLY=( $(allmod | grep -E "^$word") )
}
# Print colored exit condition
@@ -1807,11 +1881,6 @@
color_reset=""
fi
- if [[ "x${USE_RBE}" == "x" && $mins -gt 15 && "${ANDROID_BUILD_ENVIRONMENT_CONFIG}" == "googler" ]]; then
- echo
- echo "${color_warning}Start using RBE (http://go/build-fast) to get faster builds!${color_reset}"
- fi
-
echo
if [ $ret -eq 0 ] ; then
echo -n "${color_success}#### build completed successfully "
@@ -1842,59 +1911,6 @@
fi
)
-# Convenience entry point (like m) to use Bazel in AOSP.
-function b()
-(
- # zsh breaks posix by not doing string-splitting on unquoted args by default.
- # See https://zsh.sourceforge.io/Guide/zshguide05.html section 5.4.4.
- # Tell it to emulate Bourne shell for this function.
- if [ -n "$ZSH_VERSION" ]; then emulate -L sh; fi
-
- # Look for the --run-soong-tests flag and skip passing --skip-soong-tests to Soong if present
- local bazel_args=""
- local skip_tests="--skip-soong-tests"
- for i in $@; do
- if [[ $i != "--run-soong-tests" ]]; then
- bazel_args+="$i "
- else
- skip_tests=""
- fi
- done
-
- # Generate BUILD, bzl files into the synthetic Bazel workspace (out/soong/workspace).
- # RBE is disabled because it's not used with b builds and adds overhead: b/251441524
- USE_RBE=false _trigger_build "all-modules" bp2build $skip_tests USE_BAZEL_ANALYSIS= || return 1
- # Then, run Bazel using the synthetic workspace as the --package_path.
- if [[ -z "$bazel_args" ]]; then
- # If there are no args, show help and exit.
- bazel help
- else
- # Else, always run with the bp2build configuration, which sets Bazel's package path to the synthetic workspace.
- # Add the --config=bp2build after the first argument that doesn't start with a dash. That should be the bazel
- # command. (build, test, run, ect) If the --config was added at the end, it wouldn't work with commands like:
- # b run //foo -- --args-for-foo
- local config_set=0
-
- # Represent the args as an array, not a string.
- local bazel_args_with_config=()
- for arg in $bazel_args; do
- if [[ $arg == "--" && $config_set -ne 1 ]]; # if we find --, insert config argument here
- then
- bazel_args_with_config+=("--config=bp2build -- ")
- config_set=1
- else
- bazel_args_with_config+=("$arg ")
- fi
- done
- if [[ $config_set -ne 1 ]]; then
- bazel_args_with_config+=("--config=bp2build ")
- fi
-
- # Call Bazel.
- bazel ${bazel_args_with_config[@]}
- fi
-)
-
function m()
(
_trigger_build "all-modules" "$@"
@@ -2046,13 +2062,7 @@
return
;;
esac
- if [[ -z "$OUT_DIR" ]]; then
- if [[ -z "$OUT_DIR_COMMON_BASE" ]]; then
- OUT_DIR=out
- else
- OUT_DIR=${OUT_DIR_COMMON_BASE}/${PWD##*/}
- fi
- fi
+ OUT_DIR="$(get_abs_build_var OUT_DIR)"
if [[ "$1" == "--regenerate" ]]; then
shift 1
NINJA_ARGS="-t commands $@" m
@@ -2071,5 +2081,7 @@
}
validate_current_shell
+set_global_paths
source_vendorsetup
addcompletions
+
diff --git a/finalize-aidl-vndk-sdk-resources.sh b/finalize-aidl-vndk-sdk-resources.sh
index e74ba71..f03fb43 100755
--- a/finalize-aidl-vndk-sdk-resources.sh
+++ b/finalize-aidl-vndk-sdk-resources.sh
@@ -3,6 +3,14 @@
set -ex
function finalize_aidl_vndk_sdk_resources() {
+ local PLATFORM_CODENAME='UpsideDownCake'
+ local PLATFORM_CODENAME_JAVA='UPSIDE_DOWN_CAKE'
+ local PLATFORM_SDK_VERSION='34'
+ local PLATFORM_VERSION='14'
+
+ local SDK_CODENAME="public static final int $PLATFORM_CODENAME_JAVA = CUR_DEVELOPMENT;"
+ local SDK_VERSION="public static final int $PLATFORM_CODENAME_JAVA = $PLATFORM_SDK_VERSION;"
+
local top="$(dirname "$0")"/../..
# default target to modify tree and build SDK
@@ -11,11 +19,13 @@
# This script is WIP and only finalizes part of the Android branch for release.
# The full process can be found at (INTERNAL) go/android-sdk-finalization.
- # VNDK snapshot (TODO)
- # SDK snapshots (TODO)
# Update references in the codebase to new API version (TODO)
# ...
+ # VNDK definitions for new SDK version
+ cp "$top/development/vndk/tools/definition-tool/datasets/vndk-lib-extra-list-current.txt" \
+ "$top/development/vndk/tools/definition-tool/datasets/vndk-lib-extra-list-$PLATFORM_SDK_VERSION.txt"
+
AIDL_TRANSITIVE_FREEZE=true $m aidl-freeze-api create_reference_dumps
# Generate ABI dumps
@@ -23,21 +33,44 @@
out/host/linux-x86/bin/create_reference_dumps \
-p aosp_arm64 --build-variant user
+ echo "NOTE: THIS INTENTIONALLY MAY FAIL AND REPAIR ITSELF (until 'DONE')"
# Update new versions of files. See update-vndk-list.sh (which requires envsetup.sh)
$m check-vndk-list || \
{ cp $top/out/soong/vndk/vndk.libraries.txt $top/build/make/target/product/gsi/current.txt; }
+ echo "DONE: THIS INTENTIONALLY MAY FAIL AND REPAIR ITSELF"
+
+ # Finalize SDK
+
+ # build/make
+ local version_defaults="$top/build/make/core/version_defaults.mk"
+ sed -i -e "s/PLATFORM_SDK_VERSION := .*/PLATFORM_SDK_VERSION := ${PLATFORM_SDK_VERSION}/g" $version_defaults
+ sed -i -e "s/PLATFORM_VERSION_LAST_STABLE := .*/PLATFORM_VERSION_LAST_STABLE := ${PLATFORM_VERSION}/g" $version_defaults
+ sed -i -e "s/sepolicy_major_vers := .*/sepolicy_major_vers := ${PLATFORM_SDK_VERSION}/g" "$top/build/make/core/config.mk"
+ cp "$top/build/make/target/product/gsi/current.txt" "$top/build/make/target/product/gsi/$PLATFORM_SDK_VERSION.txt"
+
+ # build/soong
+ sed -i -e "/:.*$((${PLATFORM_SDK_VERSION}-1)),/a \\\t\t\t\"${PLATFORM_CODENAME}\": ${PLATFORM_SDK_VERSION}," "$top/build/soong/android/api_levels.go"
+
+ # cts
+ echo ${PLATFORM_VERSION} > "$top/cts/tests/tests/os/assets/platform_releases.txt"
+ sed -i -e "s/EXPECTED_SDK = $((${PLATFORM_SDK_VERSION}-1))/EXPECTED_SDK = ${PLATFORM_SDK_VERSION}/g" "$top/cts/tests/tests/os/src/android/os/cts/BuildVersionTest.java"
+
+ # libcore
+ sed -i "s%$SDK_CODENAME%$SDK_VERSION%g" "$top/libcore/dalvik/src/main/java/dalvik/annotation/compat/VersionCodes.java"
+
+ # platform_testing
+ local version_codes="$top/platform_testing/libraries/compatibility-common-util/src/com/android/compatibility/common/util/VersionCodes.java"
+ sed -i -e "/=.*$((${PLATFORM_SDK_VERSION}-1));/a \\ ${SDK_VERSION}" $version_codes
# Finalize resources
"$top/frameworks/base/tools/aapt2/tools/finalize_res.py" \
"$top/frameworks/base/core/res/res/values/public-staging.xml" \
"$top/frameworks/base/core/res/res/values/public-final.xml"
- # SDK finalization
- local sdk_codename='public static final int UPSIDE_DOWN_CAKE = CUR_DEVELOPMENT;'
- local sdk_version='public static final int UPSIDE_DOWN_CAKE = 34;'
- local sdk_build="$top/frameworks/base/core/java/android/os/Build.java"
-
- sed -i "s%$sdk_codename%$sdk_version%g" $sdk_build
+ # frameworks/base
+ sed -i "s%$SDK_CODENAME%$SDK_VERSION%g" "$top/frameworks/base/core/java/android/os/Build.java"
+ sed -i -e "/=.*$((${PLATFORM_SDK_VERSION}-1)),/a \\ SDK_${PLATFORM_CODENAME_JAVA} = ${PLATFORM_SDK_VERSION}," "$top/frameworks/base/tools/aapt/SdkConstants.h"
+ sed -i -e "/=.*$((${PLATFORM_SDK_VERSION}-1)),/a \\ SDK_${PLATFORM_CODENAME_JAVA} = ${PLATFORM_SDK_VERSION}," "$top/frameworks/base/tools/aapt2/SdkConstants.h"
# Force update current.txt
$m clobber
diff --git a/finalize-cleanup.sh b/finalize-cleanup.sh
index efa2707..c62a97c 100755
--- a/finalize-cleanup.sh
+++ b/finalize-cleanup.sh
@@ -9,8 +9,8 @@
repo selfupdate
repo forall -c '\
- git checkout . ; git clean -fdx ;\
- git checkout @ ; git b fina-step1 -D ; git reset --hard; \
+ git checkout . ; git revert --abort ; git clean -fdx ;\
+ git checkout @ ; git branch fina-step1 -D ; git reset --hard; \
repo start fina-step1 ; git checkout @ ; git b fina-step1 -D ;'
}
diff --git a/finalize-locally-mainline-sdk.sh b/finalize-locally-mainline-sdk.sh
new file mode 100755
index 0000000..c72ef8c
--- /dev/null
+++ b/finalize-locally-mainline-sdk.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+set -ex
+
+function finalize_locally_mainline_sdk() {
+ local MAINLINE_EXTENSION='6'
+
+ local top="$(dirname "$0")"/../..
+
+ # Bump SDK extension version.
+ "$top/packages/modules/SdkExtensions/gen_sdk/bump_sdk.sh" ${MAINLINE_EXTENSION}
+
+ local version_defaults="$top/build/make/core/version_defaults.mk"
+ sed -i -e "s/PLATFORM_SDK_EXTENSION_VERSION := .*/PLATFORM_SDK_EXTENSION_VERSION := ${MAINLINE_EXTENSION}/g" $version_defaults
+
+ # Build modules SDKs.
+ TARGET_BUILD_VARIANT=userdebug UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true "$top/vendor/google/build/mainline_modules_sdks.sh"
+
+ # Update prebuilts.
+ "$top/prebuilts/build-tools/path/linux-x86/python3" "$top/packages/modules/common/tools/finalize_sdk.py" -l -b 0 -f ${MAINLINE_EXTENSION} -r '' 0
+}
+
+finalize_locally_mainline_sdk
+
diff --git a/finalize-sdk-rel.sh b/finalize-sdk-rel.sh
new file mode 100755
index 0000000..b19e56a
--- /dev/null
+++ b/finalize-sdk-rel.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+set -ex
+
+function finalize_sdk_rel() {
+ local DEV_SRC_DIR="$(dirname "$0")"/../..
+ local BUILD_PREFIX='UP1A'
+ local PLATFORM_CODENAME='UpsideDownCake'
+ local PLATFORM_VERSION='14'
+ local PLATFORM_SDK_VERSION='34'
+
+ # default target to modify tree and build SDK
+ local m="$DEV_SRC_DIR/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
+
+ # adb keys
+ $m adb
+ LOGNAME=android-eng HOSTNAME=google.com "$DEV_SRC_DIR/out/host/linux-x86/bin/adb" keygen "$DEV_SRC_DIR/vendor/google/security/adb/${PLATFORM_VERSION}.adb_key"
+
+ # build/make/core/version_defaults.mk
+ sed -i -e "s/PLATFORM_VERSION_CODENAME.${BUILD_PREFIX} := .*/PLATFORM_VERSION_CODENAME.${BUILD_PREFIX} := REL/g" "$DEV_SRC_DIR/build/make/core/version_defaults.mk"
+
+ # cts
+ echo "$PLATFORM_VERSION" > "$DEV_SRC_DIR/cts/tests/tests/os/assets/platform_versions.txt"
+ git -C "$DEV_SRC_DIR/cts" mv hostsidetests/theme/assets/${PLATFORM_CODENAME} hostsidetests/theme/assets/${PLATFORM_SDK_VERSION}
+
+ # system/sepolicy
+ mkdir -p "$DEV_SRC_DIR/system/sepolicy/prebuilts/api/${PLATFORM_SDK_VERSION}.0/"
+ cp -r "$DEV_SRC_DIR/system/sepolicy/public/" "$DEV_SRC_DIR/system/sepolicy/prebuilts/api/${PLATFORM_SDK_VERSION}.0/"
+ cp -r "$DEV_SRC_DIR/system/sepolicy/private/" "$DEV_SRC_DIR/system/sepolicy/prebuilts/api/${PLATFORM_SDK_VERSION}.0/"
+
+ # prebuilts/abi-dumps/ndk
+ mv "$DEV_SRC_DIR/prebuilts/abi-dumps/ndk/current" "$DEV_SRC_DIR/prebuilts/abi-dumps/ndk/$PLATFORM_SDK_VERSION"
+
+ # prebuilts/abi-dumps/vndk
+ mv "$DEV_SRC_DIR/prebuilts/abi-dumps/vndk/$PLATFORM_CODENAME" "$DEV_SRC_DIR/prebuilts/abi-dumps/vndk/$PLATFORM_SDK_VERSION"
+
+ # prebuilts/abi-dumps/platform
+ mv "$DEV_SRC_DIR/prebuilts/abi-dumps/platform/current" "$DEV_SRC_DIR/prebuilts/abi-dumps/platform/$PLATFORM_SDK_VERSION"
+}
+
+finalize_sdk_rel
+
diff --git a/finalize-step-1-for-build-target.sh b/finalize-step-1-for-build-target.sh
new file mode 100755
index 0000000..8b35a1d
--- /dev/null
+++ b/finalize-step-1-for-build-target.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+# Continuous Integration script for *-finalization-1 branches.
+# Reverts previous finalization script commits and runs local build.
+
+set -ex
+
+function finalize_step_1_main() {
+ local top="$(dirname "$0")"/../..
+ local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
+
+ # vndk etc finalization
+ source $top/build/make/finalize-aidl-vndk-sdk-resources.sh
+
+ # build to confirm everything is OK
+ AIDL_FROZEN_REL=true $m
+}
+
+finalize_step_1_main
diff --git a/finalize-step-1.sh b/finalize-step-1.sh
index 9f87b6c..8871862 100755
--- a/finalize-step-1.sh
+++ b/finalize-step-1.sh
@@ -6,13 +6,18 @@
# set -ex
-function revert_local_changes() {
+function revert_to_unfinalized_state() {
repo forall -c '\
- git checkout . ; git clean -fdx ;\
- git checkout @ ; git b fina-step1 -D ; git reset --hard; \
+ git checkout . ; git revert --abort ; git clean -fdx ;\
+ git checkout @ ; git branch fina-step1 -D ; git reset --hard; \
repo start fina-step1 ; git checkout @ ; git b fina-step1 -D ;\
- previousHash="$(git log --format=%H --no-merges --max-count=100 --grep ^FINALIZATION_STEP_1_SCRIPT_COMMIT)" ;\
- if [[ $previousHash ]]; then git revert --no-commit $previousHash ; fi ;'
+ baselineHash="$(git log --format=%H --no-merges --max-count=1 --grep ^FINALIZATION_STEP_1_BASELINE_COMMIT)" ;\
+ if [[ $baselineHash ]]; then
+ previousHash="$(git log --format=%H --no-merges --max-count=100 --grep ^FINALIZATION_STEP_1_SCRIPT_COMMIT $baselineHash..HEAD | tr \n \040)" ;\
+ else
+ previousHash="$(git log --format=%H --no-merges --max-count=100 --grep ^FINALIZATION_STEP_1_SCRIPT_COMMIT | tr \n \040)" ;\
+ fi ; \
+ if [[ $previousHash ]]; then git revert --no-commit --strategy=ort --strategy-option=ours $previousHash ; fi ;'
}
function commit_changes() {
@@ -21,17 +26,20 @@
repo start fina-step1 ;
git add -A . ;
git commit -m FINALIZATION_STEP_1_SCRIPT_COMMIT -m WILL_BE_AUTOMATICALLY_REVERTED ;
- repo upload --cbr --no-verify -t -y . ;
+ repo upload --cbr --no-verify -o nokeycheck -t -y . ;
git clean -fdx ; git reset --hard ;
fi'
}
function finalize_step_1_main() {
+ # deprecated, do not use
+ exit 1
+
local top="$(dirname "$0")"/../..
repo selfupdate
- revert_local_changes
+ revert_to_unfinalized_state
# vndk etc finalization
source $top/build/make/finalize-aidl-vndk-sdk-resources.sh
diff --git a/finalize-step-2-for-build-target.sh b/finalize-step-2-for-build-target.sh
new file mode 100755
index 0000000..b74fd03
--- /dev/null
+++ b/finalize-step-2-for-build-target.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# Continuous Integration script for *-finalization-2 branches.
+# Reverts previous finalization script commits and runs local build.
+
+set -ex
+
+function finalize_step_2_main() {
+ local top="$(dirname "$0")"/../..
+ local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
+
+ # vndk etc finalization
+ source $top/build/make/finalize-aidl-vndk-sdk-resources.sh
+
+ # prebuilts etc
+ source $top/build/make/finalize-sdk-rel.sh
+
+ # mainline sdk prebuilts
+ source $top/build/make/finalize-locally-mainline-sdk.sh
+
+ # build to confirm everything is OK
+ AIDL_FROZEN_REL=true $m
+}
+
+finalize_step_2_main
diff --git a/finalize-step-2.sh b/finalize-step-2.sh
new file mode 100755
index 0000000..ef80b2b
--- /dev/null
+++ b/finalize-step-2.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# Automation for finalize_branch_for_release.sh.
+# Sets up local environment, runs the finalization script and submits the results.
+# WIP:
+# - does not submit, only sends to gerrit.
+
+# set -ex
+
+function revert_to_unfinalized_state() {
+ repo forall -c '\
+ git checkout . ; git revert --abort ; git clean -fdx ;\
+ git checkout @ ; git branch fina-step2 -D ; git reset --hard; \
+ repo start fina-step2 ; git checkout @ ; git b fina-step2 -D ;\
+ baselineHash="$(git log --format=%H --no-merges --max-count=1 --grep ^FINALIZATION_STEP_2_BASELINE_COMMIT)" ;\
+ if [[ $baselineHash ]]; then
+ previousHash="$(git log --format=%H --no-merges --max-count=100 --grep ^FINALIZATION_STEP_2_SCRIPT_COMMIT $baselineHash..HEAD | tr \n \040)" ;\
+ else
+ previousHash="$(git log --format=%H --no-merges --max-count=100 --grep ^FINALIZATION_STEP_2_SCRIPT_COMMIT | tr \n \040)" ;\
+ fi ; \
+ if [[ $previousHash ]]; then git revert --no-commit --strategy=ort --strategy-option=ours $previousHash ; fi ;'
+}
+
+function commit_changes() {
+ repo forall -c '\
+ if [[ $(git status --short) ]]; then
+ repo start fina-step1 ;
+ git add -A . ;
+ git commit -m FINALIZATION_STEP_2_SCRIPT_COMMIT -m WILL_BE_AUTOMATICALLY_REVERTED ;
+ repo upload --cbr --no-verify -o nokeycheck -t -y . ;
+ git clean -fdx ; git reset --hard ;
+ fi'
+}
+
+function finalize_step_2_main() {
+ # deprecated, do not use
+ exit 1
+
+ local top="$(dirname "$0")"/../..
+
+ repo selfupdate
+
+ revert_to_unfinalized_state
+
+ # vndk etc finalization
+ source $top/build/make/finalize-aidl-vndk-sdk-resources.sh
+
+ # move all changes to fina-step1 branch and commit with a robot message
+ commit_changes
+}
+
+finalize_step_2_main
diff --git a/finalize_branch_for_release.sh b/finalize_branch_for_release.sh
index b46390d..9e9d6a1 100755
--- a/finalize_branch_for_release.sh
+++ b/finalize_branch_for_release.sh
@@ -17,7 +17,7 @@
# Resource/SDK finalization.
# In the future, we would want to actually turn the branch into the REL
# state and test with that.
- AIDL_FROZEN_REL=true $m droidcore
+ AIDL_FROZEN_REL=true $m
# Build SDK (TODO)
# lunch sdk...
diff --git a/shell_utils.sh b/shell_utils.sh
new file mode 100644
index 0000000..9de5a50
--- /dev/null
+++ b/shell_utils.sh
@@ -0,0 +1,74 @@
+# Copyright (C) 2022 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.
+
+function gettop
+{
+ local TOPFILE=build/make/core/envsetup.mk
+ # The ${TOP-} expansion allows this to work even with set -u
+ if [ -n "${TOP:-}" -a -f "${TOP:-}/$TOPFILE" ] ; then
+ # The following circumlocution ensures we remove symlinks from TOP.
+ (cd "$TOP"; PWD= /bin/pwd)
+ else
+ if [ -f $TOPFILE ] ; then
+ # The following circumlocution (repeated below as well) ensures
+ # that we record the true directory name and not one that is
+ # faked up with symlink names.
+ PWD= /bin/pwd
+ else
+ local HERE=$PWD
+ local T=
+ while [ \( ! \( -f $TOPFILE \) \) -a \( "$PWD" != "/" \) ]; do
+ \cd ..
+ T=`PWD= /bin/pwd -P`
+ done
+ \cd "$HERE"
+ if [ -f "$T/$TOPFILE" ]; then
+ echo "$T"
+ fi
+ fi
+ fi
+}
+
+# Sets TOP, or if the root of the tree can't be found, prints a message and
+# exits. Since this function exits, it should not be called from functions
+# defined in envsetup.sh.
+if [ -z "${IMPORTING_ENVSETUP:-}" ] ; then
+function require_top
+{
+ TOP=$(gettop)
+ if [[ ! $TOP ]] ; then
+ echo "Can not locate root of source tree. $(basename $0) must be run from within the Android source tree." >&2
+ exit 1
+ fi
+}
+fi
+
+function getoutdir
+{
+ local top=$(gettop)
+ local out_dir="${OUT_DIR:-}"
+ if [[ -z "${out_dir}" ]]; then
+ if [[ -n "${OUT_DIR_COMMON_BASE:-}" && -n "${top}" ]]; then
+ out_dir="${OUT_DIR_COMMON_BASE}/$(basename ${top})"
+ else
+ out_dir="out"
+ fi
+ fi
+ if [[ "${out_dir}" != /* ]]; then
+ out_dir="${top}/${out_dir}"
+ fi
+ echo "${out_dir}"
+}
+
+
diff --git a/target/board/Android.mk b/target/board/Android.mk
index baa3d3a..21c0c10 100644
--- a/target/board/Android.mk
+++ b/target/board/Android.mk
@@ -19,8 +19,11 @@
ifndef board_info_txt
board_info_txt := $(wildcard $(TARGET_DEVICE_DIR)/board-info.txt)
endif
-$(INSTALLED_ANDROID_INFO_TXT_TARGET): $(board_info_txt) build/make/tools/check_radio_versions.py
- $(hide) build/make/tools/check_radio_versions.py $< $(BOARD_INFO_CHECK)
+CHECK_RADIO_VERSIONS := $(HOST_OUT_EXECUTABLES)/check_radio_versions$(HOST_EXECUTABLE_SUFFIX)
+$(INSTALLED_ANDROID_INFO_TXT_TARGET): $(board_info_txt) $(CHECK_RADIO_VERSIONS)
+ $(hide) $(CHECK_RADIO_VERSIONS) \
+ --board_info_txt $(board_info_txt) \
+ --board_info_check $(BOARD_INFO_CHECK)
$(call pretty,"Generated: ($@)")
ifdef board_info_txt
$(hide) grep -v '#' $< > $@
diff --git a/target/board/BoardConfigEmuCommon.mk b/target/board/BoardConfigEmuCommon.mk
index f6e64a1..7a07d70 100644
--- a/target/board/BoardConfigEmuCommon.mk
+++ b/target/board/BoardConfigEmuCommon.mk
@@ -33,8 +33,8 @@
# emulator needs super.img
BOARD_BUILD_SUPER_IMAGE_BY_DEFAULT := true
- # 4G + 8M
- BOARD_SUPER_PARTITION_SIZE := 4303355904
+ # 8G + 8M
+ BOARD_SUPER_PARTITION_SIZE ?= 8598323200
BOARD_SUPER_PARTITION_GROUPS := emulator_dynamic_partitions
ifeq ($(QEMU_USE_SYSTEM_EXT_PARTITIONS),true)
@@ -56,8 +56,8 @@
vendor
endif
- # 4G
- BOARD_EMULATOR_DYNAMIC_PARTITIONS_SIZE := 4294967296
+ # 8G
+ BOARD_EMULATOR_DYNAMIC_PARTITIONS_SIZE ?= 8589934592
# in build environment to speed up make -j
ifeq ($(QEMU_DISABLE_AVB),true)
diff --git a/target/board/BoardConfigGsiCommon.mk b/target/board/BoardConfigGsiCommon.mk
index 8c634f6..4d95b33 100644
--- a/target/board/BoardConfigGsiCommon.mk
+++ b/target/board/BoardConfigGsiCommon.mk
@@ -3,6 +3,8 @@
# Common compile-time definitions for GSI
# Builds upon the mainline config.
#
+# See device/generic/common/README.md for more details.
+#
include build/make/target/board/BoardConfigMainlineCommon.mk
@@ -17,6 +19,12 @@
TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
TARGET_USERIMAGES_SPARSE_EROFS_DISABLED := true
+# Enable system_dlkm image for creating a symlink in GSI to support
+# the devices with system_dlkm partition
+BOARD_USES_SYSTEM_DLKMIMAGE := true
+BOARD_SYSTEM_DLKMIMAGE_FILE_SYSTEM_TYPE := ext4
+TARGET_COPY_OUT_SYSTEM_DLKM := system_dlkm
+
# GSI also includes make_f2fs to support userdata parition in f2fs
# for some devices
TARGET_USERIMAGES_USE_F2FS := true
diff --git a/target/product/AndroidProducts.mk b/target/product/AndroidProducts.mk
index 585630b..1e0ce19 100644
--- a/target/product/AndroidProducts.mk
+++ b/target/product/AndroidProducts.mk
@@ -36,6 +36,7 @@
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/aosp_arm64.mk \
$(LOCAL_DIR)/aosp_arm.mk \
+ $(LOCAL_DIR)/aosp_riscv64.mk \
$(LOCAL_DIR)/aosp_x86_64.mk \
$(LOCAL_DIR)/aosp_x86.mk \
$(LOCAL_DIR)/full.mk \
diff --git a/target/product/OWNERS b/target/product/OWNERS
index 61f7d45..008e4a2 100644
--- a/target/product/OWNERS
+++ b/target/product/OWNERS
@@ -5,6 +5,6 @@
per-file developer_gsi_keys.mk = file:/target/product/gsi/OWNERS
# Android Go
-per-file go_defaults.mk = gkaiser@google.com, rajekumar@google.com
-per-file go_defaults_512.mk = gkaiser@google.com, rajekumar@google.com
-per-file go_defaults_common.mk = gkaiser@google.com, rajekumar@google.com
+per-file go_defaults.mk = gkaiser@google.com, kushg@google.com, rajekumar@google.com
+per-file go_defaults_512.mk = gkaiser@google.com, kushg@google.com, rajekumar@google.com
+per-file go_defaults_common.mk = gkaiser@google.com, kushg@google.com, rajekumar@google.com
\ No newline at end of file
diff --git a/target/product/aosp_arm.mk b/target/product/aosp_arm.mk
index 90acc17..5f200aa 100644
--- a/target/product/aosp_arm.mk
+++ b/target/product/aosp_arm.mk
@@ -49,7 +49,7 @@
#
# All components inherited here go to vendor image
#
-$(call inherit-product-if-exists, device/generic/goldfish/arm32-vendor.mk)
+$(call inherit-product-if-exists, build/make/target/product/ramdisk_stub.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_x86/device.mk)
diff --git a/target/product/aosp_riscv64.mk b/target/product/aosp_riscv64.mk
index 518f8b1..436ff97 100644
--- a/target/product/aosp_riscv64.mk
+++ b/target/product/aosp_riscv64.mk
@@ -30,7 +30,8 @@
# GSI for system/product & support 64-bit apps only
$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit_only.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/mainline_system.mk)
+#$(call inherit-product, $(SRC_TARGET_DIR)/product/mainline_system.mk)
+TARGET_FLATTEN_APEX := false
#
# All components inherited here go to system_ext image
@@ -46,7 +47,7 @@
#
# All components inherited here go to vendor image
#
-#$(call inherit-product-if-exists, device/generic/goldfish/riscv64-vendor.mk)
+$(call inherit-product-if-exists, device/generic/goldfish/riscv64-vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_riscv64/device.mk)
@@ -57,6 +58,18 @@
$(call inherit-product, $(SRC_TARGET_DIR)/product/gsi_release.mk)
endif
+# TODO: this list should come via mainline_system.mk, but for now list
+# just the modules that work for riscv64.
+PRODUCT_PACKAGES := \
+ init.environ.rc \
+ init_first_stage \
+ init_system \
+ linker \
+ shell_and_utilities \
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/default_art_config.mk)
+PRODUCT_USES_DEFAULT_ART_CONFIG := false
+
PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += \
root/init.zygote64.rc
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 96d7b2f..b66d2c7 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -54,7 +54,6 @@
com.android.appsearch \
com.android.btservices \
com.android.conscrypt \
- com.android.cronet \
com.android.extservices \
com.android.i18n \
com.android.ipsec \
@@ -66,12 +65,14 @@
com.android.os.statsd \
com.android.permission \
com.android.resolv \
+ com.android.rkpd \
com.android.neuralnetworks \
com.android.scheduling \
com.android.sdkext \
com.android.tethering \
com.android.tzdata \
com.android.uwb \
+ com.android.virt \
com.android.wifi \
ContactsProvider \
content \
@@ -121,6 +122,7 @@
init_system \
input \
installd \
+ IntentResolver \
ip \
iptables \
ip-up-vpn \
@@ -202,7 +204,6 @@
libvulkan \
libwilhelm \
linker \
- linkerconfig \
llkd \
lmkd \
LocalTransport \
@@ -387,6 +388,7 @@
procrank \
profcollectd \
profcollectctl \
+ record_binder \
servicedispatcher \
showmap \
sqlite3 \
diff --git a/target/product/base_vendor.mk b/target/product/base_vendor.mk
index 7fb785c..3c4d62e 100644
--- a/target/product/base_vendor.mk
+++ b/target/product/base_vendor.mk
@@ -46,7 +46,7 @@
# Base modules and settings for the vendor partition.
PRODUCT_PACKAGES += \
- android.hardware.cas@1.2-service \
+ android.hardware.cas-service.example \
boringssl_self_test_vendor \
dumpsys_vendor \
fs_config_files_nonsystem \
@@ -81,7 +81,11 @@
endif
-# Base module when shipping api level is less than or equal to 29
+# Base modules when shipping api level is less than or equal to 33
+PRODUCT_PACKAGES_SHIPPING_API_LEVEL_33 += \
+ android.hardware.cas@1.2-service \
+
+# Base modules when shipping api level is less than or equal to 29
PRODUCT_PACKAGES_SHIPPING_API_LEVEL_29 += \
android.hardware.configstore@1.1-service \
vndservice \
diff --git a/target/product/cfi-common.mk b/target/product/cfi-common.mk
index 3aa2be7..11c01a2 100644
--- a/target/product/cfi-common.mk
+++ b/target/product/cfi-common.mk
@@ -26,8 +26,10 @@
frameworks/av/services \
frameworks/minikin \
hardware/broadcom/wlan/bcmdhd/wpa_supplicant_8_lib \
+ hardware/synaptics/wlan/synadhd/wpa_supplicant_8_lib \
hardware/interfaces/nfc \
- hardware/qcom/wlan/qcwcn/wpa_supplicant_8_lib \
+ hardware/qcom/wlan/legacy/qcwcn/wpa_supplicant_8_lib \
+ hardware/qcom/wlan/wcn6740/qcwcn/wpa_supplicant_8_lib \
hardware/interfaces/keymaster \
hardware/interfaces/security \
packages/modules/Bluetooth/system \
diff --git a/target/product/default_art_config.mk b/target/product/default_art_config.mk
index 901302e..752b199 100644
--- a/target/product/default_art_config.mk
+++ b/target/product/default_art_config.mk
@@ -70,6 +70,7 @@
com.android.tethering:framework-connectivity-t \
com.android.tethering:framework-tethering \
com.android.uwb:framework-uwb \
+ com.android.virt:framework-virtualization \
com.android.wifi:framework-wifi \
# List of system_server classpath jars delivered via apex.
@@ -82,6 +83,7 @@
com.android.art:service-art \
com.android.media:service-media-s \
com.android.permission:service-permission \
+ com.android.rkpd:service-rkp \
# Use $(wildcard) to avoid referencing the profile in thin manifests that don't have the
# art project.
@@ -112,3 +114,5 @@
dalvik.vm.image-dex2oat-Xmx=64m \
dalvik.vm.dex2oat-Xms=64m \
dalvik.vm.dex2oat-Xmx=512m \
+
+PRODUCT_ENABLE_UFFD_GC := false # TODO(jiakaiz): Change this to "default".
diff --git a/target/product/full.mk b/target/product/full.mk
index 782280d..945957f 100644
--- a/target/product/full.mk
+++ b/target/product/full.mk
@@ -19,7 +19,7 @@
# build quite specifically for the emulator, and might not be
# entirely appropriate to inherit from for on-device configurations.
-$(call inherit-product-if-exists, device/generic/goldfish/arm32-vendor.mk)
+$(call inherit-product-if-exists, build/make/target/product/ramdisk_stub.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/generic/device.mk)
diff --git a/target/product/generic_ramdisk.mk b/target/product/generic_ramdisk.mk
index c7dcd60..ebac62f 100644
--- a/target/product/generic_ramdisk.mk
+++ b/target/product/generic_ramdisk.mk
@@ -29,11 +29,16 @@
adb_debug.prop \
userdebug_plat_sepolicy.cil \
+
+# For targets using dedicated recovery partition, generic ramdisk
+# might be relocated to recovery partition
_my_paths := \
$(TARGET_COPY_OUT_RAMDISK)/ \
$(TARGET_COPY_OUT_DEBUG_RAMDISK)/ \
system/usr/share/zoneinfo/tz_version \
system/usr/share/zoneinfo/tzdata \
+ $(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk/system \
+
# We use the "relaxed" version here because tzdata / tz_version is only produced
# by this makefile on a subset of devices.
diff --git a/target/product/go_defaults_common.mk b/target/product/go_defaults_common.mk
index 7f19615..51a1ef6 100644
--- a/target/product/go_defaults_common.mk
+++ b/target/product/go_defaults_common.mk
@@ -36,12 +36,6 @@
# Do not generate libartd.
PRODUCT_ART_TARGET_INCLUDE_DEBUG_BUILD := false
-# Do not spin up a separate process for the network stack on go devices, use an in-process APK.
-PRODUCT_PACKAGES += InProcessNetworkStack
-PRODUCT_PACKAGES += CellBroadcastAppPlatform
-PRODUCT_PACKAGES += CellBroadcastServiceModulePlatform
-PRODUCT_PACKAGES += com.android.tethering.inprocess
-
# Strip the local variable table and the local variable type table to reduce
# the size of the system image. This has no bearing on stack traces, but will
# leave less information available via JDWP.
diff --git a/target/product/gsi/33.txt b/target/product/gsi/33.txt
index 03a143d..db05f93 100644
--- a/target/product/gsi/33.txt
+++ b/target/product/gsi/33.txt
@@ -79,7 +79,6 @@
VNDK-core: android.hardware.graphics.allocator@4.0.so
VNDK-core: android.hardware.graphics.bufferqueue@1.0.so
VNDK-core: android.hardware.graphics.bufferqueue@2.0.so
-VNDK-core: android.hardware.health-V1-ndk.so
VNDK-core: android.hardware.health.storage-V1-ndk.so
VNDK-core: android.hardware.identity-V4-ndk.so
VNDK-core: android.hardware.ir-V1-ndk.so
diff --git a/target/product/gsi/Android.mk b/target/product/gsi/Android.mk
index d02dc7a..107c94f 100644
--- a/target/product/gsi/Android.mk
+++ b/target/product/gsi/Android.mk
@@ -126,8 +126,13 @@
endef
VNDK_ABI_DUMP_DIR := prebuilts/abi-dumps/vndk/$(PLATFORM_VNDK_VERSION)
-NDK_ABI_DUMP_DIR := prebuilts/abi-dumps/ndk/$(PLATFORM_VNDK_VERSION)
-PLATFORM_ABI_DUMP_DIR := prebuilts/abi-dumps/platform/$(PLATFORM_VNDK_VERSION)
+ifeq (REL,$(PLATFORM_VERSION_CODENAME))
+ NDK_ABI_DUMP_DIR := prebuilts/abi-dumps/ndk/$(PLATFORM_SDK_VERSION)
+ PLATFORM_ABI_DUMP_DIR := prebuilts/abi-dumps/platform/$(PLATFORM_SDK_VERSION)
+else
+ NDK_ABI_DUMP_DIR := prebuilts/abi-dumps/ndk/current
+ PLATFORM_ABI_DUMP_DIR := prebuilts/abi-dumps/platform/current
+endif
VNDK_ABI_DUMPS := $(call find-abi-dump-paths,$(VNDK_ABI_DUMP_DIR))
NDK_ABI_DUMPS := $(call find-abi-dump-paths,$(NDK_ABI_DUMP_DIR))
PLATFORM_ABI_DUMPS := $(call find-abi-dump-paths,$(PLATFORM_ABI_DUMP_DIR))
@@ -141,7 +146,7 @@
$(check-vndk-abi-dump-list-timestamp): PRIVATE_STUB_LIBRARIES := $(STUB_LIBRARIES)
$(check-vndk-abi-dump-list-timestamp):
$(eval added_vndk_abi_dumps := $(strip $(sort $(filter-out \
- $(call filter-abi-dump-paths,LLNDK VNDK-SP VNDK-core,$(PRIVATE_LSDUMP_PATHS)), \
+ $(call filter-abi-dump-paths,VNDK-SP VNDK-core,$(PRIVATE_LSDUMP_PATHS)), \
$(notdir $(VNDK_ABI_DUMPS))))))
$(if $(added_vndk_abi_dumps), \
echo -e "Found unexpected ABI reference dump files under $(VNDK_ABI_DUMP_DIR). It is caused by mismatch between Android.bp and the dump files. Run \`find \$${ANDROID_BUILD_TOP}/$(VNDK_ABI_DUMP_DIR) '(' -name $(subst $(space), -or -name ,$(added_vndk_abi_dumps)) ')' -delete\` to delete the dump files.")
@@ -154,7 +159,7 @@
echo -e "Found unexpected ABI reference dump files under $(NDK_ABI_DUMP_DIR). It is caused by mismatch between Android.bp and the dump files. Run \`find \$${ANDROID_BUILD_TOP}/$(NDK_ABI_DUMP_DIR) '(' -name $(subst $(space), -or -name ,$(added_ndk_abi_dumps)) ')' -delete\` to delete the dump files.")
$(eval added_platform_abi_dumps := $(strip $(sort $(filter-out \
- $(call filter-abi-dump-paths,PLATFORM,$(PRIVATE_LSDUMP_PATHS)) \
+ $(call filter-abi-dump-paths,LLNDK PLATFORM,$(PRIVATE_LSDUMP_PATHS)) \
$(addsuffix .lsdump,$(PRIVATE_STUB_LIBRARIES)), \
$(notdir $(PLATFORM_ABI_DUMPS))))))
$(if $(added_platform_abi_dumps), \
diff --git a/target/product/gsi/current.txt b/target/product/gsi/current.txt
index 94892dc..474cb20 100644
--- a/target/product/gsi/current.txt
+++ b/target/product/gsi/current.txt
@@ -7,6 +7,7 @@
LLNDK: libbinder_ndk.so
LLNDK: libc.so
LLNDK: libcgrouprc.so
+LLNDK: libcom.android.tethering.connectivity_native.so
LLNDK: libdl.so
LLNDK: libft2.so
LLNDK: liblog.so
@@ -20,8 +21,7 @@
LLNDK: libvulkan.so
VNDK-SP: android.hardware.common-V2-ndk.so
VNDK-SP: android.hardware.common.fmq-V1-ndk.so
-VNDK-SP: android.hardware.graphics.allocator-V1-ndk.so
-VNDK-SP: android.hardware.graphics.common-V3-ndk.so
+VNDK-SP: android.hardware.graphics.common-V4-ndk.so
VNDK-SP: android.hardware.graphics.common@1.0.so
VNDK-SP: android.hardware.graphics.common@1.1.so
VNDK-SP: android.hardware.graphics.common@1.2.so
@@ -30,6 +30,7 @@
VNDK-SP: android.hardware.graphics.mapper@2.1.so
VNDK-SP: android.hardware.graphics.mapper@3.0.so
VNDK-SP: android.hardware.graphics.mapper@4.0.so
+VNDK-SP: android.hardware.graphics.allocator-V2-ndk.so
VNDK-SP: android.hardware.renderscript@1.0.so
VNDK-SP: android.hidl.memory.token@1.0.so
VNDK-SP: android.hidl.memory@1.0-impl.so
diff --git a/target/product/gsi_release.mk b/target/product/gsi_release.mk
index 20493be..09d4bc9 100644
--- a/target/product/gsi_release.mk
+++ b/target/product/gsi_release.mk
@@ -23,6 +23,8 @@
# - Released GSI contains more VNDK packages to support old version vendors
# - etc.
#
+# See device/generic/common/README.md for more details.
+#
BUILDING_GSI := true
@@ -83,6 +85,7 @@
PRODUCT_BUILD_VENDOR_IMAGE := false
PRODUCT_BUILD_SUPER_PARTITION := false
PRODUCT_BUILD_SUPER_EMPTY_IMAGE := false
+PRODUCT_BUILD_SYSTEM_DLKM_IMAGE := false
PRODUCT_EXPORT_BOOT_IMAGE_TO_DIST := true
# Always build modules from source
diff --git a/target/product/module_common.mk b/target/product/module_common.mk
index 54f3949..ec670ee 100644
--- a/target/product/module_common.mk
+++ b/target/product/module_common.mk
@@ -25,3 +25,8 @@
# Builds using a module product should build modules from source, even if
# BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE says otherwise.
PRODUCT_MODULE_BUILD_FROM_SOURCE := true
+
+# Build sdk from source if the branch is not using slim manifests.
+ifneq (,$(strip $(wildcard frameworks/base/Android.bp)))
+ UNBUNDLED_BUILD_SDKS_FROM_SOURCE := true
+endif
diff --git a/target/product/ramdisk_stub.mk b/target/product/ramdisk_stub.mk
new file mode 100644
index 0000000..2a0b752
--- /dev/null
+++ b/target/product/ramdisk_stub.mk
@@ -0,0 +1,18 @@
+#
+# Copyright 2022 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.
+#
+
+PRODUCT_COPY_FILES += \
+ build/make/target/product/ramdisk_stub.mk:$(TARGET_COPY_OUT_VENDOR_RAMDISK)/nonempty
diff --git a/target/product/runtime_libart.mk b/target/product/runtime_libart.mk
index 1ebd4ab..bd4fd1c 100644
--- a/target/product/runtime_libart.mk
+++ b/target/product/runtime_libart.mk
@@ -95,7 +95,6 @@
# The thermal cutoff value is currently set to THERMAL_STATUS_MODERATE.
PRODUCT_SYSTEM_PROPERTIES += \
dalvik.vm.usejit=true \
- dalvik.vm.usejitprofiles=true \
dalvik.vm.dexopt.secondary=true \
dalvik.vm.dexopt.thermal-cutoff=2 \
dalvik.vm.appimageformat=lz4
@@ -165,3 +164,13 @@
dalvik.vm.usap_pool_size_max?=3 \
dalvik.vm.usap_pool_size_min?=1 \
dalvik.vm.usap_pool_refill_delay_ms?=3000
+
+# Allow dexopt files that are side-effects of already allowlisted files.
+# This is only necessary when ART is prebuilt.
+ifeq (false,$(ART_MODULE_BUILD_FROM_SOURCE))
+ PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += \
+ system/framework/%.art \
+ system/framework/%.oat \
+ system/framework/%.odex \
+ system/framework/%.vdex
+endif
diff --git a/target/product/sdk_phone_armv7.mk b/target/product/sdk_phone_armv7.mk
index 6c88b44..888505b 100644
--- a/target/product/sdk_phone_armv7.mk
+++ b/target/product/sdk_phone_armv7.mk
@@ -45,7 +45,7 @@
#
# All components inherited here go to vendor image
#
-$(call inherit-product-if-exists, device/generic/goldfish/arm32-vendor.mk)
+$(call inherit-product-if-exists, build/make/target/product/ramdisk_stub.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/emulator_arm/device.mk)
diff --git a/target/product/virtual_ab_ota/android_t_baseline.mk b/target/product/virtual_ab_ota/android_t_baseline.mk
index 716c8e0..418aaa4 100644
--- a/target/product/virtual_ab_ota/android_t_baseline.mk
+++ b/target/product/virtual_ab_ota/android_t_baseline.mk
@@ -12,29 +12,11 @@
# 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 enables baseline features, such as io_uring,
-# userspace merge, etc. But sets compression method to none.
-# This .mk file also removes snapuserd from vendor ramdisk,
-# as T launching devices will have init_boot which has snapuserd
-# in generic ramdisk.
-# T launching devices should include this .mk file, and configure
-# compression algorithm by setting
-# PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD to gz or brotli. Complete
-# set of supported algorithms can be found in
-# system/core/fs_mgr/libsnapshot/cow_writer.cpp
-
-PRODUCT_VIRTUAL_AB_OTA := true
-
-PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.enabled=true
-
-PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.enabled=true
-PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
-PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.io_uring.enabled=true
-PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true
-
-PRODUCT_VIRTUAL_AB_COMPRESSION := true
-PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD ?= none
-PRODUCT_PACKAGES += \
- snapuserd \
-
+# This file should be used only for T launching devices. We maintain
+# this file just for backward compatibility for T launch devices
+# so that build doesn't break.
+#
+# All U+ launching devices should instead use vabc_features.mk.
+$(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota/vabc_features.mk)
diff --git a/target/product/virtual_ab_ota/compression.mk b/target/product/virtual_ab_ota/compression.mk
index d5bd2a5..dc1ee3e 100644
--- a/target/product/virtual_ab_ota/compression.mk
+++ b/target/product/virtual_ab_ota/compression.mk
@@ -19,6 +19,12 @@
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.enabled=true
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.io_uring.enabled=true
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.batch_writes=true
+
+# Enabling this property, will improve OTA install time
+# but will use an additional CPU core
+# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.threads=true
+
PRODUCT_VIRTUAL_AB_COMPRESSION := true
PRODUCT_PACKAGES += \
snapuserd.vendor_ramdisk \
diff --git a/target/product/virtual_ab_ota/vabc_features.mk b/target/product/virtual_ab_ota/vabc_features.mk
new file mode 100644
index 0000000..874eb9c
--- /dev/null
+++ b/target/product/virtual_ab_ota/vabc_features.mk
@@ -0,0 +1,46 @@
+#
+# Copyright (C) 2022 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 enables baseline features, such as io_uring,
+# userspace merge, etc. But sets compression method to none.
+# This .mk file also removes snapuserd from vendor ramdisk,
+# as T launching devices will have init_boot which has snapuserd
+# in generic ramdisk.
+#
+# T and U launching devices should include this .mk file, and configure
+# compression algorithm by setting
+# PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD to lz4, gz or brotli. Complete
+# set of supported algorithms can be found in
+# system/core/fs_mgr/libsnapshot/cow_writer.cpp
+
+PRODUCT_VIRTUAL_AB_OTA := true
+
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.enabled=true
+
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.enabled=true
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.io_uring.enabled=true
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.batch_writes=true
+
+# Enabling this property, will improve OTA install time
+# but will use an additional CPU core
+# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.threads=true
+
+PRODUCT_VIRTUAL_AB_COMPRESSION := true
+PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD ?= none
+PRODUCT_PACKAGES += \
+ snapuserd \
+
diff --git a/tests/b_tests.sh b/tests/b_tests.sh
index f4e043c..13f156d 100755
--- a/tests/b_tests.sh
+++ b/tests/b_tests.sh
@@ -18,12 +18,19 @@
source $(dirname $0)/../envsetup.sh
+# lunch required to set up PATH to use b
+lunch aosp_arm64
+
test_target=//build/bazel/scripts/difftool:difftool
b build "$test_target"
b build "$test_target" --run-soong-tests
b build --run-soong-tests "$test_target"
b --run-soong-tests build "$test_target"
+# Test that the bazel server can be restarted once shut down. If run in a
+# docker container, you need to run the docker container with --init or
+# have some other process as PID 1 that can reap zombies.
+b shutdown
b cquery 'kind(test, //build/bazel/examples/android_app/...)' --config=android
b run $test_target -- --help >/dev/null
diff --git a/tests/inherits_in_regular_variables/inherit1.rbc b/tests/inherits_in_regular_variables/inherit1.rbc
new file mode 100644
index 0000000..4ce8825
--- /dev/null
+++ b/tests/inherits_in_regular_variables/inherit1.rbc
@@ -0,0 +1,21 @@
+# Copyright 2023 Google LLC
+#
+# 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
+#
+# https://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.
+
+load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+
+ cfg.setdefault("PRODUCT_PACKAGES", [])
+ cfg["PRODUCT_PACKAGES"] += ["bar"]
diff --git a/tests/inherits_in_regular_variables/product.rbc b/tests/inherits_in_regular_variables/product.rbc
new file mode 100644
index 0000000..c193c65
--- /dev/null
+++ b/tests/inherits_in_regular_variables/product.rbc
@@ -0,0 +1,27 @@
+# Copyright 2023 Google LLC
+#
+# 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
+#
+# https://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.
+
+load("//build/make/core:product_config.rbc", "rblf")
+load(":inherit1.rbc", _inherit1_init = "init")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+
+ cfg.setdefault("PRODUCT_PACKAGES", [])
+ cfg["PRODUCT_PACKAGES"] += ["foo"]
+
+ g["PRODUCT_PACKAGES_COPY"] = cfg["PRODUCT_PACKAGES"]
+
+ rblf.inherit(handle, "test/inherit1", _inherit1_init)
+
diff --git a/tests/inherits_in_regular_variables/test.rbc b/tests/inherits_in_regular_variables/test.rbc
new file mode 100644
index 0000000..3a76d8a
--- /dev/null
+++ b/tests/inherits_in_regular_variables/test.rbc
@@ -0,0 +1,30 @@
+# Copyright 2023 Google LLC
+#
+# 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
+#
+# https://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.
+
+load("//build/make/core:product_config.rbc", "rblf")
+load("//build/make/tests/input_variables.rbc", input_variables_init = "init")
+load(":product.rbc", "init")
+
+
+def assert_eq(expected, actual):
+ if expected != actual:
+ fail("Expected '%s', got '%s'" % (expected, actual))
+
+def test():
+ (globals, globals_base) = rblf.product_configuration("test/device", init, input_variables_init)
+ assert_eq(["foo", "bar"], globals["PRODUCTS.test/device.mk.PRODUCT_PACKAGES"])
+ assert_eq(["foo", ("test/inherit1",)], globals["PRODUCT_PACKAGES_COPY"])
+
+ # Ideally we would check that rblf.printvars returns the correct result, but we don't have
+ # a good way to intercept its output or mock rblf_cli
diff --git a/tests/run.rbc b/tests/run.rbc
index c6dfeba..33583eb 100644
--- a/tests/run.rbc
+++ b/tests/run.rbc
@@ -28,6 +28,7 @@
load("//build/make/tests/single_value_inheritance:test.rbc", test_single_value_inheritance = "test")
load("//build/make/tests/artifact_path_requirements:test.rbc", test_artifact_path_requirements = "test")
load("//build/make/tests/prefixed_sort_order:test.rbc", test_prefixed_sort_order = "test")
+load("//build/make/tests/inherits_in_regular_variables:test.rbc", test_inherits_in_regular_variables = "test")
def assert_eq(expected, actual):
if expected != actual:
@@ -45,6 +46,11 @@
assert_eq("a b c", rblf.mkstrip(" a b \n c \t"))
assert_eq("1", rblf.mkstrip("1 "))
+assert_eq(["a", "b"], rblf.words("a b"))
+assert_eq(["a", "b", "c"], rblf.words(["a b", "c"]))
+# 1-tuple like we use in product variables
+assert_eq(["a b", ("c",)], rblf.words(["a b", ("c",)]))
+
assert_eq("b1 b2", rblf.mksubst("a", "b", "a1 a2"))
assert_eq(["b1", "x2"], rblf.mksubst("a", "b", ["a1", "x2"]))
@@ -162,6 +168,18 @@
assert_eq({"A_LIST_VARIABLE": ["foo", "bar"]}, board_globals)
assert_eq({"A_LIST_VARIABLE": ["foo"]}, board_globals_base)
+g = {"FOO": "a", "BAR": "c", "BAZ": "e"}
+cfg = {"FOO": "b", "BAR": "d", "BAZ": "f"}
+rblf.clear_var_list(g, struct(cfg=cfg), "FOO BAR NEWVAR")
+assert_eq("", g["FOO"])
+assert_eq("", cfg["FOO"])
+assert_eq("", g["BAR"])
+assert_eq("", cfg["BAR"])
+assert_eq("e", g["BAZ"])
+assert_eq("f", cfg["BAZ"])
+assert_eq("", g.get("NEWVAR"))
+
test_single_value_inheritance()
test_artifact_path_requirements()
test_prefixed_sort_order()
+test_inherits_in_regular_variables()
diff --git a/tools/Android.bp b/tools/Android.bp
index bd326f1..1f0d406 100644
--- a/tools/Android.bp
+++ b/tools/Android.bp
@@ -54,3 +54,13 @@
name: "build-runfiles",
srcs: ["build-runfiles.cc"],
}
+
+python_binary_host {
+ name: "check_radio_versions",
+ srcs: ["check_radio_versions.py"],
+}
+
+python_binary_host {
+ name: "check_elf_file",
+ srcs: ["check_elf_file.py"],
+}
diff --git a/tools/atree/fs.cpp b/tools/atree/fs.cpp
index 6cd080e..d004e97 100644
--- a/tools/atree/fs.cpp
+++ b/tools/atree/fs.cpp
@@ -177,7 +177,7 @@
} else {
// Split the arguments if more than 1
char* cmd = strdup(strip_cmd);
- const char** args = (const char**) malloc(sizeof(const char*) * (num_args + 2));
+ const char** args = (const char**) calloc((num_args + 2), sizeof(const char*));
const char** curr = args;
char* s = cmd;
diff --git a/tools/auto_gen_test_config.py b/tools/auto_gen_test_config.py
index 943f238..ce64160 100755
--- a/tools/auto_gen_test_config.py
+++ b/tools/auto_gen_test_config.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright (C) 2017 The Android Open Source Project
#
@@ -69,7 +69,7 @@
module = os.path.splitext(os.path.basename(target_config))[0]
instrumentation = instrumentation_elements[0]
manifest = manifest_elements[0]
- if instrumentation.attributes.has_key(ATTRIBUTE_LABEL):
+ if ATTRIBUTE_LABEL in instrumentation.attributes:
label = instrumentation.attributes[ATTRIBUTE_LABEL].value
else:
label = module
diff --git a/tools/check_elf_file.py b/tools/check_elf_file.py
index 0b80226..51ec23b 100755
--- a/tools/check_elf_file.py
+++ b/tools/check_elf_file.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright (C) 2019 The Android Open Source Project
#
@@ -196,11 +196,7 @@
def _read_llvm_readobj(cls, elf_file_path, header, llvm_readobj):
"""Run llvm-readobj and parse the output."""
cmd = [llvm_readobj, '--dynamic-table', '--dyn-symbols', elf_file_path]
- proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, _ = proc.communicate()
- rc = proc.returncode
- if rc != 0:
- raise subprocess.CalledProcessError(rc, cmd, out)
+ out = subprocess.check_output(cmd, text=True)
lines = out.splitlines()
return cls._parse_llvm_readobj(elf_file_path, header, lines)
@@ -411,8 +407,7 @@
# Chech whether all DT_NEEDED entries are specified.
for lib in self._file_under_test.dt_needed:
if lib not in specified_sonames:
- self._error('DT_NEEDED "{}" is not specified in shared_libs.'
- .format(lib.decode('utf-8')))
+ self._error(f'DT_NEEDED "{lib}" is not specified in shared_libs.')
missing_shared_libs = True
if missing_shared_libs:
@@ -467,7 +462,7 @@
"""Check whether all undefined symbols are resolved to a definition."""
all_elf_files = [self._file_under_test] + self._shared_libs
missing_symbols = []
- for sym, imported_vers in self._file_under_test.imported.iteritems():
+ for sym, imported_vers in self._file_under_test.imported.items():
for imported_ver in imported_vers:
lib = self._find_symbol_from_libs(all_elf_files, sym, imported_ver)
if not lib:
@@ -475,16 +470,14 @@
if missing_symbols:
for sym, ver in sorted(missing_symbols):
- sym = sym.decode('utf-8')
if ver:
- sym += '@' + ver.decode('utf-8')
- self._error('Unresolved symbol: {}'.format(sym))
+ sym += '@' + ver
+ self._error(f'Unresolved symbol: {sym}')
self._note()
self._note('Some dependencies might be changed, thus the symbol(s) '
'above cannot be resolved.')
- self._note('Please re-build the prebuilt file: "{}".'
- .format(self._file_path))
+ self._note(f'Please re-build the prebuilt file: "{self._file_path}".')
self._note()
self._note('If this is a new prebuilt file and it is designed to have '
diff --git a/tools/check_radio_versions.py b/tools/check_radio_versions.py
index ebe621f..d1d50e6 100755
--- a/tools/check_radio_versions.py
+++ b/tools/check_radio_versions.py
@@ -22,11 +22,18 @@
except ImportError:
from sha import sha as sha1
-if len(sys.argv) < 2:
+import argparse
+
+parser = argparse.ArgumentParser()
+parser.add_argument("--board_info_txt", nargs="?", required=True)
+parser.add_argument("--board_info_check", nargs="*", required=True)
+args = parser.parse_args()
+
+if not args.board_info_txt:
sys.exit(0)
build_info = {}
-f = open(sys.argv[1])
+f = open(args.board_info_txt)
for line in f:
line = line.strip()
if line.startswith("require"):
@@ -36,7 +43,7 @@
bad = False
-for item in sys.argv[2:]:
+for item in args.board_info_check:
key, fn = item.split(":", 1)
values = build_info.get(key, None)
@@ -52,8 +59,8 @@
try:
f = open(fn + ".sha1")
except IOError:
- if not bad: print
- print "*** Error opening \"%s.sha1\"; can't verify %s" % (fn, key)
+ if not bad: print()
+ print("*** Error opening \"%s.sha1\"; can't verify %s" % (fn, key))
bad = True
continue
for line in f:
@@ -63,17 +70,17 @@
versions[h] = v
if digest not in versions:
- if not bad: print
- print "*** SHA-1 hash of \"%s\" doesn't appear in \"%s.sha1\"" % (fn, fn)
+ if not bad: print()
+ print("*** SHA-1 hash of \"%s\" doesn't appear in \"%s.sha1\"" % (fn, fn))
bad = True
continue
if versions[digest] not in values:
- if not bad: print
- print "*** \"%s\" is version %s; not any %s allowed by \"%s\"." % (
- fn, versions[digest], key, sys.argv[1])
+ if not bad: print()
+ print("*** \"%s\" is version %s; not any %s allowed by \"%s\"." % (
+ fn, versions[digest], key, args.board_info_txt))
bad = True
if bad:
- print
+ print()
sys.exit(1)
diff --git a/tools/compare_fileslist.py b/tools/compare_fileslist.py
deleted file mode 100755
index 1f507d8..0000000
--- a/tools/compare_fileslist.py
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import cgi, os, string, sys
-
-def IsDifferent(row):
- val = None
- for v in row:
- if v:
- if not val:
- val = v
- else:
- if val != v:
- return True
- return False
-
-def main(argv):
- inputs = argv[1:]
- data = {}
- index = 0
- for input in inputs:
- f = file(input, "r")
- lines = f.readlines()
- f.close()
- lines = map(string.split, lines)
- lines = map(lambda (x,y): (y,int(x)), lines)
- for fn,sz in lines:
- if not data.has_key(fn):
- data[fn] = {}
- data[fn][index] = sz
- index = index + 1
- rows = []
- for fn,sizes in data.iteritems():
- row = [fn]
- for i in range(0,index):
- if sizes.has_key(i):
- row.append(sizes[i])
- else:
- row.append(None)
- rows.append(row)
- rows = sorted(rows, key=lambda x: x[0])
- print """<html>
- <head>
- <style type="text/css">
- .fn, .sz, .z, .d {
- padding-left: 10px;
- padding-right: 10px;
- }
- .sz, .z, .d {
- text-align: right;
- }
- .fn {
- background-color: #ffffdd;
- }
- .sz {
- background-color: #ffffcc;
- }
- .z {
- background-color: #ffcccc;
- }
- .d {
- background-color: #99ccff;
- }
- </style>
- </head>
- <body>
- """
- print "<table>"
- print "<tr>"
- for input in inputs:
- combo = input.split(os.path.sep)[1]
- print " <td class='fn'>%s</td>" % cgi.escape(combo)
- print "</tr>"
-
- for row in rows:
- print "<tr>"
- for sz in row[1:]:
- if not sz:
- print " <td class='z'> </td>"
- elif IsDifferent(row[1:]):
- print " <td class='d'>%d</td>" % sz
- else:
- print " <td class='sz'>%d</td>" % sz
- print " <td class='fn'>%s</td>" % cgi.escape(row[0])
- print "</tr>"
- print "</table>"
- print "</body></html>"
-
-if __name__ == '__main__':
- main(sys.argv)
-
-
diff --git a/tools/compliance/Android.bp b/tools/compliance/Android.bp
index 2527df7..8e13f2f 100644
--- a/tools/compliance/Android.bp
+++ b/tools/compliance/Android.bp
@@ -131,6 +131,17 @@
testSrcs: ["cmd/xmlnotice/xmlnotice_test.go"],
}
+blueprint_go_binary {
+ name: "compliance_sbom",
+ srcs: ["cmd/sbom/sbom.go"],
+ deps: [
+ "compliance-module",
+ "blueprint-deptools",
+ "soong-response",
+ ],
+ testSrcs: ["cmd/sbom/sbom_test.go"],
+}
+
bootstrap_go_package {
name: "compliance-module",
srcs: [
diff --git a/tools/compliance/README.md b/tools/compliance/README.md
new file mode 100644
index 0000000..995d9ca
--- /dev/null
+++ b/tools/compliance/README.md
@@ -0,0 +1,101 @@
+# Compliance
+
+<!-- Much of this content appears too in doc.go
+When changing this file consider whether the change also applies to doc.go -->
+
+Package compliance provides an approved means for reading, consuming, and
+analyzing license metadata graphs.
+
+Assuming the license metadata and dependencies are fully and accurately
+recorded in the build system, any discrepancy between the official policy for
+open source license compliance and this code is **a bug in this code.**
+
+## Naming
+
+All of the code that directly reflects a policy decision belongs in a file with
+a name begninning `policy_`. Changes to these files need to be authored or
+reviewed by someone in OSPO or whichever successor group governs policy.
+
+The files with names not beginning `policy_` describe data types, and general,
+reusable algorithms.
+
+The source code for binary tools and utilities appears under the `cmd/`
+subdirectory. Other subdirectories contain reusable components that are not
+`compliance` per se.
+
+## Data Types
+
+A few principal types to understand are LicenseGraph, LicenseCondition, and
+ResolutionSet.
+
+### LicenseGraph
+
+A LicenseGraph is an immutable graph of the targets and dependencies reachable
+from a specific set of root targets. In general, the root targets will be the
+artifacts in a release or distribution. While conceptually immutable, parts of
+the graph may be loaded or evaluated lazily.
+
+Conceptually, the graph itself will always be a directed acyclic graph. One
+representation is a set of directed edges. Another is a set of nodes with
+directed edges to their dependencies.
+
+The edges have annotations, which can distinguish between build tools, runtime
+dependencies, and dependencies like 'contains' that make a derivative work.
+
+### LicenseCondition
+
+A LicenseCondition is an immutable tuple pairing a condition name with an
+originating target. e.g. Per current policy, a static library licensed under an
+MIT license would pair a "notice" condition with the static library target, and
+a dynamic license licensed under GPL would pair a "restricted" condition with
+the dynamic library target.
+
+### ResolutionSet
+
+A ResolutionSet is an immutable set of `AttachesTo`, `ActsOn`, `Resolves`
+tuples describing how license conditions apply to targets.
+
+`AttachesTo` is the trigger for acting. Distribution of the target invokes
+the policy.
+
+`ActsOn` is the target to share, give notice for, hide etc.
+
+`Resolves` is the set of conditions that the action resolves.
+
+For most condition types, `ActsOn` will be the target where the condition
+originated. For example, a notice condition policy means attribution or notice
+must be given for the target where the condition originates. Likewise, a
+proprietary condition policy means the privacy of the target where the
+condition originates must be respected. i.e. The thing acted on is the origin.
+
+Restricted conditions are different. The infectious nature of restricted often
+means sharing code that is not the target where the restricted condition
+originates. Linking an MIT library to a GPL library implies a policy to share
+the MIT library despite the MIT license having no source sharing requirement.
+
+In this case, one or more resolution tuples will have the MIT license module in
+`ActsOn` and the restricted condition originating at the GPL library module in
+`Resolves`. These tuples will `AttachTo` every target that depends on the GPL
+library because shipping any of those targets trigger the policy to share the
+code.
+
+## Processes
+
+### ReadLicenseGraph
+
+The principal means to ingest license metadata. Given the distribution targets,
+ReadLicenseGraph populates the LicenseGraph for those root targets.
+
+### NoticeIndex.IndexLicenseTexts
+
+IndexLicenseTexts reads, deduplicates and caches license texts for notice
+files. Also reads and caches project metadata for deriving library names.
+
+The algorithm for deriving library names has not been dictated by OSPO policy,
+but reflects a pragmatic attempt to comply with Android policy regarding
+unreleased product names, proprietary partner names etc.
+
+### projectmetadata.Index.MetadataForProjects
+
+MetadataForProjects reads, deduplicates and caches project METADATA files used
+for notice library names, and various properties appearing in SBOMs.
diff --git a/tools/compliance/cmd/checkshare/checkshare_test.go b/tools/compliance/cmd/checkshare/checkshare_test.go
index fdcab29..079691c 100644
--- a/tools/compliance/cmd/checkshare/checkshare_test.go
+++ b/tools/compliance/cmd/checkshare/checkshare_test.go
@@ -241,6 +241,59 @@
roots: []string{"lib/libd.so.meta_lic"},
expectedStdout: "PASS",
},
+ {
+ condition: "regressconcur",
+ name: "container",
+ roots: []string{"container.zip.meta_lic"},
+ expectedStdout: "FAIL",
+ expectedOutcomes: outcomeList{
+ &outcome{
+ target: "testdata/regressconcur/bin/bin1.meta_lic",
+ privacyCondition: "proprietary",
+ shareCondition: "restricted",
+ },
+ &outcome{
+ target: "testdata/regressconcur/bin/bin2.meta_lic",
+ privacyCondition: "proprietary",
+ shareCondition: "restricted",
+ },
+ &outcome{
+ target: "testdata/regressconcur/bin/bin3.meta_lic",
+ privacyCondition: "proprietary",
+ shareCondition: "restricted",
+ },
+ &outcome{
+ target: "testdata/regressconcur/bin/bin4.meta_lic",
+ privacyCondition: "proprietary",
+ shareCondition: "restricted",
+ },
+ &outcome{
+ target: "testdata/regressconcur/bin/bin5.meta_lic",
+ privacyCondition: "proprietary",
+ shareCondition: "restricted",
+ },
+ &outcome{
+ target: "testdata/regressconcur/bin/bin6.meta_lic",
+ privacyCondition: "proprietary",
+ shareCondition: "restricted",
+ },
+ &outcome{
+ target: "testdata/regressconcur/bin/bin7.meta_lic",
+ privacyCondition: "proprietary",
+ shareCondition: "restricted",
+ },
+ &outcome{
+ target: "testdata/regressconcur/bin/bin8.meta_lic",
+ privacyCondition: "proprietary",
+ shareCondition: "restricted",
+ },
+ &outcome{
+ target: "testdata/regressconcur/bin/bin9.meta_lic",
+ privacyCondition: "proprietary",
+ shareCondition: "restricted",
+ },
+ },
+ },
}
for _, tt := range tests {
t.Run(tt.condition+" "+tt.name, func(t *testing.T) {
diff --git a/tools/compliance/cmd/dumpgraph/dumpgraph_test.go b/tools/compliance/cmd/dumpgraph/dumpgraph_test.go
index d1deed3..e2d0db0 100644
--- a/tools/compliance/cmd/dumpgraph/dumpgraph_test.go
+++ b/tools/compliance/cmd/dumpgraph/dumpgraph_test.go
@@ -341,13 +341,13 @@
roots: []string{"highest.apex.meta_lic"},
ctx: context{stripPrefix: []string{"testdata/restricted/"}, labelConditions: true},
expectedOut: []string{
- "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:restricted_allows_dynamic_linking static",
+ "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:restricted_if_statically_linked static",
"bin/bin1.meta_lic:notice lib/libc.a.meta_lic:reciprocal static",
"bin/bin2.meta_lic:notice lib/libb.so.meta_lic:restricted dynamic",
"bin/bin2.meta_lic:notice lib/libd.so.meta_lic:notice dynamic",
"highest.apex.meta_lic:notice bin/bin1.meta_lic:notice static",
"highest.apex.meta_lic:notice bin/bin2.meta_lic:notice static",
- "highest.apex.meta_lic:notice lib/liba.so.meta_lic:restricted_allows_dynamic_linking static",
+ "highest.apex.meta_lic:notice lib/liba.so.meta_lic:restricted_if_statically_linked static",
"highest.apex.meta_lic:notice lib/libb.so.meta_lic:restricted static",
},
},
@@ -1011,7 +1011,7 @@
matchTarget("bin/bin1.meta_lic", "notice"),
matchTarget("bin/bin2.meta_lic", "notice"),
matchTarget("highest.apex.meta_lic", "notice"),
- matchTarget("lib/liba.so.meta_lic", "restricted_allows_dynamic_linking"),
+ matchTarget("lib/liba.so.meta_lic", "restricted_if_statically_linked"),
matchTarget("lib/libb.so.meta_lic", "restricted"),
matchTarget("lib/libc.a.meta_lic", "reciprocal"),
matchTarget("lib/libd.so.meta_lic", "notice"),
diff --git a/tools/compliance/cmd/dumpresolutions/dumpresolutions_test.go b/tools/compliance/cmd/dumpresolutions/dumpresolutions_test.go
index 63fd157..227942b 100644
--- a/tools/compliance/cmd/dumpresolutions/dumpresolutions_test.go
+++ b/tools/compliance/cmd/dumpresolutions/dumpresolutions_test.go
@@ -529,18 +529,18 @@
name: "apex",
roots: []string{"highest.apex.meta_lic"},
expectedOut: []string{
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic notice:restricted_allows_dynamic_linking",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic notice:restricted_if_statically_linked",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_if_statically_linked",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal:restricted_if_statically_linked",
"testdata/restricted/bin/bin2.meta_lic testdata/restricted/bin/bin2.meta_lic notice:restricted",
"testdata/restricted/bin/bin2.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/highest.apex.meta_lic testdata/restricted/bin/bin1.meta_lic notice:restricted_allows_dynamic_linking",
+ "testdata/restricted/highest.apex.meta_lic testdata/restricted/bin/bin1.meta_lic notice:restricted_if_statically_linked",
"testdata/restricted/highest.apex.meta_lic testdata/restricted/bin/bin2.meta_lic notice:restricted",
- "testdata/restricted/highest.apex.meta_lic testdata/restricted/highest.apex.meta_lic notice:restricted:restricted_allows_dynamic_linking",
- "testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "testdata/restricted/highest.apex.meta_lic testdata/restricted/highest.apex.meta_lic notice:restricted:restricted_if_statically_linked",
+ "testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_if_statically_linked",
"testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
- "testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal:restricted_if_statically_linked",
+ "testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_if_statically_linked",
"testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
},
},
@@ -550,18 +550,18 @@
roots: []string{"highest.apex.meta_lic"},
ctx: context{stripPrefix: []string{"testdata/restricted/"}},
expectedOut: []string{
- "bin/bin1.meta_lic bin/bin1.meta_lic notice:restricted_allows_dynamic_linking",
- "bin/bin1.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
- "bin/bin1.meta_lic lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
+ "bin/bin1.meta_lic bin/bin1.meta_lic notice:restricted_if_statically_linked",
+ "bin/bin1.meta_lic lib/liba.so.meta_lic restricted_if_statically_linked",
+ "bin/bin1.meta_lic lib/libc.a.meta_lic reciprocal:restricted_if_statically_linked",
"bin/bin2.meta_lic bin/bin2.meta_lic notice:restricted",
"bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic bin/bin1.meta_lic notice:restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic bin/bin1.meta_lic notice:restricted_if_statically_linked",
"highest.apex.meta_lic bin/bin2.meta_lic notice:restricted",
- "highest.apex.meta_lic highest.apex.meta_lic notice:restricted:restricted_allows_dynamic_linking",
- "highest.apex.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic highest.apex.meta_lic notice:restricted:restricted_if_statically_linked",
+ "highest.apex.meta_lic lib/liba.so.meta_lic restricted_if_statically_linked",
"highest.apex.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
- "lib/liba.so.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic lib/libc.a.meta_lic reciprocal:restricted_if_statically_linked",
+ "lib/liba.so.meta_lic lib/liba.so.meta_lic restricted_if_statically_linked",
"lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
},
},
@@ -590,18 +590,18 @@
stripPrefix: []string{"testdata/restricted/"},
},
expectedOut: []string{
- "bin/bin1.meta_lic bin/bin1.meta_lic restricted_allows_dynamic_linking",
- "bin/bin1.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
- "bin/bin1.meta_lic lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
+ "bin/bin1.meta_lic bin/bin1.meta_lic restricted_if_statically_linked",
+ "bin/bin1.meta_lic lib/liba.so.meta_lic restricted_if_statically_linked",
+ "bin/bin1.meta_lic lib/libc.a.meta_lic reciprocal:restricted_if_statically_linked",
"bin/bin2.meta_lic bin/bin2.meta_lic restricted",
"bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic bin/bin1.meta_lic restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic bin/bin1.meta_lic restricted_if_statically_linked",
"highest.apex.meta_lic bin/bin2.meta_lic restricted",
- "highest.apex.meta_lic highest.apex.meta_lic restricted:restricted_allows_dynamic_linking",
- "highest.apex.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic highest.apex.meta_lic restricted:restricted_if_statically_linked",
+ "highest.apex.meta_lic lib/liba.so.meta_lic restricted_if_statically_linked",
"highest.apex.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
- "lib/liba.so.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic lib/libc.a.meta_lic reciprocal:restricted_if_statically_linked",
+ "lib/liba.so.meta_lic lib/liba.so.meta_lic restricted_if_statically_linked",
"lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
},
},
@@ -624,18 +624,18 @@
stripPrefix: []string{"testdata/restricted/"},
},
expectedOut: []string{
- "bin/bin1.meta_lic bin/bin1.meta_lic restricted_allows_dynamic_linking",
- "bin/bin1.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
- "bin/bin1.meta_lic lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
+ "bin/bin1.meta_lic bin/bin1.meta_lic restricted_if_statically_linked",
+ "bin/bin1.meta_lic lib/liba.so.meta_lic restricted_if_statically_linked",
+ "bin/bin1.meta_lic lib/libc.a.meta_lic reciprocal:restricted_if_statically_linked",
"bin/bin2.meta_lic bin/bin2.meta_lic restricted",
"bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic bin/bin1.meta_lic restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic bin/bin1.meta_lic restricted_if_statically_linked",
"highest.apex.meta_lic bin/bin2.meta_lic restricted",
- "highest.apex.meta_lic highest.apex.meta_lic restricted:restricted_allows_dynamic_linking",
- "highest.apex.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic highest.apex.meta_lic restricted:restricted_if_statically_linked",
+ "highest.apex.meta_lic lib/liba.so.meta_lic restricted_if_statically_linked",
"highest.apex.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
- "lib/liba.so.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic lib/libc.a.meta_lic reciprocal:restricted_if_statically_linked",
+ "lib/liba.so.meta_lic lib/liba.so.meta_lic restricted_if_statically_linked",
"lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
},
},
@@ -645,18 +645,18 @@
roots: []string{"highest.apex.meta_lic"},
ctx: context{stripPrefix: []string{"testdata/restricted/"}, labelConditions: true},
expectedOut: []string{
- "bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice notice:restricted_allows_dynamic_linking",
- "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:restricted_allows_dynamic_linking restricted_allows_dynamic_linking",
- "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:reciprocal reciprocal:restricted_allows_dynamic_linking",
+ "bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice notice:restricted_if_statically_linked",
+ "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:restricted_if_statically_linked restricted_if_statically_linked",
+ "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:reciprocal reciprocal:restricted_if_statically_linked",
"bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice notice:restricted",
"bin/bin2.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
- "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice notice:restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice notice:restricted_if_statically_linked",
"highest.apex.meta_lic:notice bin/bin2.meta_lic:notice notice:restricted",
- "highest.apex.meta_lic:notice highest.apex.meta_lic:notice notice:restricted:restricted_allows_dynamic_linking",
- "highest.apex.meta_lic:notice lib/liba.so.meta_lic:restricted_allows_dynamic_linking restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic:notice highest.apex.meta_lic:notice notice:restricted:restricted_if_statically_linked",
+ "highest.apex.meta_lic:notice lib/liba.so.meta_lic:restricted_if_statically_linked restricted_if_statically_linked",
"highest.apex.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
- "highest.apex.meta_lic:notice lib/libc.a.meta_lic:reciprocal reciprocal:restricted_allows_dynamic_linking",
- "lib/liba.so.meta_lic:restricted_allows_dynamic_linking lib/liba.so.meta_lic:restricted_allows_dynamic_linking restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic:notice lib/libc.a.meta_lic:reciprocal reciprocal:restricted_if_statically_linked",
+ "lib/liba.so.meta_lic:restricted_if_statically_linked lib/liba.so.meta_lic:restricted_if_statically_linked restricted_if_statically_linked",
"lib/libb.so.meta_lic:restricted lib/libb.so.meta_lic:restricted restricted",
},
},
@@ -665,18 +665,18 @@
name: "container",
roots: []string{"container.zip.meta_lic"},
expectedOut: []string{
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic notice:restricted_allows_dynamic_linking",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic notice:restricted_if_statically_linked",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_if_statically_linked",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal:restricted_if_statically_linked",
"testdata/restricted/bin/bin2.meta_lic testdata/restricted/bin/bin2.meta_lic notice:restricted",
"testdata/restricted/bin/bin2.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/container.zip.meta_lic testdata/restricted/bin/bin1.meta_lic notice:restricted_allows_dynamic_linking",
+ "testdata/restricted/container.zip.meta_lic testdata/restricted/bin/bin1.meta_lic notice:restricted_if_statically_linked",
"testdata/restricted/container.zip.meta_lic testdata/restricted/bin/bin2.meta_lic notice:restricted",
- "testdata/restricted/container.zip.meta_lic testdata/restricted/container.zip.meta_lic notice:restricted:restricted_allows_dynamic_linking",
- "testdata/restricted/container.zip.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "testdata/restricted/container.zip.meta_lic testdata/restricted/container.zip.meta_lic notice:restricted:restricted_if_statically_linked",
+ "testdata/restricted/container.zip.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_if_statically_linked",
"testdata/restricted/container.zip.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/container.zip.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
- "testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "testdata/restricted/container.zip.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal:restricted_if_statically_linked",
+ "testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_if_statically_linked",
"testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
},
},
@@ -685,8 +685,8 @@
name: "application",
roots: []string{"application.meta_lic"},
expectedOut: []string{
- "testdata/restricted/application.meta_lic testdata/restricted/application.meta_lic notice:restricted:restricted_allows_dynamic_linking",
- "testdata/restricted/application.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted:restricted_allows_dynamic_linking",
+ "testdata/restricted/application.meta_lic testdata/restricted/application.meta_lic notice:restricted:restricted_if_statically_linked",
+ "testdata/restricted/application.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted:restricted_if_statically_linked",
},
},
{
@@ -694,9 +694,9 @@
name: "binary",
roots: []string{"bin/bin1.meta_lic"},
expectedOut: []string{
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic notice:restricted_allows_dynamic_linking",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic notice:restricted_if_statically_linked",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_if_statically_linked",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal:restricted_if_statically_linked",
},
},
{
@@ -2235,17 +2235,17 @@
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/bin/bin1.meta_lic",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"notice"),
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/lib/libc.a.meta_lic",
"reciprocal",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"testdata/restricted/bin/bin2.meta_lic",
"testdata/restricted/bin/bin2.meta_lic",
@@ -2258,7 +2258,7 @@
matchResolution(
"testdata/restricted/highest.apex.meta_lic",
"testdata/restricted/bin/bin1.meta_lic",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"notice"),
matchResolution(
"testdata/restricted/highest.apex.meta_lic",
@@ -2269,12 +2269,12 @@
"testdata/restricted/highest.apex.meta_lic",
"testdata/restricted/highest.apex.meta_lic",
"restricted",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"notice"),
matchResolution(
"testdata/restricted/highest.apex.meta_lic",
"testdata/restricted/lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"testdata/restricted/highest.apex.meta_lic",
"testdata/restricted/lib/libb.so.meta_lic",
@@ -2283,11 +2283,11 @@
"testdata/restricted/highest.apex.meta_lic",
"testdata/restricted/lib/libc.a.meta_lic",
"reciprocal",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"testdata/restricted/lib/liba.so.meta_lic",
"testdata/restricted/lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"testdata/restricted/lib/libb.so.meta_lic",
"testdata/restricted/lib/libb.so.meta_lic",
@@ -2309,17 +2309,17 @@
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
"reciprocal",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
@@ -2332,7 +2332,7 @@
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"notice"),
matchResolution(
"highest.apex.meta_lic",
@@ -2343,12 +2343,12 @@
"highest.apex.meta_lic",
"highest.apex.meta_lic",
"restricted",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
@@ -2357,11 +2357,11 @@
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
"reciprocal",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
@@ -2420,16 +2420,16 @@
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
"reciprocal",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
@@ -2441,7 +2441,7 @@
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
@@ -2450,11 +2450,11 @@
"highest.apex.meta_lic",
"highest.apex.meta_lic",
"restricted",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
@@ -2463,11 +2463,11 @@
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
"reciprocal",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
@@ -2502,16 +2502,16 @@
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
"reciprocal",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
@@ -2523,7 +2523,7 @@
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
@@ -2532,11 +2532,11 @@
"highest.apex.meta_lic",
"highest.apex.meta_lic",
"restricted",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
@@ -2545,11 +2545,11 @@
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
"reciprocal",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
@@ -2563,7 +2563,7 @@
ctx: context{stripPrefix: []string{"testdata/restricted/"}, labelConditions: true},
expectedOut: []getMatcher{
matchTarget("bin/bin1.meta_lic", "notice"),
- matchTarget("lib/liba.so.meta_lic", "restricted_allows_dynamic_linking"),
+ matchTarget("lib/liba.so.meta_lic", "restricted_if_statically_linked"),
matchTarget("lib/libc.a.meta_lic", "reciprocal"),
matchTarget("bin/bin2.meta_lic", "notice"),
matchTarget("lib/libb.so.meta_lic", "restricted"),
@@ -2571,17 +2571,17 @@
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
"reciprocal",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
@@ -2594,7 +2594,7 @@
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"notice"),
matchResolution(
"highest.apex.meta_lic",
@@ -2605,12 +2605,12 @@
"highest.apex.meta_lic",
"highest.apex.meta_lic",
"restricted",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
@@ -2619,11 +2619,11 @@
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
"reciprocal",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
@@ -2644,17 +2644,17 @@
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/bin/bin1.meta_lic",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"notice"),
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/lib/libc.a.meta_lic",
"reciprocal",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"testdata/restricted/bin/bin2.meta_lic",
"testdata/restricted/bin/bin2.meta_lic",
@@ -2667,7 +2667,7 @@
matchResolution(
"testdata/restricted/container.zip.meta_lic",
"testdata/restricted/bin/bin1.meta_lic",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"notice"),
matchResolution(
"testdata/restricted/container.zip.meta_lic",
@@ -2678,12 +2678,12 @@
"testdata/restricted/container.zip.meta_lic",
"testdata/restricted/container.zip.meta_lic",
"restricted",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"notice"),
matchResolution(
"testdata/restricted/container.zip.meta_lic",
"testdata/restricted/lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"testdata/restricted/container.zip.meta_lic",
"testdata/restricted/lib/libb.so.meta_lic",
@@ -2692,11 +2692,11 @@
"testdata/restricted/container.zip.meta_lic",
"testdata/restricted/lib/libc.a.meta_lic",
"reciprocal",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"testdata/restricted/lib/liba.so.meta_lic",
"testdata/restricted/lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"testdata/restricted/lib/libb.so.meta_lic",
"testdata/restricted/lib/libb.so.meta_lic",
@@ -2714,12 +2714,12 @@
"testdata/restricted/application.meta_lic",
"testdata/restricted/application.meta_lic",
"restricted",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"notice"),
matchResolution(
"testdata/restricted/application.meta_lic",
"testdata/restricted/lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"restricted"),
},
},
@@ -2734,16 +2734,16 @@
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/bin/bin1.meta_lic",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"notice"),
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/lib/liba.so.meta_lic",
- "restricted_allows_dynamic_linking"),
+ "restricted_if_statically_linked"),
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/lib/libc.a.meta_lic",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"reciprocal"),
},
},
diff --git a/tools/compliance/cmd/htmlnotice/htmlnotice.go b/tools/compliance/cmd/htmlnotice/htmlnotice.go
index 1a49610..78371ee 100644
--- a/tools/compliance/cmd/htmlnotice/htmlnotice.go
+++ b/tools/compliance/cmd/htmlnotice/htmlnotice.go
@@ -24,6 +24,7 @@
"io/fs"
"os"
"path/filepath"
+ "sort"
"strings"
"android/soong/response"
@@ -275,7 +276,8 @@
}
fmt.Fprintln(ctx.stdout, "</body></html>")
- *ctx.deps = ni.InputNoticeFiles()
+ *ctx.deps = ni.InputFiles()
+ sort.Strings(*ctx.deps)
return nil
}
diff --git a/tools/compliance/cmd/htmlnotice/htmlnotice_test.go b/tools/compliance/cmd/htmlnotice/htmlnotice_test.go
index b927018..8dc1197 100644
--- a/tools/compliance/cmd/htmlnotice/htmlnotice_test.go
+++ b/tools/compliance/cmd/htmlnotice/htmlnotice_test.go
@@ -78,7 +78,16 @@
usedBy{"highest.apex/lib/libb.so"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/bin/bin1.meta_lic",
+ "testdata/firstparty/bin/bin2.meta_lic",
+ "testdata/firstparty/highest.apex.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libb.so.meta_lic",
+ "testdata/firstparty/lib/libc.a.meta_lic",
+ "testdata/firstparty/lib/libd.so.meta_lic",
+ },
},
{
condition: "firstparty",
@@ -106,7 +115,16 @@
usedBy{"highest.apex/lib/libb.so"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/bin/bin1.meta_lic",
+ "testdata/firstparty/bin/bin2.meta_lic",
+ "testdata/firstparty/highest.apex.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libb.so.meta_lic",
+ "testdata/firstparty/lib/libc.a.meta_lic",
+ "testdata/firstparty/lib/libd.so.meta_lic",
+ },
},
{
condition: "firstparty",
@@ -124,7 +142,16 @@
usedBy{"highest.apex/lib/libb.so"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/bin/bin1.meta_lic",
+ "testdata/firstparty/bin/bin2.meta_lic",
+ "testdata/firstparty/highest.apex.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libb.so.meta_lic",
+ "testdata/firstparty/lib/libc.a.meta_lic",
+ "testdata/firstparty/lib/libd.so.meta_lic",
+ },
},
{
condition: "firstparty",
@@ -154,7 +181,16 @@
usedBy{"highest.apex/lib/libb.so"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/bin/bin1.meta_lic",
+ "testdata/firstparty/bin/bin2.meta_lic",
+ "testdata/firstparty/highest.apex.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libb.so.meta_lic",
+ "testdata/firstparty/lib/libc.a.meta_lic",
+ "testdata/firstparty/lib/libd.so.meta_lic",
+ },
},
{
condition: "firstparty",
@@ -170,7 +206,16 @@
usedBy{"container.zip/libb.so"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/bin/bin1.meta_lic",
+ "testdata/firstparty/bin/bin2.meta_lic",
+ "testdata/firstparty/container.zip.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libb.so.meta_lic",
+ "testdata/firstparty/lib/libc.a.meta_lic",
+ "testdata/firstparty/lib/libd.so.meta_lic",
+ },
},
{
condition: "firstparty",
@@ -182,7 +227,13 @@
usedBy{"application"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/application.meta_lic",
+ "testdata/firstparty/bin/bin3.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libb.so.meta_lic",
+ },
},
{
condition: "firstparty",
@@ -194,7 +245,12 @@
usedBy{"bin/bin1"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/bin/bin1.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libc.a.meta_lic",
+ },
},
{
condition: "firstparty",
@@ -206,7 +262,10 @@
usedBy{"lib/libd.so"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/lib/libd.so.meta_lic",
+ },
},
{
condition: "notice",
@@ -231,6 +290,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/bin/bin1.meta_lic",
+ "testdata/notice/bin/bin2.meta_lic",
+ "testdata/notice/highest.apex.meta_lic",
+ "testdata/notice/lib/liba.so.meta_lic",
+ "testdata/notice/lib/libb.so.meta_lic",
+ "testdata/notice/lib/libc.a.meta_lic",
+ "testdata/notice/lib/libd.so.meta_lic",
},
},
{
@@ -256,6 +322,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/bin/bin1.meta_lic",
+ "testdata/notice/bin/bin2.meta_lic",
+ "testdata/notice/container.zip.meta_lic",
+ "testdata/notice/lib/liba.so.meta_lic",
+ "testdata/notice/lib/libb.so.meta_lic",
+ "testdata/notice/lib/libc.a.meta_lic",
+ "testdata/notice/lib/libd.so.meta_lic",
},
},
{
@@ -275,6 +348,10 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/application.meta_lic",
+ "testdata/notice/bin/bin3.meta_lic",
+ "testdata/notice/lib/liba.so.meta_lic",
+ "testdata/notice/lib/libb.so.meta_lic",
},
},
{
@@ -296,6 +373,9 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/bin/bin1.meta_lic",
+ "testdata/notice/lib/liba.so.meta_lic",
+ "testdata/notice/lib/libc.a.meta_lic",
},
},
{
@@ -308,7 +388,10 @@
usedBy{"lib/libd.so"},
notice{},
},
- expectedDeps: []string{"testdata/notice/NOTICE_LICENSE"},
+ expectedDeps: []string{
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/lib/libd.so.meta_lic",
+ },
},
{
condition: "reciprocal",
@@ -333,6 +416,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/reciprocal/bin/bin1.meta_lic",
+ "testdata/reciprocal/bin/bin2.meta_lic",
+ "testdata/reciprocal/highest.apex.meta_lic",
+ "testdata/reciprocal/lib/liba.so.meta_lic",
+ "testdata/reciprocal/lib/libb.so.meta_lic",
+ "testdata/reciprocal/lib/libc.a.meta_lic",
+ "testdata/reciprocal/lib/libd.so.meta_lic",
},
},
{
@@ -358,6 +448,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/reciprocal/bin/bin1.meta_lic",
+ "testdata/reciprocal/bin/bin2.meta_lic",
+ "testdata/reciprocal/container.zip.meta_lic",
+ "testdata/reciprocal/lib/liba.so.meta_lic",
+ "testdata/reciprocal/lib/libb.so.meta_lic",
+ "testdata/reciprocal/lib/libc.a.meta_lic",
+ "testdata/reciprocal/lib/libd.so.meta_lic",
},
},
{
@@ -377,6 +474,10 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/reciprocal/application.meta_lic",
+ "testdata/reciprocal/bin/bin3.meta_lic",
+ "testdata/reciprocal/lib/liba.so.meta_lic",
+ "testdata/reciprocal/lib/libb.so.meta_lic",
},
},
{
@@ -398,6 +499,9 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/reciprocal/bin/bin1.meta_lic",
+ "testdata/reciprocal/lib/liba.so.meta_lic",
+ "testdata/reciprocal/lib/libc.a.meta_lic",
},
},
{
@@ -410,7 +514,10 @@
usedBy{"lib/libd.so"},
notice{},
},
- expectedDeps: []string{"testdata/notice/NOTICE_LICENSE"},
+ expectedDeps: []string{
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/reciprocal/lib/libd.so.meta_lic",
+ },
},
{
condition: "restricted",
@@ -440,6 +547,13 @@
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
"testdata/restricted/RESTRICTED_LICENSE",
+ "testdata/restricted/bin/bin1.meta_lic",
+ "testdata/restricted/bin/bin2.meta_lic",
+ "testdata/restricted/highest.apex.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "testdata/restricted/lib/libb.so.meta_lic",
+ "testdata/restricted/lib/libc.a.meta_lic",
+ "testdata/restricted/lib/libd.so.meta_lic",
},
},
{
@@ -470,6 +584,13 @@
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
"testdata/restricted/RESTRICTED_LICENSE",
+ "testdata/restricted/bin/bin1.meta_lic",
+ "testdata/restricted/bin/bin2.meta_lic",
+ "testdata/restricted/container.zip.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "testdata/restricted/lib/libb.so.meta_lic",
+ "testdata/restricted/lib/libc.a.meta_lic",
+ "testdata/restricted/lib/libd.so.meta_lic",
},
},
{
@@ -489,6 +610,10 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/restricted/RESTRICTED_LICENSE",
+ "testdata/restricted/application.meta_lic",
+ "testdata/restricted/bin/bin3.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "testdata/restricted/lib/libb.so.meta_lic",
},
},
{
@@ -513,6 +638,9 @@
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
"testdata/restricted/RESTRICTED_LICENSE",
+ "testdata/restricted/bin/bin1.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "testdata/restricted/lib/libc.a.meta_lic",
},
},
{
@@ -525,7 +653,10 @@
usedBy{"lib/libd.so"},
notice{},
},
- expectedDeps: []string{"testdata/notice/NOTICE_LICENSE"},
+ expectedDeps: []string{
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/restricted/lib/libd.so.meta_lic",
+ },
},
{
condition: "proprietary",
@@ -555,6 +686,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/proprietary/PROPRIETARY_LICENSE",
+ "testdata/proprietary/bin/bin1.meta_lic",
+ "testdata/proprietary/bin/bin2.meta_lic",
+ "testdata/proprietary/highest.apex.meta_lic",
+ "testdata/proprietary/lib/liba.so.meta_lic",
+ "testdata/proprietary/lib/libb.so.meta_lic",
+ "testdata/proprietary/lib/libc.a.meta_lic",
+ "testdata/proprietary/lib/libd.so.meta_lic",
"testdata/restricted/RESTRICTED_LICENSE",
},
},
@@ -586,6 +724,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/proprietary/PROPRIETARY_LICENSE",
+ "testdata/proprietary/bin/bin1.meta_lic",
+ "testdata/proprietary/bin/bin2.meta_lic",
+ "testdata/proprietary/container.zip.meta_lic",
+ "testdata/proprietary/lib/liba.so.meta_lic",
+ "testdata/proprietary/lib/libb.so.meta_lic",
+ "testdata/proprietary/lib/libc.a.meta_lic",
+ "testdata/proprietary/lib/libd.so.meta_lic",
"testdata/restricted/RESTRICTED_LICENSE",
},
},
@@ -606,6 +751,10 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/proprietary/PROPRIETARY_LICENSE",
+ "testdata/proprietary/application.meta_lic",
+ "testdata/proprietary/bin/bin3.meta_lic",
+ "testdata/proprietary/lib/liba.so.meta_lic",
+ "testdata/proprietary/lib/libb.so.meta_lic",
},
},
{
@@ -627,6 +776,9 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/proprietary/PROPRIETARY_LICENSE",
+ "testdata/proprietary/bin/bin1.meta_lic",
+ "testdata/proprietary/lib/liba.so.meta_lic",
+ "testdata/proprietary/lib/libc.a.meta_lic",
},
},
{
@@ -639,7 +791,10 @@
usedBy{"lib/libd.so"},
notice{},
},
- expectedDeps: []string{"testdata/notice/NOTICE_LICENSE"},
+ expectedDeps: []string{
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/proprietary/lib/libd.so.meta_lic",
+ },
},
}
for _, tt := range tests {
diff --git a/tools/compliance/cmd/listshare/listshare_test.go b/tools/compliance/cmd/listshare/listshare_test.go
index fb61583..16a8b69 100644
--- a/tools/compliance/cmd/listshare/listshare_test.go
+++ b/tools/compliance/cmd/listshare/listshare_test.go
@@ -187,7 +187,7 @@
},
{
project: "device/library",
- conditions: []string{"restricted_allows_dynamic_linking"},
+ conditions: []string{"restricted_if_statically_linked"},
},
{
project: "dynamic/binary",
@@ -196,14 +196,14 @@
{
project: "static/binary",
conditions: []string{
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
},
},
{
project: "static/library",
conditions: []string{
"reciprocal",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
},
},
},
@@ -219,7 +219,7 @@
},
{
project: "device/library",
- conditions: []string{"restricted_allows_dynamic_linking"},
+ conditions: []string{"restricted_if_statically_linked"},
},
{
project: "dynamic/binary",
@@ -228,14 +228,14 @@
{
project: "static/binary",
conditions: []string{
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
},
},
{
project: "static/library",
conditions: []string{
"reciprocal",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
},
},
},
@@ -249,14 +249,14 @@
project: "device/library",
conditions: []string{
"restricted",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
},
},
{
project: "distributable/application",
conditions: []string{
"restricted",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
},
},
},
@@ -269,20 +269,20 @@
{
project: "device/library",
conditions: []string{
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
},
},
{
project: "static/binary",
conditions: []string{
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
},
},
{
project: "static/library",
conditions: []string{
"reciprocal",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
},
},
},
diff --git a/tools/compliance/cmd/rtrace/rtrace_test.go b/tools/compliance/cmd/rtrace/rtrace_test.go
index cbe9461..d650868 100644
--- a/tools/compliance/cmd/rtrace/rtrace_test.go
+++ b/tools/compliance/cmd/rtrace/rtrace_test.go
@@ -44,9 +44,9 @@
expectedOut []string
}{
{
- condition: "firstparty",
- name: "apex",
- roots: []string{"highest.apex.meta_lic"},
+ condition: "firstparty",
+ name: "apex",
+ roots: []string{"highest.apex.meta_lic"},
expectedOut: []string{},
},
{
@@ -60,33 +60,33 @@
expectedOut: []string{},
},
{
- condition: "firstparty",
- name: "container",
- roots: []string{"container.zip.meta_lic"},
+ condition: "firstparty",
+ name: "container",
+ roots: []string{"container.zip.meta_lic"},
expectedOut: []string{},
},
{
- condition: "firstparty",
- name: "application",
- roots: []string{"application.meta_lic"},
+ condition: "firstparty",
+ name: "application",
+ roots: []string{"application.meta_lic"},
expectedOut: []string{},
},
{
- condition: "firstparty",
- name: "binary",
- roots: []string{"bin/bin1.meta_lic"},
+ condition: "firstparty",
+ name: "binary",
+ roots: []string{"bin/bin1.meta_lic"},
expectedOut: []string{},
},
{
- condition: "firstparty",
- name: "library",
- roots: []string{"lib/libd.so.meta_lic"},
+ condition: "firstparty",
+ name: "library",
+ roots: []string{"lib/libd.so.meta_lic"},
expectedOut: []string{},
},
{
- condition: "notice",
- name: "apex",
- roots: []string{"highest.apex.meta_lic"},
+ condition: "notice",
+ name: "apex",
+ roots: []string{"highest.apex.meta_lic"},
expectedOut: []string{},
},
{
@@ -100,33 +100,33 @@
expectedOut: []string{},
},
{
- condition: "notice",
- name: "container",
- roots: []string{"container.zip.meta_lic"},
+ condition: "notice",
+ name: "container",
+ roots: []string{"container.zip.meta_lic"},
expectedOut: []string{},
},
{
- condition: "notice",
- name: "application",
- roots: []string{"application.meta_lic"},
+ condition: "notice",
+ name: "application",
+ roots: []string{"application.meta_lic"},
expectedOut: []string{},
},
{
- condition: "notice",
- name: "binary",
- roots: []string{"bin/bin1.meta_lic"},
+ condition: "notice",
+ name: "binary",
+ roots: []string{"bin/bin1.meta_lic"},
expectedOut: []string{},
},
{
- condition: "notice",
- name: "library",
- roots: []string{"lib/libd.so.meta_lic"},
+ condition: "notice",
+ name: "library",
+ roots: []string{"lib/libd.so.meta_lic"},
expectedOut: []string{},
},
{
- condition: "reciprocal",
- name: "apex",
- roots: []string{"highest.apex.meta_lic"},
+ condition: "reciprocal",
+ name: "apex",
+ roots: []string{"highest.apex.meta_lic"},
expectedOut: []string{},
},
{
@@ -140,27 +140,27 @@
expectedOut: []string{},
},
{
- condition: "reciprocal",
- name: "container",
- roots: []string{"container.zip.meta_lic"},
+ condition: "reciprocal",
+ name: "container",
+ roots: []string{"container.zip.meta_lic"},
expectedOut: []string{},
},
{
- condition: "reciprocal",
- name: "application",
- roots: []string{"application.meta_lic"},
+ condition: "reciprocal",
+ name: "application",
+ roots: []string{"application.meta_lic"},
expectedOut: []string{},
},
{
- condition: "reciprocal",
- name: "binary",
- roots: []string{"bin/bin1.meta_lic"},
+ condition: "reciprocal",
+ name: "binary",
+ roots: []string{"bin/bin1.meta_lic"},
expectedOut: []string{},
},
{
- condition: "reciprocal",
- name: "library",
- roots: []string{"lib/libd.so.meta_lic"},
+ condition: "reciprocal",
+ name: "library",
+ roots: []string{"lib/libd.so.meta_lic"},
expectedOut: []string{},
},
{
@@ -168,7 +168,7 @@
name: "apex",
roots: []string{"highest.apex.meta_lic"},
expectedOut: []string{
- "testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "testdata/restricted/lib/liba.so.meta_lic restricted_if_statically_linked",
"testdata/restricted/lib/libb.so.meta_lic restricted",
},
},
@@ -180,7 +180,7 @@
sources: []string{"testdata/restricted/bin/bin1.meta_lic"},
stripPrefix: []string{"testdata/restricted/"},
},
- expectedOut: []string{"lib/liba.so.meta_lic restricted_allows_dynamic_linking"},
+ expectedOut: []string{"lib/liba.so.meta_lic restricted_if_statically_linked"},
},
{
condition: "restricted",
@@ -197,32 +197,32 @@
name: "container",
roots: []string{"container.zip.meta_lic"},
expectedOut: []string{
- "testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "testdata/restricted/lib/liba.so.meta_lic restricted_if_statically_linked",
"testdata/restricted/lib/libb.so.meta_lic restricted",
},
},
{
- condition: "restricted",
- name: "application",
- roots: []string{"application.meta_lic"},
- expectedOut: []string{"testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking"},
+ condition: "restricted",
+ name: "application",
+ roots: []string{"application.meta_lic"},
+ expectedOut: []string{"testdata/restricted/lib/liba.so.meta_lic restricted_if_statically_linked"},
},
{
- condition: "restricted",
- name: "binary",
- roots: []string{"bin/bin1.meta_lic"},
- expectedOut: []string{"testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking"},
+ condition: "restricted",
+ name: "binary",
+ roots: []string{"bin/bin1.meta_lic"},
+ expectedOut: []string{"testdata/restricted/lib/liba.so.meta_lic restricted_if_statically_linked"},
},
{
- condition: "restricted",
- name: "library",
- roots: []string{"lib/libd.so.meta_lic"},
+ condition: "restricted",
+ name: "library",
+ roots: []string{"lib/libd.so.meta_lic"},
expectedOut: []string{},
},
{
- condition: "proprietary",
- name: "apex",
- roots: []string{"highest.apex.meta_lic"},
+ condition: "proprietary",
+ name: "apex",
+ roots: []string{"highest.apex.meta_lic"},
expectedOut: []string{"testdata/proprietary/lib/libb.so.meta_lic restricted"},
},
{
@@ -246,27 +246,27 @@
expectedOut: []string{"lib/libb.so.meta_lic restricted"},
},
{
- condition: "proprietary",
- name: "container",
- roots: []string{"container.zip.meta_lic"},
+ condition: "proprietary",
+ name: "container",
+ roots: []string{"container.zip.meta_lic"},
expectedOut: []string{"testdata/proprietary/lib/libb.so.meta_lic restricted"},
},
{
- condition: "proprietary",
- name: "application",
- roots: []string{"application.meta_lic"},
+ condition: "proprietary",
+ name: "application",
+ roots: []string{"application.meta_lic"},
expectedOut: []string{},
},
{
- condition: "proprietary",
- name: "binary",
- roots: []string{"bin/bin1.meta_lic"},
+ condition: "proprietary",
+ name: "binary",
+ roots: []string{"bin/bin1.meta_lic"},
expectedOut: []string{},
},
{
- condition: "proprietary",
- name: "library",
- roots: []string{"lib/libd.so.meta_lic"},
+ condition: "proprietary",
+ name: "library",
+ roots: []string{"lib/libd.so.meta_lic"},
expectedOut: []string{},
},
}
diff --git a/tools/compliance/cmd/sbom/sbom.go b/tools/compliance/cmd/sbom/sbom.go
new file mode 100644
index 0000000..0f8a876
--- /dev/null
+++ b/tools/compliance/cmd/sbom/sbom.go
@@ -0,0 +1,434 @@
+// Copyright 2022 Google LLC
+//
+// 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 main
+
+import (
+ "bytes"
+ "flag"
+ "fmt"
+ "io"
+ "io/fs"
+ "os"
+ "path/filepath"
+ "sort"
+ "strings"
+ "time"
+
+ "android/soong/response"
+ "android/soong/tools/compliance"
+ "android/soong/tools/compliance/projectmetadata"
+
+ "github.com/google/blueprint/deptools"
+)
+
+var (
+ failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
+ failNoLicenses = fmt.Errorf("No licenses found")
+)
+
+type context struct {
+ stdout io.Writer
+ stderr io.Writer
+ rootFS fs.FS
+ product string
+ stripPrefix []string
+ creationTime creationTimeGetter
+}
+
+func (ctx context) strip(installPath string) string {
+ for _, prefix := range ctx.stripPrefix {
+ if strings.HasPrefix(installPath, prefix) {
+ p := strings.TrimPrefix(installPath, prefix)
+ if 0 == len(p) {
+ p = ctx.product
+ }
+ if 0 == len(p) {
+ continue
+ }
+ return p
+ }
+ }
+ return installPath
+}
+
+// newMultiString creates a flag that allows multiple values in an array.
+func newMultiString(flags *flag.FlagSet, name, usage string) *multiString {
+ var f multiString
+ flags.Var(&f, name, usage)
+ return &f
+}
+
+// multiString implements the flag `Value` interface for multiple strings.
+type multiString []string
+
+func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
+func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
+
+func main() {
+ var expandedArgs []string
+ for _, arg := range os.Args[1:] {
+ if strings.HasPrefix(arg, "@") {
+ f, err := os.Open(strings.TrimPrefix(arg, "@"))
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(1)
+ }
+
+ respArgs, err := response.ReadRspFile(f)
+ f.Close()
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(1)
+ }
+ expandedArgs = append(expandedArgs, respArgs...)
+ } else {
+ expandedArgs = append(expandedArgs, arg)
+ }
+ }
+
+ flags := flag.NewFlagSet("flags", flag.ExitOnError)
+
+ flags.Usage = func() {
+ fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
+
+Outputs an SBOM.spdx.
+
+Options:
+`, filepath.Base(os.Args[0]))
+ flags.PrintDefaults()
+ }
+
+ outputFile := flags.String("o", "-", "Where to write the SBOM spdx file. (default stdout)")
+ depsFile := flags.String("d", "", "Where to write the deps file")
+ product := flags.String("product", "", "The name of the product for which the notice is generated.")
+ stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
+
+ flags.Parse(expandedArgs)
+
+ // Must specify at least one root target.
+ if flags.NArg() == 0 {
+ flags.Usage()
+ os.Exit(2)
+ }
+
+ if len(*outputFile) == 0 {
+ flags.Usage()
+ fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
+ os.Exit(2)
+ } else {
+ dir, err := filepath.Abs(filepath.Dir(*outputFile))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "cannot determine path to %q: %s\n", *outputFile, err)
+ os.Exit(1)
+ }
+ fi, err := os.Stat(dir)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "cannot read directory %q of %q: %s\n", dir, *outputFile, err)
+ os.Exit(1)
+ }
+ if !fi.IsDir() {
+ fmt.Fprintf(os.Stderr, "parent %q of %q is not a directory\n", dir, *outputFile)
+ os.Exit(1)
+ }
+ }
+
+ var ofile io.Writer
+ ofile = os.Stdout
+ var obuf *bytes.Buffer
+ if *outputFile != "-" {
+ obuf = &bytes.Buffer{}
+ ofile = obuf
+ }
+
+ ctx := &context{ofile, os.Stderr, compliance.FS, *product, *stripPrefix, actualTime}
+
+ deps, err := sbomGenerator(ctx, flags.Args()...)
+ if err != nil {
+ if err == failNoneRequested {
+ flags.Usage()
+ }
+ fmt.Fprintf(os.Stderr, "%s\n", err.Error())
+ os.Exit(1)
+ }
+
+ if *outputFile != "-" {
+ err := os.WriteFile(*outputFile, obuf.Bytes(), 0666)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "could not write output to %q: %s\n", *outputFile, err)
+ os.Exit(1)
+ }
+ }
+
+ if *depsFile != "" {
+ err := deptools.WriteDepFile(*depsFile, *outputFile, deps)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "could not write deps to %q: %s\n", *depsFile, err)
+ os.Exit(1)
+ }
+ }
+ os.Exit(0)
+}
+
+type creationTimeGetter func() time.Time
+
+// actualTime returns current time in UTC
+func actualTime() time.Time {
+ return time.Now().UTC()
+}
+
+// replaceSlashes replaces "/" by "-" for the library path to be used for packages & files SPDXID
+func replaceSlashes(x string) string {
+ return strings.ReplaceAll(x, "/", "-")
+}
+
+// getPackageName returns a package name of a target Node
+func getPackageName(_ *context, tn *compliance.TargetNode) string {
+ return replaceSlashes(tn.Name())
+}
+
+// getDocumentName returns a package name of a target Node
+func getDocumentName(ctx *context, tn *compliance.TargetNode, pm *projectmetadata.ProjectMetadata) string {
+ if len(ctx.product) > 0 {
+ return replaceSlashes(ctx.product)
+ }
+ if len(tn.ModuleName()) > 0 {
+ if pm != nil {
+ return replaceSlashes(pm.Name() + ":" + tn.ModuleName())
+ }
+ return replaceSlashes(tn.ModuleName())
+ }
+
+ // TO DO: Replace tn.Name() with pm.Name() + parts of the target name
+ return replaceSlashes(tn.Name())
+}
+
+// getDownloadUrl returns the download URL if available (GIT, SVN, etc..),
+// or NOASSERTION if not available, none determined or ambiguous
+func getDownloadUrl(_ *context, pm *projectmetadata.ProjectMetadata) string {
+ if pm == nil {
+ return "NOASSERTION"
+ }
+
+ urlsByTypeName := pm.UrlsByTypeName()
+ if urlsByTypeName == nil {
+ return "NOASSERTION"
+ }
+
+ url := urlsByTypeName.DownloadUrl()
+ if url == "" {
+ return "NOASSERTION"
+ }
+ return url
+}
+
+// getProjectMetadata returns the optimal project metadata for the target node
+func getProjectMetadata(_ *context, pmix *projectmetadata.Index,
+ tn *compliance.TargetNode) (*projectmetadata.ProjectMetadata, error) {
+ pms, err := pmix.MetadataForProjects(tn.Projects()...)
+ if err != nil {
+ return nil, fmt.Errorf("Unable to read projects for %q: %w\n", tn, err)
+ }
+ if len(pms) == 0 {
+ return nil, nil
+ }
+
+ // Getting the project metadata that contains most of the info needed for sbomGenerator
+ score := -1
+ index := -1
+ for i := 0; i < len(pms); i++ {
+ tempScore := 0
+ if pms[i].Name() != "" {
+ tempScore += 1
+ }
+ if pms[i].Version() != "" {
+ tempScore += 1
+ }
+ if pms[i].UrlsByTypeName().DownloadUrl() != "" {
+ tempScore += 1
+ }
+
+ if tempScore == score {
+ if pms[i].Project() < pms[index].Project() {
+ index = i
+ }
+ } else if tempScore > score {
+ score = tempScore
+ index = i
+ }
+ }
+ return pms[index], nil
+}
+
+// inputFiles returns the complete list of files read
+func inputFiles(lg *compliance.LicenseGraph, pmix *projectmetadata.Index, licenseTexts []string) []string {
+ projectMeta := pmix.AllMetadataFiles()
+ targets := lg.TargetNames()
+ files := make([]string, 0, len(licenseTexts)+len(targets)+len(projectMeta))
+ files = append(files, licenseTexts...)
+ files = append(files, targets...)
+ files = append(files, projectMeta...)
+ return files
+}
+
+// sbomGenerator implements the spdx bom utility
+
+// SBOM is part of the new government regulation issued to improve national cyber security
+// and enhance software supply chain and transparency, see https://www.cisa.gov/sbom
+
+// sbomGenerator uses the SPDX standard, see the SPDX specification (https://spdx.github.io/spdx-spec/)
+// sbomGenerator is also following the internal google SBOM styleguide (http://goto.google.com/spdx-style-guide)
+func sbomGenerator(ctx *context, files ...string) ([]string, error) {
+ // Must be at least one root file.
+ if len(files) < 1 {
+ return nil, failNoneRequested
+ }
+
+ pmix := projectmetadata.NewIndex(ctx.rootFS)
+
+ lg, err := compliance.ReadLicenseGraph(ctx.rootFS, ctx.stderr, files)
+
+ if err != nil {
+ return nil, fmt.Errorf("Unable to read license text file(s) for %q: %v\n", files, err)
+ }
+
+ // implementing the licenses references for the packages
+ licenses := make(map[string]string)
+ concludedLicenses := func(licenseTexts []string) string {
+ licenseRefs := make([]string, 0, len(licenseTexts))
+ for _, licenseText := range licenseTexts {
+ license := strings.SplitN(licenseText, ":", 2)[0]
+ if _, ok := licenses[license]; !ok {
+ licenseRef := "LicenseRef-" + replaceSlashes(license)
+ licenses[license] = licenseRef
+ }
+
+ licenseRefs = append(licenseRefs, licenses[license])
+ }
+ if len(licenseRefs) > 1 {
+ return "(" + strings.Join(licenseRefs, " AND ") + ")"
+ } else if len(licenseRefs) == 1 {
+ return licenseRefs[0]
+ }
+ return "NONE"
+ }
+
+ isMainPackage := true
+ var mainPackage string
+ visitedNodes := make(map[*compliance.TargetNode]struct{})
+
+ // performing a Breadth-first top down walk of licensegraph and building package information
+ compliance.WalkTopDownBreadthFirst(nil, lg,
+ func(lg *compliance.LicenseGraph, tn *compliance.TargetNode, path compliance.TargetEdgePath) bool {
+ if err != nil {
+ return false
+ }
+ var pm *projectmetadata.ProjectMetadata
+ pm, err = getProjectMetadata(ctx, pmix, tn)
+ if err != nil {
+ return false
+ }
+
+ if isMainPackage {
+ mainPackage = getDocumentName(ctx, tn, pm)
+ fmt.Fprintf(ctx.stdout, "SPDXVersion: SPDX-2.2\n")
+ fmt.Fprintf(ctx.stdout, "DataLicense: CC0-1.0\n")
+ fmt.Fprintf(ctx.stdout, "DocumentName: %s\n", mainPackage)
+ fmt.Fprintf(ctx.stdout, "SPDXID: SPDXRef-DOCUMENT\n")
+ fmt.Fprintf(ctx.stdout, "DocumentNamespace: Android\n")
+ fmt.Fprintf(ctx.stdout, "Creator: Organization: Google LLC\n")
+ fmt.Fprintf(ctx.stdout, "Created: %s\n", ctx.creationTime().Format("2006-01-02T15:04:05Z"))
+ isMainPackage = false
+ }
+
+ relationships := make([]string, 0, 1)
+ defer func() {
+ if r := recover(); r != nil {
+ panic(r)
+ }
+ for _, relationship := range relationships {
+ fmt.Fprintln(ctx.stdout, relationship)
+ }
+ }()
+ if len(path) == 0 {
+ relationships = append(relationships,
+ fmt.Sprintf("Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-Package-%s",
+ getPackageName(ctx, tn)))
+ } else {
+ // Check parent and identify annotation
+ parent := path[len(path)-1]
+ targetEdge := parent.Edge()
+ if targetEdge.IsRuntimeDependency() {
+ // Adding the dynamic link annotation RUNTIME_DEPENDENCY_OF relationship
+ relationships = append(relationships, fmt.Sprintf("Relationship: SPDXRef-Package-%s RUNTIME_DEPENDENCY_OF SPDXRef-Package-%s", getPackageName(ctx, tn), getPackageName(ctx, targetEdge.Target())))
+
+ } else if targetEdge.IsDerivation() {
+ // Adding the derivation annotation as a CONTAINS relationship
+ relationships = append(relationships, fmt.Sprintf("Relationship: SPDXRef-Package-%s CONTAINS SPDXRef-Package-%s", getPackageName(ctx, targetEdge.Target()), getPackageName(ctx, tn)))
+
+ } else if targetEdge.IsBuildTool() {
+ // Adding the toolchain annotation as a BUILD_TOOL_OF relationship
+ relationships = append(relationships, fmt.Sprintf("Relationship: SPDXRef-Package-%s BUILD_TOOL_OF SPDXRef-Package-%s", getPackageName(ctx, tn), getPackageName(ctx, targetEdge.Target())))
+ } else {
+ panic(fmt.Errorf("Unknown dependency type: %v", targetEdge.Annotations()))
+ }
+ }
+
+ if _, alreadyVisited := visitedNodes[tn]; alreadyVisited {
+ return false
+ }
+ visitedNodes[tn] = struct{}{}
+ pkgName := getPackageName(ctx, tn)
+ fmt.Fprintf(ctx.stdout, "##### Package: %s\n", strings.Replace(pkgName, "-", "/", -2))
+ fmt.Fprintf(ctx.stdout, "PackageName: %s\n", pkgName)
+ if pm != nil && pm.Version() != "" {
+ fmt.Fprintf(ctx.stdout, "PackageVersion: %s\n", pm.Version())
+ }
+ fmt.Fprintf(ctx.stdout, "SPDXID: SPDXRef-Package-%s\n", pkgName)
+ fmt.Fprintf(ctx.stdout, "PackageDownloadLocation: %s\n", getDownloadUrl(ctx, pm))
+ fmt.Fprintf(ctx.stdout, "PackageLicenseConcluded: %s\n", concludedLicenses(tn.LicenseTexts()))
+ return true
+ })
+
+ fmt.Fprintf(ctx.stdout, "##### Non-standard license:\n")
+
+ licenseTexts := make([]string, 0, len(licenses))
+
+ for licenseText := range licenses {
+ licenseTexts = append(licenseTexts, licenseText)
+ }
+
+ sort.Strings(licenseTexts)
+
+ for _, licenseText := range licenseTexts {
+ fmt.Fprintf(ctx.stdout, "LicenseID: %s\n", licenses[licenseText])
+ // open the file
+ f, err := ctx.rootFS.Open(filepath.Clean(licenseText))
+ if err != nil {
+ return nil, fmt.Errorf("error opening license text file %q: %w", licenseText, err)
+ }
+
+ // read the file
+ text, err := io.ReadAll(f)
+ if err != nil {
+ return nil, fmt.Errorf("error reading license text file %q: %w", licenseText, err)
+ }
+ // adding the extracted license text
+ fmt.Fprintf(ctx.stdout, "ExtractedText: <text>%v</text>\n", string(text))
+ }
+
+ deps := inputFiles(lg, pmix, licenseTexts)
+ sort.Strings(deps)
+ return deps, nil
+}
diff --git a/tools/compliance/cmd/sbom/sbom_test.go b/tools/compliance/cmd/sbom/sbom_test.go
new file mode 100644
index 0000000..6df74e2
--- /dev/null
+++ b/tools/compliance/cmd/sbom/sbom_test.go
@@ -0,0 +1,1745 @@
+// Copyright 2022 Google LLC
+//
+// 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 main
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "os"
+ "reflect"
+ "regexp"
+ "strings"
+ "testing"
+ "time"
+
+ "android/soong/tools/compliance"
+)
+
+var (
+ spdxVersionTag = regexp.MustCompile(`^\s*SPDXVersion: SPDX-2.2\s*$`)
+ spdxDataLicenseTag = regexp.MustCompile(`^\s*DataLicense: CC0-1.0\s*$`)
+ spdxDocumentNameTag = regexp.MustCompile(`^\s*DocumentName:\s*Android*\s*$`)
+ spdxIDTag = regexp.MustCompile(`^\s*SPDXID:\s*SPDXRef-DOCUMENT\s*$`)
+ spdxDocumentNameSpaceTag = regexp.MustCompile(`^\s*DocumentNamespace:\s*Android\s*$`)
+ spdxCreatorOrganizationTag = regexp.MustCompile(`^\s*Creator:\s*Organization:\s*Google LLC\s*$`)
+ spdxCreatedTimeTag = regexp.MustCompile(`^\s*Created: 1970-01-01T00:00:00Z\s*$`)
+ spdxPackageTag = regexp.MustCompile(`^\s*#####\s*Package:\s*(.*)\s*$`)
+ spdxPackageNameTag = regexp.MustCompile(`^\s*PackageName:\s*(.*)\s*$`)
+ spdxPkgIDTag = regexp.MustCompile(`^\s*SPDXID:\s*SPDXRef-Package-(.*)\s*$`)
+ spdxPkgDownloadLocationTag = regexp.MustCompile(`^\s*PackageDownloadLocation:\s*NOASSERTION\s*$`)
+ spdxPkgLicenseDeclaredTag = regexp.MustCompile(`^\s*PackageLicenseConcluded:\s*LicenseRef-(.*)\s*$`)
+ spdxRelationshipTag = regexp.MustCompile(`^\s*Relationship:\s*SPDXRef-(.*)\s*(DESCRIBES|CONTAINS|BUILD_TOOL_OF|RUNTIME_DEPENDENCY_OF)\s*SPDXRef-Package-(.*)\s*$`)
+ spdxLicenseTag = regexp.MustCompile(`^\s*##### Non-standard license:\s*$`)
+ spdxLicenseIDTag = regexp.MustCompile(`^\s*LicenseID: LicenseRef-(.*)\s*$`)
+ spdxExtractedTextTag = regexp.MustCompile(`^\s*ExtractedText:\s*<text>(.*)\s*$`)
+ spdxExtractedClosingTextTag = regexp.MustCompile(`^\s*</text>\s*$`)
+)
+
+func TestMain(m *testing.M) {
+ // Change into the parent directory before running the tests
+ // so they can find the testdata directory.
+ if err := os.Chdir(".."); err != nil {
+ fmt.Printf("failed to change to testdata directory: %s\n", err)
+ os.Exit(1)
+ }
+ os.Exit(m.Run())
+}
+
+func Test(t *testing.T) {
+ tests := []struct {
+ condition string
+ name string
+ outDir string
+ roots []string
+ stripPrefix string
+ expectedOut []matcher
+ expectedDeps []string
+ }{
+ {
+ condition: "firstparty",
+ name: "apex",
+ roots: []string{"highest.apex.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/firstparty/highest.apex.meta_lic"},
+ packageName{"testdata/firstparty/highest.apex.meta_lic"},
+ spdxPkgID{"testdata/firstparty/highest.apex.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata-firstparty-highest.apex.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/firstparty/bin/bin1.meta_lic"},
+ packageName{"testdata/firstparty/bin/bin1.meta_lic"},
+ spdxPkgID{"testdata/firstparty/bin/bin1.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/firstparty/highest.apex.meta_lic ", "testdata/firstparty/bin/bin1.meta_lic", "CONTAINS"},
+ packageTag{"testdata/firstparty/bin/bin2.meta_lic"},
+ packageName{"testdata/firstparty/bin/bin2.meta_lic"},
+ spdxPkgID{"testdata/firstparty/bin/bin2.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/firstparty/highest.apex.meta_lic ", "testdata-firstparty-bin-bin2.meta_lic", "CONTAINS"},
+ packageTag{"testdata/firstparty/lib/liba.so.meta_lic"},
+ packageName{"testdata/firstparty/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/firstparty/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/firstparty/highest.apex.meta_lic ", "testdata/firstparty/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/firstparty/lib/libb.so.meta_lic"},
+ packageName{"testdata/firstparty/lib/libb.so.meta_lic"},
+ spdxPkgID{"testdata/firstparty/lib/libb.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/firstparty/highest.apex.meta_lic ", "testdata/firstparty/lib/libb.so.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/firstparty/bin/bin1.meta_lic ", "testdata/firstparty/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/firstparty/lib/libc.a.meta_lic"},
+ packageName{"testdata/firstparty/lib/libc.a.meta_lic"},
+ spdxPkgID{"testdata/firstparty/lib/libc.a.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata-firstparty-bin-bin1.meta_lic ", "testdata/firstparty/lib/libc.a.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/firstparty/lib/libb.so.meta_lic ", "testdata/firstparty/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ packageTag{"testdata/firstparty/lib/libd.so.meta_lic"},
+ packageName{"testdata/firstparty/lib/libd.so.meta_lic"},
+ spdxPkgID{"testdata/firstparty/lib/libd.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/firstparty/lib/libd.so.meta_lic ", "testdata/firstparty/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/bin/bin1.meta_lic",
+ "testdata/firstparty/bin/bin2.meta_lic",
+ "testdata/firstparty/highest.apex.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libb.so.meta_lic",
+ "testdata/firstparty/lib/libc.a.meta_lic",
+ "testdata/firstparty/lib/libd.so.meta_lic",
+ },
+ },
+ {
+ condition: "firstparty",
+ name: "application",
+ roots: []string{"application.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/firstparty/application.meta_lic"},
+ packageName{"testdata/firstparty/application.meta_lic"},
+ spdxPkgID{"testdata/firstparty/application.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/firstparty/application.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/firstparty/bin/bin3.meta_lic"},
+ packageName{"testdata/firstparty/bin/bin3.meta_lic"},
+ spdxPkgID{"testdata/firstparty/bin/bin3.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/firstparty/bin/bin3.meta_lic ", "testdata-firstparty-application.meta_lic", "BUILD_TOOL_OF"},
+ packageTag{"testdata/firstparty/lib/liba.so.meta_lic"},
+ packageName{"testdata/firstparty/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/firstparty/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/firstparty/application.meta_lic ", "testdata/firstparty/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/firstparty/lib/libb.so.meta_lic"},
+ packageName{"testdata/firstparty/lib/libb.so.meta_lic"},
+ spdxPkgID{"testdata/firstparty/lib/libb.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/firstparty/lib/libb.so.meta_lic ", "testdata-firstparty-application.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/application.meta_lic",
+ "testdata/firstparty/bin/bin3.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libb.so.meta_lic",
+ },
+ },
+ {
+ condition: "firstparty",
+ name: "container",
+ roots: []string{"container.zip.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/firstparty/container.zip.meta_lic"},
+ packageName{"testdata/firstparty/container.zip.meta_lic"},
+ spdxPkgID{"testdata/firstparty/container.zip.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/firstparty/container.zip.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/firstparty/bin/bin1.meta_lic"},
+ packageName{"testdata/firstparty/bin/bin1.meta_lic"},
+ spdxPkgID{"testdata/firstparty/bin/bin1.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/firstparty/container.zip.meta_lic ", "testdata/firstparty/bin/bin1.meta_lic", "CONTAINS"},
+ packageTag{"testdata/firstparty/bin/bin2.meta_lic"},
+ packageName{"testdata/firstparty/bin/bin2.meta_lic"},
+ spdxPkgID{"testdata/firstparty/bin/bin2.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/firstparty/container.zip.meta_lic ", "testdata/firstparty/bin/bin2.meta_lic", "CONTAINS"},
+ packageTag{"testdata/firstparty/lib/liba.so.meta_lic"},
+ packageName{"testdata/firstparty/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/firstparty/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/firstparty/container.zip.meta_lic ", "testdata/firstparty/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/firstparty/lib/libb.so.meta_lic"},
+ packageName{"testdata/firstparty/lib/libb.so.meta_lic"},
+ spdxPkgID{"testdata/firstparty/lib/libb.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/firstparty/container.zip.meta_lic ", "testdata/firstparty/lib/libb.so.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/firstparty/bin/bin1.meta_lic ", "testdata/firstparty/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/firstparty/lib/libc.a.meta_lic"},
+ packageName{"testdata/firstparty/lib/libc.a.meta_lic"},
+ spdxPkgID{"testdata/firstparty/lib/libc.a.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/firstparty/bin/bin1.meta_lic ", "testdata/firstparty/lib/libc.a.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/firstparty/lib/libb.so.meta_lic ", "testdata/firstparty/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ packageTag{"testdata/firstparty/lib/libd.so.meta_lic"},
+ packageName{"testdata/firstparty/lib/libd.so.meta_lic"},
+ spdxPkgID{"testdata/firstparty/lib/libd.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/firstparty/lib/libd.so.meta_lic ", "testdata/firstparty/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/bin/bin1.meta_lic",
+ "testdata/firstparty/bin/bin2.meta_lic",
+ "testdata/firstparty/container.zip.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libb.so.meta_lic",
+ "testdata/firstparty/lib/libc.a.meta_lic",
+ "testdata/firstparty/lib/libd.so.meta_lic",
+ },
+ },
+ {
+ condition: "firstparty",
+ name: "binary",
+ roots: []string{"bin/bin1.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/firstparty/bin/bin1.meta_lic"},
+ packageName{"testdata/firstparty/bin/bin1.meta_lic"},
+ spdxPkgID{"testdata/firstparty/bin/bin1.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/firstparty/bin/bin1.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/firstparty/lib/liba.so.meta_lic"},
+ packageName{"testdata/firstparty/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/firstparty/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/firstparty/bin/bin1.meta_lic ", "testdata/firstparty/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/firstparty/lib/libc.a.meta_lic"},
+ packageName{"testdata/firstparty/lib/libc.a.meta_lic"},
+ spdxPkgID{"testdata/firstparty/lib/libc.a.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/firstparty/bin/bin1.meta_lic ", "testdata/firstparty/lib/libc.a.meta_lic", "CONTAINS"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/bin/bin1.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libc.a.meta_lic",
+ },
+ },
+ {
+ condition: "firstparty",
+ name: "library",
+ roots: []string{"lib/libd.so.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/firstparty/lib/libd.so.meta_lic"},
+ packageName{"testdata/firstparty/lib/libd.so.meta_lic"},
+ spdxPkgID{"testdata/firstparty/lib/libd.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/firstparty/lib/libd.so.meta_lic", "DESCRIBES"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/lib/libd.so.meta_lic",
+ },
+ },
+ {
+ condition: "notice",
+ name: "apex",
+ roots: []string{"highest.apex.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/notice/highest.apex.meta_lic"},
+ packageName{"testdata/notice/highest.apex.meta_lic"},
+ spdxPkgID{"testdata/notice/highest.apex.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/notice/highest.apex.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/notice/bin/bin1.meta_lic"},
+ packageName{"testdata/notice/bin/bin1.meta_lic"},
+ spdxPkgID{"testdata/notice/bin/bin1.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/notice/highest.apex.meta_lic ", "testdata/notice/bin/bin1.meta_lic", "CONTAINS"},
+ packageTag{"testdata/notice/bin/bin2.meta_lic"},
+ packageName{"testdata/notice/bin/bin2.meta_lic"},
+ spdxPkgID{"testdata/notice/bin/bin2.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/notice/highest.apex.meta_lic ", "testdata/notice/bin/bin2.meta_lic", "CONTAINS"},
+ packageTag{"testdata/notice/lib/liba.so.meta_lic"},
+ packageName{"testdata/notice/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/notice/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"Package-testdata/notice/highest.apex.meta_lic ", "testdata/notice/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/notice/lib/libb.so.meta_lic"},
+ packageName{"testdata/notice/lib/libb.so.meta_lic"},
+ spdxPkgID{"testdata/notice/lib/libb.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/notice/highest.apex.meta_lic ", "testdata/notice/lib/libb.so.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/notice/bin/bin1.meta_lic ", "testdata/notice/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/notice/lib/libc.a.meta_lic"},
+ packageName{"testdata/notice/lib/libc.a.meta_lic"},
+ spdxPkgID{"testdata/notice/lib/libc.a.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"Package-testdata/notice/bin/bin1.meta_lic ", "testdata/notice/lib/libc.a.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/notice/lib/libb.so.meta_lic ", "testdata/notice/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ packageTag{"testdata/notice/lib/libd.so.meta_lic"},
+ packageName{"testdata/notice/lib/libd.so.meta_lic"},
+ spdxPkgID{"testdata/notice/lib/libd.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"Package-testdata/notice/lib/libd.so.meta_lic ", "testdata/notice/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
+ spdxExtractedText{"%%%Notice License%%%"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/bin/bin1.meta_lic",
+ "testdata/notice/bin/bin2.meta_lic",
+ "testdata/notice/highest.apex.meta_lic",
+ "testdata/notice/lib/liba.so.meta_lic",
+ "testdata/notice/lib/libb.so.meta_lic",
+ "testdata/notice/lib/libc.a.meta_lic",
+ "testdata/notice/lib/libd.so.meta_lic",
+ },
+ },
+ {
+ condition: "notice",
+ name: "container",
+ roots: []string{"container.zip.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/notice/container.zip.meta_lic"},
+ packageName{"testdata/notice/container.zip.meta_lic"},
+ spdxPkgID{"testdata/notice/container.zip.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/notice/container.zip.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/notice/bin/bin1.meta_lic"},
+ packageName{"testdata/notice/bin/bin1.meta_lic"},
+ spdxPkgID{"testdata/notice/bin/bin1.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/notice/container.zip.meta_lic ", "testdata/notice/bin/bin1.meta_lic", "CONTAINS"},
+ packageTag{"testdata/notice/bin/bin2.meta_lic"},
+ packageName{"testdata/notice/bin/bin2.meta_lic"},
+ spdxPkgID{"testdata/notice/bin/bin2.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/notice/container.zip.meta_lic ", "testdata/notice/bin/bin2.meta_lic", "CONTAINS"},
+ packageTag{"testdata/notice/lib/liba.so.meta_lic"},
+ packageName{"testdata/notice/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/notice/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"Package-testdata/notice/container.zip.meta_lic ", "testdata/notice/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/notice/lib/libb.so.meta_lic"},
+ packageName{"testdata/notice/lib/libb.so.meta_lic"},
+ spdxPkgID{"testdata/notice/lib/libb.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/notice/container.zip.meta_lic ", "testdata/notice/lib/libb.so.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/notice/bin/bin1.meta_lic ", "testdata/notice/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/notice/lib/libc.a.meta_lic"},
+ packageName{"testdata/notice/lib/libc.a.meta_lic"},
+ spdxPkgID{"testdata/notice/lib/libc.a.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"Package-testdata/notice/bin/bin1.meta_lic ", "testdata/notice/lib/libc.a.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/notice/lib/libb.so.meta_lic ", "testdata/notice/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ packageTag{"testdata/notice/lib/libd.so.meta_lic"},
+ packageName{"testdata/notice/lib/libd.so.meta_lic"},
+ spdxPkgID{"testdata/notice/lib/libd.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"Package-testdata/notice/lib/libd.so.meta_lic ", "testdata/notice/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
+ spdxExtractedText{"%%%Notice License%%%"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/bin/bin1.meta_lic",
+ "testdata/notice/bin/bin2.meta_lic",
+ "testdata/notice/container.zip.meta_lic",
+ "testdata/notice/lib/liba.so.meta_lic",
+ "testdata/notice/lib/libb.so.meta_lic",
+ "testdata/notice/lib/libc.a.meta_lic",
+ "testdata/notice/lib/libd.so.meta_lic",
+ },
+ },
+ {
+ condition: "notice",
+ name: "application",
+ roots: []string{"application.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/notice/application.meta_lic"},
+ packageName{"testdata/notice/application.meta_lic"},
+ spdxPkgID{"testdata/notice/application.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata-notice-application.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/notice/bin/bin3.meta_lic"},
+ packageName{"testdata/notice/bin/bin3.meta_lic"},
+ spdxPkgID{"testdata/notice/bin/bin3.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"Package-testdata-notice-bin-bin3.meta_lic ", "testdata/notice/application.meta_lic", "BUILD_TOOL_OF"},
+ packageTag{"testdata/notice/lib/liba.so.meta_lic"},
+ packageName{"testdata/notice/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/notice/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"Package-testdata/notice/application.meta_lic ", "testdata-notice-lib-liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/notice/lib/libb.so.meta_lic"},
+ packageName{"testdata/notice/lib/libb.so.meta_lic"},
+ spdxPkgID{"testdata/notice/lib/libb.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata-notice-lib-libb.so.meta_lic ", "testdata/notice/application.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
+ spdxExtractedText{"%%%Notice License%%%"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/application.meta_lic",
+ "testdata/notice/bin/bin3.meta_lic",
+ "testdata/notice/lib/liba.so.meta_lic",
+ "testdata/notice/lib/libb.so.meta_lic",
+ },
+ },
+ {
+ condition: "notice",
+ name: "binary",
+ roots: []string{"bin/bin1.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/notice/bin/bin1.meta_lic"},
+ packageName{"testdata/notice/bin/bin1.meta_lic"},
+ spdxPkgID{"testdata/notice/bin/bin1.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/notice/bin/bin1.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/notice/lib/liba.so.meta_lic"},
+ packageName{"testdata/notice/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/notice/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"Package-testdata/notice/bin/bin1.meta_lic ", "testdata/notice/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/notice/lib/libc.a.meta_lic"},
+ packageName{"testdata/notice/lib/libc.a.meta_lic"},
+ spdxPkgID{"testdata/notice/lib/libc.a.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"Package-testdata/notice/bin/bin1.meta_lic ", "testdata/notice/lib/libc.a.meta_lic", "CONTAINS"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
+ spdxExtractedText{"%%%Notice License%%%"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/bin/bin1.meta_lic",
+ "testdata/notice/lib/liba.so.meta_lic",
+ "testdata/notice/lib/libc.a.meta_lic",
+ },
+ },
+ {
+ condition: "notice",
+ name: "library",
+ roots: []string{"lib/libd.so.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/notice/lib/libd.so.meta_lic"},
+ packageName{"testdata/notice/lib/libd.so.meta_lic"},
+ spdxPkgID{"testdata/notice/lib/libd.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/notice/lib/libd.so.meta_lic", "DESCRIBES"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
+ spdxExtractedText{"%%%Notice License%%%"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/lib/libd.so.meta_lic",
+ },
+ },
+ {
+ condition: "reciprocal",
+ name: "apex",
+ roots: []string{"highest.apex.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/reciprocal/highest.apex.meta_lic"},
+ packageName{"testdata/reciprocal/highest.apex.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/highest.apex.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/reciprocal/highest.apex.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/reciprocal/bin/bin1.meta_lic"},
+ packageName{"testdata/reciprocal/bin/bin1.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/bin/bin1.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/reciprocal/highest.apex.meta_lic ", "testdata-reciprocal-bin-bin1.meta_lic", "CONTAINS"},
+ packageTag{"testdata/reciprocal/bin/bin2.meta_lic"},
+ packageName{"testdata/reciprocal/bin/bin2.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/bin/bin2.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/reciprocal/highest.apex.meta_lic ", "testdata-reciprocal-bin-bin2.meta_lic", "CONTAINS"},
+ packageTag{"testdata/reciprocal/lib/liba.so.meta_lic"},
+ packageName{"testdata/reciprocal/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
+ spdxRelationship{"Package-testdata/reciprocal/highest.apex.meta_lic ", "testdata/reciprocal/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/reciprocal/lib/libb.so.meta_lic"},
+ packageName{"testdata/reciprocal/lib/libb.so.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/lib/libb.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/reciprocal/highest.apex.meta_lic ", "testdata/reciprocal/lib/libb.so.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/reciprocal/bin/bin1.meta_lic ", "testdata/reciprocal/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/reciprocal/lib/libc.a.meta_lic"},
+ packageName{"testdata/reciprocal/lib/libc.a.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/lib/libc.a.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
+ spdxRelationship{"Package-testdata/reciprocal/bin/bin1.meta_lic ", "testdata/reciprocal/lib/libc.a.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/reciprocal/lib/libb.so.meta_lic ", "testdata/reciprocal/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ packageTag{"testdata/reciprocal/lib/libd.so.meta_lic"},
+ packageName{"testdata/reciprocal/lib/libd.so.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/lib/libd.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"Package-testdata/reciprocal/lib/libd.so.meta_lic ", "testdata/reciprocal/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
+ spdxExtractedText{"%%%Notice License%%%"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-reciprocal-RECIPROCAL_LICENSE"},
+ spdxExtractedText{"$$$Reciprocal License$$$"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/reciprocal/bin/bin1.meta_lic",
+ "testdata/reciprocal/bin/bin2.meta_lic",
+ "testdata/reciprocal/highest.apex.meta_lic",
+ "testdata/reciprocal/lib/liba.so.meta_lic",
+ "testdata/reciprocal/lib/libb.so.meta_lic",
+ "testdata/reciprocal/lib/libc.a.meta_lic",
+ "testdata/reciprocal/lib/libd.so.meta_lic",
+ },
+ },
+ {
+ condition: "reciprocal",
+ name: "container",
+ roots: []string{"container.zip.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/reciprocal/container.zip.meta_lic"},
+ packageName{"testdata/reciprocal/container.zip.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/container.zip.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/reciprocal/container.zip.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/reciprocal/bin/bin1.meta_lic"},
+ packageName{"testdata/reciprocal/bin/bin1.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/bin/bin1.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/reciprocal/container.zip.meta_lic ", "testdata-reciprocal-bin-bin1.meta_lic", "CONTAINS"},
+ packageTag{"testdata/reciprocal/bin/bin2.meta_lic"},
+ packageName{"testdata/reciprocal/bin/bin2.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/bin/bin2.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/reciprocal/container.zip.meta_lic ", "testdata-reciprocal-bin-bin2.meta_lic", "CONTAINS"},
+ packageTag{"testdata/reciprocal/lib/liba.so.meta_lic"},
+ packageName{"testdata/reciprocal/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
+ spdxRelationship{"Package-testdata/reciprocal/container.zip.meta_lic ", "testdata/reciprocal/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/reciprocal/lib/libb.so.meta_lic"},
+ packageName{"testdata/reciprocal/lib/libb.so.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/lib/libb.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/reciprocal/container.zip.meta_lic ", "testdata/reciprocal/lib/libb.so.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/reciprocal/bin/bin1.meta_lic ", "testdata/reciprocal/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/reciprocal/lib/libc.a.meta_lic"},
+ packageName{"testdata/reciprocal/lib/libc.a.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/lib/libc.a.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
+ spdxRelationship{"Package-testdata/reciprocal/bin/bin1.meta_lic ", "testdata/reciprocal/lib/libc.a.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/reciprocal/lib/libb.so.meta_lic ", "testdata/reciprocal/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ packageTag{"testdata/reciprocal/lib/libd.so.meta_lic"},
+ packageName{"testdata/reciprocal/lib/libd.so.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/lib/libd.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"Package-testdata/reciprocal/lib/libd.so.meta_lic ", "testdata/reciprocal/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
+ spdxExtractedText{"%%%Notice License%%%"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-reciprocal-RECIPROCAL_LICENSE"},
+ spdxExtractedText{"$$$Reciprocal License$$$"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/reciprocal/bin/bin1.meta_lic",
+ "testdata/reciprocal/bin/bin2.meta_lic",
+ "testdata/reciprocal/container.zip.meta_lic",
+ "testdata/reciprocal/lib/liba.so.meta_lic",
+ "testdata/reciprocal/lib/libb.so.meta_lic",
+ "testdata/reciprocal/lib/libc.a.meta_lic",
+ "testdata/reciprocal/lib/libd.so.meta_lic",
+ },
+ },
+ {
+ condition: "reciprocal",
+ name: "application",
+ roots: []string{"application.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/reciprocal/application.meta_lic"},
+ packageName{"testdata/reciprocal/application.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/application.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/reciprocal/application.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/reciprocal/bin/bin3.meta_lic"},
+ packageName{"testdata/reciprocal/bin/bin3.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/bin/bin3.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"Package-testdata-reciprocal-bin-bin3.meta_lic ", "testdata/reciprocal/application.meta_lic", "BUILD_TOOL_OF"},
+ packageTag{"testdata/reciprocal/lib/liba.so.meta_lic"},
+ packageName{"testdata/reciprocal/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
+ spdxRelationship{"Package-testdata/reciprocal/application.meta_lic ", "testdata/reciprocal/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/reciprocal/lib/libb.so.meta_lic"},
+ packageName{"testdata/reciprocal/lib/libb.so.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/lib/libb.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/reciprocal/lib/libb.so.meta_lic ", "testdata/reciprocal/application.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
+ spdxExtractedText{"%%%Notice License%%%"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-reciprocal-RECIPROCAL_LICENSE"},
+ spdxExtractedText{"$$$Reciprocal License$$$"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/reciprocal/application.meta_lic",
+ "testdata/reciprocal/bin/bin3.meta_lic",
+ "testdata/reciprocal/lib/liba.so.meta_lic",
+ "testdata/reciprocal/lib/libb.so.meta_lic",
+ },
+ },
+ {
+ condition: "reciprocal",
+ name: "binary",
+ roots: []string{"bin/bin1.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/reciprocal/bin/bin1.meta_lic"},
+ packageName{"testdata/reciprocal/bin/bin1.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/bin/bin1.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/reciprocal/bin/bin1.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/reciprocal/lib/liba.so.meta_lic"},
+ packageName{"testdata/reciprocal/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
+ spdxRelationship{"Package-testdata/reciprocal/bin/bin1.meta_lic ", "testdata/reciprocal/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/reciprocal/lib/libc.a.meta_lic"},
+ packageName{"testdata/reciprocal/lib/libc.a.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/lib/libc.a.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
+ spdxRelationship{"Package-testdata/reciprocal/bin/bin1.meta_lic ", "testdata/reciprocal/lib/libc.a.meta_lic", "CONTAINS"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-reciprocal-RECIPROCAL_LICENSE"},
+ spdxExtractedText{"$$$Reciprocal License$$$"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/reciprocal/bin/bin1.meta_lic",
+ "testdata/reciprocal/lib/liba.so.meta_lic",
+ "testdata/reciprocal/lib/libc.a.meta_lic",
+ },
+ },
+ {
+ condition: "reciprocal",
+ name: "library",
+ roots: []string{"lib/libd.so.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/reciprocal/lib/libd.so.meta_lic"},
+ packageName{"testdata/reciprocal/lib/libd.so.meta_lic"},
+ spdxPkgID{"testdata/reciprocal/lib/libd.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/reciprocal/lib/libd.so.meta_lic", "DESCRIBES"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
+ spdxExtractedText{"%%%Notice License%%%"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/reciprocal/lib/libd.so.meta_lic",
+ },
+ },
+ {
+ condition: "restricted",
+ name: "apex",
+ roots: []string{"highest.apex.meta_lic"},
+ stripPrefix: "out/target/product/fictional/system/apex/",
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/restricted/highest.apex.meta_lic"},
+ packageName{"testdata/restricted/highest.apex.meta_lic"},
+ spdxPkgID{"testdata/restricted/highest.apex.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/restricted/highest.apex.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/restricted/bin/bin1.meta_lic"},
+ packageName{"testdata/restricted/bin/bin1.meta_lic"},
+ spdxPkgID{"testdata/restricted/bin/bin1.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/restricted/highest.apex.meta_lic ", "testdata/restricted/bin/bin1.meta_lic", "CONTAINS"},
+ packageTag{"testdata/restricted/bin/bin2.meta_lic"},
+ packageName{"testdata/restricted/bin/bin2.meta_lic"},
+ spdxPkgID{"testdata/restricted/bin/bin2.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/restricted/highest.apex.meta_lic ", "testdata/restricted/bin/bin2.meta_lic", "CONTAINS"},
+ packageTag{"testdata/restricted/lib/liba.so.meta_lic"},
+ packageName{"testdata/restricted/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/restricted/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
+ spdxRelationship{"Package-testdata/restricted/highest.apex.meta_lic ", "testdata/restricted/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/restricted/lib/libb.so.meta_lic"},
+ packageName{"testdata/restricted/lib/libb.so.meta_lic"},
+ spdxPkgID{"testdata/restricted/lib/libb.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
+ spdxRelationship{"Package-testdata/restricted/highest.apex.meta_lic ", "testdata/restricted/lib/libb.so.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/restricted/bin/bin1.meta_lic ", "testdata/restricted/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/restricted/lib/libc.a.meta_lic"},
+ packageName{"testdata/restricted/lib/libc.a.meta_lic"},
+ spdxPkgID{"testdata/restricted/lib/libc.a.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
+ spdxRelationship{"Package-testdata/restricted/bin/bin1.meta_lic ", "testdata/restricted/lib/libc.a.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/restricted/lib/libb.so.meta_lic ", "testdata/restricted/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ packageTag{"testdata/restricted/lib/libd.so.meta_lic"},
+ packageName{"testdata/restricted/lib/libd.so.meta_lic"},
+ spdxPkgID{"testdata/restricted/lib/libd.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"Package-testdata/restricted/lib/libd.so.meta_lic ", "testdata/restricted/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
+ spdxExtractedText{"%%%Notice License%%%"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-reciprocal-RECIPROCAL_LICENSE"},
+ spdxExtractedText{"$$$Reciprocal License$$$"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-restricted-RESTRICTED_LICENSE"},
+ spdxExtractedText{"###Restricted License###"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/restricted/RESTRICTED_LICENSE",
+ "testdata/restricted/bin/bin1.meta_lic",
+ "testdata/restricted/bin/bin2.meta_lic",
+ "testdata/restricted/highest.apex.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "testdata/restricted/lib/libb.so.meta_lic",
+ "testdata/restricted/lib/libc.a.meta_lic",
+ "testdata/restricted/lib/libd.so.meta_lic",
+ },
+ },
+ {
+ condition: "restricted",
+ name: "container",
+ roots: []string{"container.zip.meta_lic"},
+ stripPrefix: "out/target/product/fictional/system/apex/",
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/restricted/container.zip.meta_lic"},
+ packageName{"testdata/restricted/container.zip.meta_lic"},
+ spdxPkgID{"testdata/restricted/container.zip.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/restricted/container.zip.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/restricted/bin/bin1.meta_lic"},
+ packageName{"testdata/restricted/bin/bin1.meta_lic"},
+ spdxPkgID{"testdata/restricted/bin/bin1.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/restricted/container.zip.meta_lic ", "testdata/restricted/bin/bin1.meta_lic", "CONTAINS"},
+ packageTag{"testdata/restricted/bin/bin2.meta_lic"},
+ packageName{"testdata/restricted/bin/bin2.meta_lic"},
+ spdxPkgID{"testdata/restricted/bin/bin2.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/restricted/container.zip.meta_lic ", "testdata/restricted/bin/bin2.meta_lic", "CONTAINS"},
+ packageTag{"testdata/restricted/lib/liba.so.meta_lic"},
+ packageName{"testdata/restricted/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/restricted/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
+ spdxRelationship{"Package-testdata/restricted/container.zip.meta_lic ", "testdata/restricted/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/restricted/lib/libb.so.meta_lic"},
+ packageName{"testdata/restricted/lib/libb.so.meta_lic"},
+ spdxPkgID{"testdata/restricted/lib/libb.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
+ spdxRelationship{"Package-testdata/restricted/container.zip.meta_lic ", "testdata/restricted/lib/libb.so.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/restricted/bin/bin1.meta_lic ", "testdata/restricted/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/restricted/lib/libc.a.meta_lic"},
+ packageName{"testdata/restricted/lib/libc.a.meta_lic"},
+ spdxPkgID{"testdata/restricted/lib/libc.a.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
+ spdxRelationship{"Package-testdata/restricted/bin/bin1.meta_lic ", "testdata/restricted/lib/libc.a.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/restricted/lib/libb.so.meta_lic ", "testdata/restricted/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ packageTag{"testdata/restricted/lib/libd.so.meta_lic"},
+ packageName{"testdata/restricted/lib/libd.so.meta_lic"},
+ spdxPkgID{"testdata/restricted/lib/libd.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"Package-testdata/restricted/lib/libd.so.meta_lic ", "testdata/restricted/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
+ spdxExtractedText{"%%%Notice License%%%"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-reciprocal-RECIPROCAL_LICENSE"},
+ spdxExtractedText{"$$$Reciprocal License$$$"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-restricted-RESTRICTED_LICENSE"},
+ spdxExtractedText{"###Restricted License###"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/restricted/RESTRICTED_LICENSE",
+ "testdata/restricted/bin/bin1.meta_lic",
+ "testdata/restricted/bin/bin2.meta_lic",
+ "testdata/restricted/container.zip.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "testdata/restricted/lib/libb.so.meta_lic",
+ "testdata/restricted/lib/libc.a.meta_lic",
+ "testdata/restricted/lib/libd.so.meta_lic",
+ },
+ },
+ {
+ condition: "restricted",
+ name: "binary",
+ roots: []string{"bin/bin1.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/restricted/bin/bin1.meta_lic"},
+ packageName{"testdata/restricted/bin/bin1.meta_lic"},
+ spdxPkgID{"testdata/restricted/bin/bin1.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/restricted/bin/bin1.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/restricted/lib/liba.so.meta_lic"},
+ packageName{"testdata/restricted/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/restricted/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
+ spdxRelationship{"Package-testdata/restricted/bin/bin1.meta_lic ", "testdata/restricted/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/restricted/lib/libc.a.meta_lic"},
+ packageName{"testdata/restricted/lib/libc.a.meta_lic"},
+ spdxPkgID{"testdata/restricted/lib/libc.a.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
+ spdxRelationship{"Package-testdata/restricted/bin/bin1.meta_lic ", "testdata/restricted/lib/libc.a.meta_lic", "CONTAINS"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-reciprocal-RECIPROCAL_LICENSE"},
+ spdxExtractedText{"$$$Reciprocal License$$$"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-restricted-RESTRICTED_LICENSE"},
+ spdxExtractedText{"###Restricted License###"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/restricted/RESTRICTED_LICENSE",
+ "testdata/restricted/bin/bin1.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "testdata/restricted/lib/libc.a.meta_lic",
+ },
+ },
+ {
+ condition: "restricted",
+ name: "library",
+ roots: []string{"lib/libd.so.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/restricted/lib/libd.so.meta_lic"},
+ packageName{"testdata/restricted/lib/libd.so.meta_lic"},
+ spdxPkgID{"testdata/restricted/lib/libd.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/restricted/lib/libd.so.meta_lic", "DESCRIBES"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
+ spdxExtractedText{"%%%Notice License%%%"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/restricted/lib/libd.so.meta_lic",
+ },
+ },
+ {
+ condition: "proprietary",
+ name: "apex",
+ roots: []string{"highest.apex.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/proprietary/highest.apex.meta_lic"},
+ packageName{"testdata/proprietary/highest.apex.meta_lic"},
+ spdxPkgID{"testdata/proprietary/highest.apex.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/proprietary/highest.apex.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/proprietary/bin/bin1.meta_lic"},
+ packageName{"testdata/proprietary/bin/bin1.meta_lic"},
+ spdxPkgID{"testdata/proprietary/bin/bin1.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/proprietary/highest.apex.meta_lic ", "testdata/proprietary/bin/bin1.meta_lic", "CONTAINS"},
+ packageTag{"testdata/proprietary/bin/bin2.meta_lic"},
+ packageName{"testdata/proprietary/bin/bin2.meta_lic"},
+ spdxPkgID{"testdata/proprietary/bin/bin2.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
+ spdxRelationship{"Package-testdata/proprietary/highest.apex.meta_lic ", "testdata/proprietary/bin/bin2.meta_lic", "CONTAINS"},
+ packageTag{"testdata/proprietary/lib/liba.so.meta_lic"},
+ packageName{"testdata/proprietary/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/proprietary/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
+ spdxRelationship{"Package-testdata/proprietary/highest.apex.meta_lic ", "testdata/proprietary/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/proprietary/lib/libb.so.meta_lic"},
+ packageName{"testdata/proprietary/lib/libb.so.meta_lic"},
+ spdxPkgID{"testdata/proprietary/lib/libb.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
+ spdxRelationship{"Package-testdata/proprietary/highest.apex.meta_lic ", "testdata/proprietary/lib/libb.so.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/proprietary/bin/bin1.meta_lic ", "testdata/proprietary/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/proprietary/lib/libc.a.meta_lic"},
+ packageName{"testdata/proprietary/lib/libc.a.meta_lic"},
+ spdxPkgID{"testdata/proprietary/lib/libc.a.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
+ spdxRelationship{"Package-testdata/proprietary/bin/bin1.meta_lic ", "testdata/proprietary/lib/libc.a.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata-proprietary-lib-libb.so.meta_lic ", "testdata/proprietary/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ packageTag{"testdata/proprietary/lib/libd.so.meta_lic"},
+ packageName{"testdata/proprietary/lib/libd.so.meta_lic"},
+ spdxPkgID{"testdata/proprietary/lib/libd.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"Package-testdata-proprietary-lib-libd.so.meta_lic ", "testdata/proprietary/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
+ spdxExtractedText{"%%%Notice License%%%"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-proprietary-PROPRIETARY_LICENSE"},
+ spdxExtractedText{"@@@Proprietary License@@@"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-restricted-RESTRICTED_LICENSE"},
+ spdxExtractedText{"###Restricted License###"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/proprietary/PROPRIETARY_LICENSE",
+ "testdata/proprietary/bin/bin1.meta_lic",
+ "testdata/proprietary/bin/bin2.meta_lic",
+ "testdata/proprietary/highest.apex.meta_lic",
+ "testdata/proprietary/lib/liba.so.meta_lic",
+ "testdata/proprietary/lib/libb.so.meta_lic",
+ "testdata/proprietary/lib/libc.a.meta_lic",
+ "testdata/proprietary/lib/libd.so.meta_lic",
+ "testdata/restricted/RESTRICTED_LICENSE",
+ },
+ },
+ {
+ condition: "proprietary",
+ name: "container",
+ roots: []string{"container.zip.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/proprietary/container.zip.meta_lic"},
+ packageName{"testdata/proprietary/container.zip.meta_lic"},
+ spdxPkgID{"testdata/proprietary/container.zip.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/proprietary/container.zip.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/proprietary/bin/bin1.meta_lic"},
+ packageName{"testdata/proprietary/bin/bin1.meta_lic"},
+ spdxPkgID{"testdata/proprietary/bin/bin1.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"Package-testdata/proprietary/container.zip.meta_lic ", "testdata/proprietary/bin/bin1.meta_lic", "CONTAINS"},
+ packageTag{"testdata/proprietary/bin/bin2.meta_lic"},
+ packageName{"testdata/proprietary/bin/bin2.meta_lic"},
+ spdxPkgID{"testdata/proprietary/bin/bin2.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
+ spdxRelationship{"Package-testdata/proprietary/container.zip.meta_lic ", "testdata/proprietary/bin/bin2.meta_lic", "CONTAINS"},
+ packageTag{"testdata/proprietary/lib/liba.so.meta_lic"},
+ packageName{"testdata/proprietary/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/proprietary/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
+ spdxRelationship{"Package-testdata/proprietary/container.zip.meta_lic ", "testdata/proprietary/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/proprietary/lib/libb.so.meta_lic"},
+ packageName{"testdata/proprietary/lib/libb.so.meta_lic"},
+ spdxPkgID{"testdata/proprietary/lib/libb.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
+ spdxRelationship{"Package-testdata/proprietary/container.zip.meta_lic ", "testdata/proprietary/lib/libb.so.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata/proprietary/bin/bin1.meta_lic ", "testdata/proprietary/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/proprietary/lib/libc.a.meta_lic"},
+ packageName{"testdata/proprietary/lib/libc.a.meta_lic"},
+ spdxPkgID{"testdata/proprietary/lib/libc.a.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
+ spdxRelationship{"Package-testdata/proprietary/bin/bin1.meta_lic ", "testdata/proprietary/lib/libc.a.meta_lic", "CONTAINS"},
+ spdxRelationship{"Package-testdata-proprietary-lib-libb.so.meta_lic ", "testdata/proprietary/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ packageTag{"testdata/proprietary/lib/libd.so.meta_lic"},
+ packageName{"testdata/proprietary/lib/libd.so.meta_lic"},
+ spdxPkgID{"testdata/proprietary/lib/libd.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"Package-testdata-proprietary-lib-libd.so.meta_lic ", "testdata/proprietary/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
+ spdxExtractedText{"%%%Notice License%%%"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-proprietary-PROPRIETARY_LICENSE"},
+ spdxExtractedText{"@@@Proprietary License@@@"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-restricted-RESTRICTED_LICENSE"},
+ spdxExtractedText{"###Restricted License###"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/proprietary/PROPRIETARY_LICENSE",
+ "testdata/proprietary/bin/bin1.meta_lic",
+ "testdata/proprietary/bin/bin2.meta_lic",
+ "testdata/proprietary/container.zip.meta_lic",
+ "testdata/proprietary/lib/liba.so.meta_lic",
+ "testdata/proprietary/lib/libb.so.meta_lic",
+ "testdata/proprietary/lib/libc.a.meta_lic",
+ "testdata/proprietary/lib/libd.so.meta_lic",
+ "testdata/restricted/RESTRICTED_LICENSE",
+ },
+ },
+ {
+ condition: "proprietary",
+ name: "application",
+ roots: []string{"application.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/proprietary/application.meta_lic"},
+ packageName{"testdata/proprietary/application.meta_lic"},
+ spdxPkgID{"testdata/proprietary/application.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/proprietary/application.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/proprietary/bin/bin3.meta_lic"},
+ packageName{"testdata/proprietary/bin/bin3.meta_lic"},
+ spdxPkgID{"testdata/proprietary/bin/bin3.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
+ spdxRelationship{"Package-testdata/proprietary/bin/bin3.meta_lic ", "testdata/proprietary/application.meta_lic", "BUILD_TOOL_OF"},
+ packageTag{"testdata/proprietary/lib/liba.so.meta_lic"},
+ packageName{"testdata/proprietary/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/proprietary/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
+ spdxRelationship{"Package-testdata/proprietary/application.meta_lic ", "testdata/proprietary/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/proprietary/lib/libb.so.meta_lic"},
+ packageName{"testdata/proprietary/lib/libb.so.meta_lic"},
+ spdxPkgID{"testdata/proprietary/lib/libb.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
+ spdxRelationship{"Package-testdata/proprietary/lib/libb.so.meta_lic ", "testdata/proprietary/application.meta_lic", "RUNTIME_DEPENDENCY_OF"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-proprietary-PROPRIETARY_LICENSE"},
+ spdxExtractedText{"@@@Proprietary License@@@"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-restricted-RESTRICTED_LICENSE"},
+ spdxExtractedText{"###Restricted License###"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/proprietary/PROPRIETARY_LICENSE",
+ "testdata/proprietary/application.meta_lic",
+ "testdata/proprietary/bin/bin3.meta_lic",
+ "testdata/proprietary/lib/liba.so.meta_lic",
+ "testdata/proprietary/lib/libb.so.meta_lic",
+ "testdata/restricted/RESTRICTED_LICENSE",
+ },
+ },
+ {
+ condition: "proprietary",
+ name: "binary",
+ roots: []string{"bin/bin1.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/proprietary/bin/bin1.meta_lic"},
+ packageName{"testdata/proprietary/bin/bin1.meta_lic"},
+ spdxPkgID{"testdata/proprietary/bin/bin1.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/proprietary/bin/bin1.meta_lic", "DESCRIBES"},
+ packageTag{"testdata/proprietary/lib/liba.so.meta_lic"},
+ packageName{"testdata/proprietary/lib/liba.so.meta_lic"},
+ spdxPkgID{"testdata/proprietary/lib/liba.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
+ spdxRelationship{"Package-testdata/proprietary/bin/bin1.meta_lic ", "testdata/proprietary/lib/liba.so.meta_lic", "CONTAINS"},
+ packageTag{"testdata/proprietary/lib/libc.a.meta_lic"},
+ packageName{"testdata/proprietary/lib/libc.a.meta_lic"},
+ spdxPkgID{"testdata/proprietary/lib/libc.a.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
+ spdxRelationship{"Package-testdata/proprietary/bin/bin1.meta_lic ", "testdata/proprietary/lib/libc.a.meta_lic", "CONTAINS"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
+ spdxExtractedText{"&&&First Party License&&&"},
+ spdxExtractedClosingText{},
+ spdxLicenseID{"testdata-proprietary-PROPRIETARY_LICENSE"},
+ spdxExtractedText{"@@@Proprietary License@@@"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/proprietary/PROPRIETARY_LICENSE",
+ "testdata/proprietary/bin/bin1.meta_lic",
+ "testdata/proprietary/lib/liba.so.meta_lic",
+ "testdata/proprietary/lib/libc.a.meta_lic",
+ },
+ },
+ {
+ condition: "proprietary",
+ name: "library",
+ roots: []string{"lib/libd.so.meta_lic"},
+ expectedOut: []matcher{
+ spdxVersion{},
+ spdxDataLicense{},
+ spdxDocumentName{"Android"},
+ spdxID{},
+ spdxDocumentNameSpace{},
+ spdxCreatorOrganization{},
+ spdxCreatedTime{},
+ packageTag{"testdata/proprietary/lib/libd.so.meta_lic"},
+ packageName{"testdata/proprietary/lib/libd.so.meta_lic"},
+ spdxPkgID{"testdata/proprietary/lib/libd.so.meta_lic"},
+ spdxPkgDownloadLocation{"NOASSERTION"},
+ spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
+ spdxRelationship{"DOCUMENT ", "testdata/proprietary/lib/libd.so.meta_lic", "DESCRIBES"},
+ spdxLicense{},
+ spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
+ spdxExtractedText{"%%%Notice License%%%"},
+ spdxExtractedClosingText{},
+ },
+ expectedDeps: []string{
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/proprietary/lib/libd.so.meta_lic",
+ },
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.condition+" "+tt.name, func(t *testing.T) {
+ stdout := &bytes.Buffer{}
+ stderr := &bytes.Buffer{}
+
+ rootFiles := make([]string, 0, len(tt.roots))
+ for _, r := range tt.roots {
+ rootFiles = append(rootFiles, "testdata/"+tt.condition+"/"+r)
+ }
+
+ ctx := context{stdout, stderr, compliance.GetFS(tt.outDir), "Android", []string{tt.stripPrefix}, fakeTime}
+
+ deps, err := sbomGenerator(&ctx, rootFiles...)
+ if err != nil {
+ t.Fatalf("sbom: error = %v, stderr = %v", err, stderr)
+ return
+ }
+ if stderr.Len() > 0 {
+ t.Errorf("sbom: gotStderr = %v, want none", stderr)
+ }
+
+ t.Logf("got stdout: %s", stdout.String())
+
+ t.Logf("want stdout: %s", matcherList(tt.expectedOut).String())
+
+ out := bufio.NewScanner(stdout)
+ lineno := 0
+ for out.Scan() {
+ line := out.Text()
+ if strings.TrimLeft(line, " ") == "" {
+ continue
+ }
+ if len(tt.expectedOut) <= lineno {
+ t.Errorf("sbom: unexpected output at line %d: got %q, want nothing (wanted %d lines)", lineno+1, line, len(tt.expectedOut))
+ } else if !tt.expectedOut[lineno].isMatch(line) {
+ t.Errorf("sbom: unexpected output at line %d: got %q, want %q", lineno+1, line, tt.expectedOut[lineno])
+ }
+ lineno++
+ }
+ for ; lineno < len(tt.expectedOut); lineno++ {
+ t.Errorf("bom: missing output line %d: ended early, want %q", lineno+1, tt.expectedOut[lineno])
+ }
+
+ t.Logf("got deps: %q", deps)
+
+ t.Logf("want deps: %q", tt.expectedDeps)
+
+ if g, w := deps, tt.expectedDeps; !reflect.DeepEqual(g, w) {
+ t.Errorf("unexpected deps, wanted:\n%s\ngot:\n%s\n",
+ strings.Join(w, "\n"), strings.Join(g, "\n"))
+ }
+ })
+ }
+}
+
+type matcher interface {
+ isMatch(line string) bool
+ String() string
+}
+
+type packageTag struct {
+ name string
+}
+
+func (m packageTag) isMatch(line string) bool {
+ groups := spdxPackageTag.FindStringSubmatch(line)
+ if len(groups) != 2 {
+ return false
+ }
+ return groups[1] == m.name
+}
+
+func (m packageTag) String() string {
+ return "##### Package: " + m.name
+}
+
+type packageName struct {
+ name string
+}
+
+func (m packageName) isMatch(line string) bool {
+ groups := spdxPackageNameTag.FindStringSubmatch(line)
+ if len(groups) != 2 {
+ return false
+ }
+ return groups[1] == replaceSlashes(m.name)
+}
+
+func (m packageName) String() string {
+ return "PackageName: " + replaceSlashes(m.name)
+}
+
+type spdxID struct {}
+
+func (m spdxID) isMatch(line string) bool {
+ return spdxIDTag.MatchString(line)
+}
+
+func (m spdxID) String() string {
+ return "SPDXID: SPDXRef-DOCUMENT"
+}
+
+type spdxPkgID struct {
+ name string
+}
+
+func (m spdxPkgID) isMatch(line string) bool {
+ groups := spdxPkgIDTag.FindStringSubmatch(line)
+ if len(groups) != 2 {
+ return false
+ }
+ return groups[1] == replaceSlashes(m.name)
+}
+
+func (m spdxPkgID) String() string {
+ return "SPDXID: SPDXRef-Package-" + replaceSlashes(m.name)
+}
+
+type spdxVersion struct{}
+
+func (m spdxVersion) isMatch(line string) bool {
+ return spdxVersionTag.MatchString(line)
+}
+
+func (m spdxVersion) String() string {
+ return "SPDXVersion: SPDX-2.2"
+}
+
+type spdxDataLicense struct{}
+
+func (m spdxDataLicense) isMatch(line string) bool {
+ return spdxDataLicenseTag.MatchString(line)
+}
+
+func (m spdxDataLicense) String() string {
+ return "DataLicense: CC0-1.0"
+}
+
+type spdxDocumentName struct {
+ name string
+}
+
+func (m spdxDocumentName) isMatch(line string) bool {
+ return spdxDocumentNameTag.MatchString(line)
+}
+
+func (m spdxDocumentName) String() string {
+ return "DocumentName: " + m.name
+}
+
+type spdxDocumentNameSpace struct {
+ name string
+}
+
+func (m spdxDocumentNameSpace) isMatch(line string) bool {
+ return spdxDocumentNameSpaceTag.MatchString(line)
+}
+
+func (m spdxDocumentNameSpace) String() string {
+ return "DocumentNameSpace: Android"
+}
+
+type spdxCreatorOrganization struct{}
+
+func (m spdxCreatorOrganization) isMatch(line string) bool {
+ return spdxCreatorOrganizationTag.MatchString(line)
+}
+
+func (m spdxCreatorOrganization) String() string {
+ return "Creator: Organization: Google LLC"
+}
+
+func fakeTime() time.Time {
+ return time.UnixMicro(0).UTC()
+}
+
+type spdxCreatedTime struct{}
+
+func (m spdxCreatedTime) isMatch(line string) bool {
+ return spdxCreatedTimeTag.MatchString(line)
+}
+
+func (m spdxCreatedTime) String() string {
+ return "Created: 1970-01-01T00:00:00Z"
+}
+
+type spdxPkgDownloadLocation struct {
+ name string
+}
+
+func (m spdxPkgDownloadLocation) isMatch(line string) bool {
+ return spdxPkgDownloadLocationTag.MatchString(line)
+}
+
+func (m spdxPkgDownloadLocation) String() string {
+ return "PackageDownloadLocation: " + m.name
+}
+
+type spdxPkgLicenseDeclared struct {
+ name string
+}
+
+func (m spdxPkgLicenseDeclared) isMatch(line string) bool {
+ groups := spdxPkgLicenseDeclaredTag.FindStringSubmatch(line)
+ if len(groups) != 2 {
+ return false
+ }
+ return groups[1] == replaceSlashes(m.name)
+}
+
+func (m spdxPkgLicenseDeclared) String() string {
+ return "PackageLicenseConcluded: LicenseRef-" + m.name
+}
+
+type spdxRelationship struct {
+ pkg1 string
+ pkg2 string
+ relation string
+}
+
+func (m spdxRelationship) isMatch(line string) bool {
+ groups := spdxRelationshipTag.FindStringSubmatch(line)
+ if len(groups) != 4 {
+ return false
+ }
+ return groups[1] == replaceSlashes(m.pkg1) && groups[2] == m.relation && groups[3] == replaceSlashes(m.pkg2)
+}
+
+func (m spdxRelationship) String() string {
+ return "Relationship: SPDXRef-" + replaceSlashes(m.pkg1) + " " + m.relation + " SPDXRef-Package-" + replaceSlashes(m.pkg2)
+}
+
+type spdxLicense struct{}
+
+func (m spdxLicense) isMatch(line string) bool {
+ return spdxLicenseTag.MatchString(line)
+}
+
+func (m spdxLicense) String() string {
+ return "##### Non-standard license:"
+}
+
+type spdxLicenseID struct {
+ name string
+}
+
+func (m spdxLicenseID) isMatch(line string) bool {
+ groups := spdxLicenseIDTag.FindStringSubmatch(line)
+ if len(groups) != 2 {
+ return false
+ }
+ return groups[1] == replaceSlashes(m.name)
+}
+
+func (m spdxLicenseID) String() string {
+ return "LicenseID: LicenseRef-" + m.name
+}
+
+type spdxExtractedText struct {
+ name string
+}
+
+func (m spdxExtractedText) isMatch(line string) bool {
+ groups := spdxExtractedTextTag.FindStringSubmatch(line)
+ if len(groups) != 2 {
+ return false
+ }
+ return groups[1] == replaceSlashes(m.name)
+}
+
+func (m spdxExtractedText) String() string {
+ return "ExtractedText: <text>" + m.name
+}
+
+type spdxExtractedClosingText struct{}
+
+func (m spdxExtractedClosingText) isMatch(line string) bool {
+ return spdxExtractedClosingTextTag.MatchString(line)
+}
+
+func (m spdxExtractedClosingText) String() string {
+ return "</text>"
+}
+
+type matcherList []matcher
+
+func (l matcherList) String() string {
+ var sb strings.Builder
+ for _, m := range l {
+ s := m.String()
+ fmt.Fprintf(&sb, "%s\n", s)
+ }
+ return sb.String()
+}
diff --git a/tools/compliance/cmd/testdata/proprietary/bin/bin3.meta_lic b/tools/compliance/cmd/testdata/proprietary/bin/bin3.meta_lic
index 7ef14e9..859be7f 100644
--- a/tools/compliance/cmd/testdata/proprietary/bin/bin3.meta_lic
+++ b/tools/compliance/cmd/testdata/proprietary/bin/bin3.meta_lic
@@ -2,7 +2,7 @@
module_classes: "EXECUTABLES"
projects: "standalone/binary"
license_kinds: "SPDX-license-identifier-LGPL-2.0"
-license_conditions: "restricted"
+license_conditions: "restricted_if_statically_linked"
license_texts: "testdata/restricted/RESTRICTED_LICENSE"
is_container: false
built: "out/target/product/fictional/obj/EXECUTABLES/bin_intermediates/bin3"
diff --git a/tools/compliance/cmd/testdata/regressconcur/README.md b/tools/compliance/cmd/testdata/regressconcur/README.md
new file mode 100644
index 0000000..98ab0ef
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/README.md
@@ -0,0 +1,62 @@
+## Start long walks followed by short walks
+
+Detect concurrency error where "already started" treated as
+"already finished".
+
+### Testdata build graph structure:
+
+A restricted licensed library sandwiched between a notice library and a notice
+binary. The source-code for the libraries only needs to be shared if shipped
+alongside the container with the binaries.
+
+```dot
+strict digraph {
+ rankdir=LR;
+ bin1 [label="bin/bin1.meta_lic\nproprietary"];
+ bin2 [label="bin/bin2.meta_lic\nproprietary"];
+ bin3 [label="bin/bin3.meta_lic\nproprietary"];
+ bin4 [label="bin/bin4.meta_lic\nproprietary"];
+ bin5 [label="bin/bin5.meta_lic\nproprietary"];
+ bin6 [label="bin/bin6.meta_lic\nproprietary"];
+ bin7 [label="bin/bin7.meta_lic\nproprietary"];
+ bin8 [label="bin/bin8.meta_lic\nproprietary"];
+ bin9 [label="bin/bin9.meta_lic\nproprietary"];
+ container [label="container.zip.meta_lic\nnotice"];
+ lib1 [label="lib/lib1.so.meta_lic\nnotice"];
+ lib2 [label="lib/lib2.so.meta_lic\nnotice"];
+ lib3 [label="lib/lib3.so.meta_lic\nnotice"];
+ lib4 [label="lib/lib4.so.meta_lic\nnotice"];
+ lib5 [label="lib/lib5.so.meta_lic\nnotice"];
+ lib6 [label="lib/lib6.so.meta_lic\nnotice"];
+ lib7 [label="lib/lib7.so.meta_lic\nnotice"];
+ lib8 [label="lib/lib8.so.meta_lic\nnotice"];
+ lib9 [label="lib/lib9.so.meta_lic\nrestricted"];
+ container -> bin1 [label="static"];
+ container -> bin2 [label="static"];
+ container -> bin3 [label="static"];
+ container -> bin4 [label="static"];
+ container -> bin5 [label="static"];
+ container -> bin6 [label="static"];
+ container -> bin7 [label="static"];
+ container -> bin8 [label="static"];
+ container -> bin9 [label="static"];
+ bin1 -> lib1 [label="static"];
+ bin2 -> lib2 [label="static"];
+ bin3 -> lib3 [label="static"];
+ bin4 -> lib4 [label="static"];
+ bin5 -> lib5 [label="static"];
+ bin6 -> lib6 [label="static"];
+ bin7 -> lib7 [label="static"];
+ bin8 -> lib8 [label="static"];
+ bin9 -> lib9 [label="static"];
+ lib1 -> lib2 [label="static"];
+ lib2 -> lib3 [label="static"];
+ lib3 -> lib4 [label="static"];
+ lib4 -> lib5 [label="static"];
+ lib5 -> lib6 [label="static"];
+ lib6 -> lib7 [label="static"];
+ lib7 -> lib8 [label="static"];
+ lib8 -> lib9 [label="static"];
+ {rank=same; container}
+}
+```
diff --git a/tools/compliance/cmd/testdata/regressconcur/bin/bin1.meta_lic b/tools/compliance/cmd/testdata/regressconcur/bin/bin1.meta_lic
new file mode 100644
index 0000000..e3763f6
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/bin/bin1.meta_lic
@@ -0,0 +1,13 @@
+package_name: "Android"
+module_classes: "EXECUTABLES"
+projects: "bin/onelibrary"
+license_kinds: "legacy_proprietary"
+license_conditions: "proprietary"
+is_container: false
+built: "out/target/product/fictional/obj/EXECUTABLES/bin_intermediates/bin1"
+installed: "out/target/product/fictional/system/bin/bin1"
+sources: "out/target/product/fictional/system/lib/lib1.a"
+deps: {
+ file: "testdata/regressconcur/lib/lib1.a.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/bin/bin2.meta_lic b/tools/compliance/cmd/testdata/regressconcur/bin/bin2.meta_lic
new file mode 100644
index 0000000..e1822bb
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/bin/bin2.meta_lic
@@ -0,0 +1,13 @@
+package_name: "Android"
+module_classes: "EXECUTABLES"
+projects: "bin/onelibrary"
+license_kinds: "legacy_proprietary"
+license_conditions: "proprietary"
+is_container: false
+built: "out/target/product/fictional/obj/EXECUTABLES/bin_intermediates/bin2"
+installed: "out/target/product/fictional/system/bin/bin2"
+sources: "out/target/product/fictional/system/lib/lib2.a"
+deps: {
+ file: "testdata/regressconcur/lib/lib2.a.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/bin/bin3.meta_lic b/tools/compliance/cmd/testdata/regressconcur/bin/bin3.meta_lic
new file mode 100644
index 0000000..35f5d74
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/bin/bin3.meta_lic
@@ -0,0 +1,13 @@
+package_name: "Android"
+module_classes: "EXECUTABLES"
+projects: "bin/onelibrary"
+license_kinds: "legacy_proprietary"
+license_conditions: "proprietary"
+is_container: false
+built: "out/target/product/fictional/obj/EXECUTABLES/bin_intermediates/bin3"
+installed: "out/target/product/fictional/system/bin/bin3"
+sources: "out/target/product/fictional/system/lib/lib3.a"
+deps: {
+ file: "testdata/regressconcur/lib/lib3.a.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/bin/bin4.meta_lic b/tools/compliance/cmd/testdata/regressconcur/bin/bin4.meta_lic
new file mode 100644
index 0000000..3287382
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/bin/bin4.meta_lic
@@ -0,0 +1,13 @@
+package_name: "Android"
+module_classes: "EXECUTABLES"
+projects: "bin/onelibrary"
+license_kinds: "legacy_proprietary"
+license_conditions: "proprietary"
+is_container: false
+built: "out/target/product/fictional/obj/EXECUTABLES/bin_intermediates/bin4"
+installed: "out/target/product/fictional/system/bin/bin4"
+sources: "out/target/product/fictional/system/lib/lib4.a"
+deps: {
+ file: "testdata/regressconcur/lib/lib4.a.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/bin/bin5.meta_lic b/tools/compliance/cmd/testdata/regressconcur/bin/bin5.meta_lic
new file mode 100644
index 0000000..f51bcdb
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/bin/bin5.meta_lic
@@ -0,0 +1,13 @@
+package_name: "Android"
+module_classes: "EXECUTABLES"
+projects: "bin/onelibrary"
+license_kinds: "legacy_proprietary"
+license_conditions: "proprietary"
+is_container: false
+built: "out/target/product/fictional/obj/EXECUTABLES/bin_intermediates/bin5"
+installed: "out/target/product/fictional/system/bin/bin5"
+sources: "out/target/product/fictional/system/lib/lib5.a"
+deps: {
+ file: "testdata/regressconcur/lib/lib5.a.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/bin/bin6.meta_lic b/tools/compliance/cmd/testdata/regressconcur/bin/bin6.meta_lic
new file mode 100644
index 0000000..4c99b01
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/bin/bin6.meta_lic
@@ -0,0 +1,13 @@
+package_name: "Android"
+module_classes: "EXECUTABLES"
+projects: "bin/onelibrary"
+license_kinds: "legacy_proprietary"
+license_conditions: "proprietary"
+is_container: false
+built: "out/target/product/fictional/obj/EXECUTABLES/bin_intermediates/bin6"
+installed: "out/target/product/fictional/system/bin/bin6"
+sources: "out/target/product/fictional/system/lib/lib6.a"
+deps: {
+ file: "testdata/regressconcur/lib/lib6.a.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/bin/bin7.meta_lic b/tools/compliance/cmd/testdata/regressconcur/bin/bin7.meta_lic
new file mode 100644
index 0000000..565a338
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/bin/bin7.meta_lic
@@ -0,0 +1,13 @@
+package_name: "Android"
+module_classes: "EXECUTABLES"
+projects: "bin/onelibrary"
+license_kinds: "legacy_proprietary"
+license_conditions: "proprietary"
+is_container: false
+built: "out/target/product/fictional/obj/EXECUTABLES/bin_intermediates/bin7"
+installed: "out/target/product/fictional/system/bin/bin7"
+sources: "out/target/product/fictional/system/lib/lib7.a"
+deps: {
+ file: "testdata/regressconcur/lib/lib7.a.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/bin/bin8.meta_lic b/tools/compliance/cmd/testdata/regressconcur/bin/bin8.meta_lic
new file mode 100644
index 0000000..f66c2c9
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/bin/bin8.meta_lic
@@ -0,0 +1,13 @@
+package_name: "Android"
+module_classes: "EXECUTABLES"
+projects: "bin/onelibrary"
+license_kinds: "legacy_proprietary"
+license_conditions: "proprietary"
+is_container: false
+built: "out/target/product/fictional/obj/EXECUTABLES/bin_intermediates/bin8"
+installed: "out/target/product/fictional/system/bin/bin8"
+sources: "out/target/product/fictional/system/lib/lib8.a"
+deps: {
+ file: "testdata/regressconcur/lib/lib8.a.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/bin/bin9.meta_lic b/tools/compliance/cmd/testdata/regressconcur/bin/bin9.meta_lic
new file mode 100644
index 0000000..0aac4c6
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/bin/bin9.meta_lic
@@ -0,0 +1,13 @@
+package_name: "Android"
+module_classes: "EXECUTABLES"
+projects: "bin/onelibrary"
+license_kinds: "legacy_proprietary"
+license_conditions: "proprietary"
+is_container: false
+built: "out/target/product/fictional/obj/EXECUTABLES/bin_intermediates/bin9"
+installed: "out/target/product/fictional/system/bin/bin9"
+sources: "out/target/product/fictional/system/lib/lib9.a"
+deps: {
+ file: "testdata/regressconcur/lib/lib9.a.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/container.zip.meta_lic b/tools/compliance/cmd/testdata/regressconcur/container.zip.meta_lic
new file mode 100644
index 0000000..88683d4
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/container.zip.meta_lic
@@ -0,0 +1,60 @@
+package_name: "Android"
+projects: "container/zip"
+license_kinds: "SPDX-license-identifier-MIT"
+license_conditions: "notice"
+is_container: true
+built: "out/target/product/fictional/obj/ETC/container_intermediates/container.zip"
+installed: "out/target/product/fictional/data/container.zip"
+install_map {
+ from_path: "out/target/product/fictional/system/lib/"
+ container_path: "/"
+}
+install_map {
+ from_path: "out/target/product/fictional/system/bin/"
+ container_path: "/"
+}
+sources: "out/target/product/fictional/system/bin/bin1"
+sources: "out/target/product/fictional/system/bin/bin2"
+sources: "out/target/product/fictional/system/bin/bin3"
+sources: "out/target/product/fictional/system/bin/bin4"
+sources: "out/target/product/fictional/system/bin/bin5"
+sources: "out/target/product/fictional/system/bin/bin6"
+sources: "out/target/product/fictional/system/bin/bin7"
+sources: "out/target/product/fictional/system/bin/bin8"
+sources: "out/target/product/fictional/system/bin/bin9"
+deps: {
+ file: "testdata/regressconcur/bin/bin1.meta_lic"
+ annotations: "static"
+}
+deps: {
+ file: "testdata/regressconcur/bin/bin2.meta_lic"
+ annotations: "static"
+}
+deps: {
+ file: "testdata/regressconcur/bin/bin3.meta_lic"
+ annotations: "static"
+}
+deps: {
+ file: "testdata/regressconcur/bin/bin4.meta_lic"
+ annotations: "static"
+}
+deps: {
+ file: "testdata/regressconcur/bin/bin5.meta_lic"
+ annotations: "static"
+}
+deps: {
+ file: "testdata/regressconcur/bin/bin6.meta_lic"
+ annotations: "static"
+}
+deps: {
+ file: "testdata/regressconcur/bin/bin7.meta_lic"
+ annotations: "static"
+}
+deps: {
+ file: "testdata/regressconcur/bin/bin8.meta_lic"
+ annotations: "static"
+}
+deps: {
+ file: "testdata/regressconcur/bin/bin9.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/lib/lib1.a.meta_lic b/tools/compliance/cmd/testdata/regressconcur/lib/lib1.a.meta_lic
new file mode 100644
index 0000000..89ebd7c
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/lib/lib1.a.meta_lic
@@ -0,0 +1,13 @@
+package_name: "Android"
+projects: "lib/restricted"
+license_kinds: "SPDX-license-identifier-MIT"
+license_conditions: "notice"
+is_container: false
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib1.so"
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib1.a"
+installed: "out/target/product/fictional/system/lib/lib1.so"
+sources: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib2.a"
+deps: {
+ file: "testdata/regressconcur/lib/lib2.a.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/lib/lib2.a.meta_lic b/tools/compliance/cmd/testdata/regressconcur/lib/lib2.a.meta_lic
new file mode 100644
index 0000000..ec84287
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/lib/lib2.a.meta_lic
@@ -0,0 +1,13 @@
+package_name: "Android"
+projects: "lib/restricted"
+license_kinds: "SPDX-license-identifier-MIT"
+license_conditions: "notice"
+is_container: false
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib2.so"
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib2.a"
+installed: "out/target/product/fictional/system/lib/lib2.so"
+sources: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib3.a"
+deps: {
+ file: "testdata/regressconcur/lib/lib3.a.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/lib/lib3.a.meta_lic b/tools/compliance/cmd/testdata/regressconcur/lib/lib3.a.meta_lic
new file mode 100644
index 0000000..1949c06
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/lib/lib3.a.meta_lic
@@ -0,0 +1,13 @@
+package_name: "Android"
+projects: "lib/restricted"
+license_kinds: "SPDX-license-identifier-MIT"
+license_conditions: "notice"
+is_container: false
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib3.so"
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib3.a"
+installed: "out/target/product/fictional/system/lib/lib3.so"
+sources: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib4.a"
+deps: {
+ file: "testdata/regressconcur/lib/lib4.a.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/lib/lib4.a.meta_lic b/tools/compliance/cmd/testdata/regressconcur/lib/lib4.a.meta_lic
new file mode 100644
index 0000000..4dc777b
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/lib/lib4.a.meta_lic
@@ -0,0 +1,13 @@
+package_name: "Android"
+projects: "lib/restricted"
+license_kinds: "SPDX-license-identifier-MIT"
+license_conditions: "notice"
+is_container: false
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib4.so"
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib4.a"
+installed: "out/target/product/fictional/system/lib/lib4.so"
+sources: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib5.a"
+deps: {
+ file: "testdata/regressconcur/lib/lib5.a.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/lib/lib5.a.meta_lic b/tools/compliance/cmd/testdata/regressconcur/lib/lib5.a.meta_lic
new file mode 100644
index 0000000..5d005dc
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/lib/lib5.a.meta_lic
@@ -0,0 +1,13 @@
+package_name: "Android"
+projects: "lib/restricted"
+license_kinds: "SPDX-license-identifier-MIT"
+license_conditions: "notice"
+is_container: false
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib5.so"
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib5.a"
+installed: "out/target/product/fictional/system/lib/lib5.so"
+sources: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib6.a"
+deps: {
+ file: "testdata/regressconcur/lib/lib6.a.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/lib/lib6.a.meta_lic b/tools/compliance/cmd/testdata/regressconcur/lib/lib6.a.meta_lic
new file mode 100644
index 0000000..f2920c3
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/lib/lib6.a.meta_lic
@@ -0,0 +1,13 @@
+package_name: "Android"
+projects: "lib/restricted"
+license_kinds: "SPDX-license-identifier-MIT"
+license_conditions: "notice"
+is_container: false
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib6.so"
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib6.a"
+installed: "out/target/product/fictional/system/lib/lib6.so"
+sources: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib7.a"
+deps: {
+ file: "testdata/regressconcur/lib/lib7.a.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/lib/lib7.a.meta_lic b/tools/compliance/cmd/testdata/regressconcur/lib/lib7.a.meta_lic
new file mode 100644
index 0000000..28c0c5f
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/lib/lib7.a.meta_lic
@@ -0,0 +1,13 @@
+package_name: "Android"
+projects: "lib/restricted"
+license_kinds: "SPDX-license-identifier-MIT"
+license_conditions: "notice"
+is_container: false
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib7.so"
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib7.a"
+installed: "out/target/product/fictional/system/lib/lib7.so"
+sources: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib8.a"
+deps: {
+ file: "testdata/regressconcur/lib/lib8.a.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/lib/lib8.a.meta_lic b/tools/compliance/cmd/testdata/regressconcur/lib/lib8.a.meta_lic
new file mode 100644
index 0000000..b887edc
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/lib/lib8.a.meta_lic
@@ -0,0 +1,13 @@
+package_name: "Android"
+projects: "lib/restricted"
+license_kinds: "SPDX-license-identifier-MIT"
+license_conditions: "notice"
+is_container: false
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib8.so"
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib8.a"
+installed: "out/target/product/fictional/system/lib/lib8.so"
+sources: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib9.a"
+deps: {
+ file: "testdata/regressconcur/lib/lib9.a.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressconcur/lib/lib9.a.meta_lic b/tools/compliance/cmd/testdata/regressconcur/lib/lib9.a.meta_lic
new file mode 100644
index 0000000..9bf155f
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressconcur/lib/lib9.a.meta_lic
@@ -0,0 +1,8 @@
+package_name: "Android"
+projects: "lib/restricted"
+license_kinds: "SPDX-license-identifier-GPL-2.0"
+license_conditions: "restricted"
+is_container: false
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib9.so"
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/lib9.a"
+installed: "out/target/product/fictional/system/lib/lib9.so"
diff --git a/tools/compliance/cmd/testdata/restricted/bin/bin3.meta_lic b/tools/compliance/cmd/testdata/restricted/bin/bin3.meta_lic
index 7ef14e9..859be7f 100644
--- a/tools/compliance/cmd/testdata/restricted/bin/bin3.meta_lic
+++ b/tools/compliance/cmd/testdata/restricted/bin/bin3.meta_lic
@@ -2,7 +2,7 @@
module_classes: "EXECUTABLES"
projects: "standalone/binary"
license_kinds: "SPDX-license-identifier-LGPL-2.0"
-license_conditions: "restricted"
+license_conditions: "restricted_if_statically_linked"
license_texts: "testdata/restricted/RESTRICTED_LICENSE"
is_container: false
built: "out/target/product/fictional/obj/EXECUTABLES/bin_intermediates/bin3"
diff --git a/tools/compliance/cmd/testdata/restricted/lib/liba.so.meta_lic b/tools/compliance/cmd/testdata/restricted/lib/liba.so.meta_lic
index a505d4a..ce5de6e 100644
--- a/tools/compliance/cmd/testdata/restricted/lib/liba.so.meta_lic
+++ b/tools/compliance/cmd/testdata/restricted/lib/liba.so.meta_lic
@@ -1,7 +1,7 @@
package_name: "Device"
projects: "device/library"
license_kinds: "SPDX-license-identifier-LGPL-2.0"
-license_conditions: "restricted"
+license_conditions: "restricted_if_statically_linked"
license_texts: "testdata/restricted/RESTRICTED_LICENSE"
is_container: false
built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/liba.so"
diff --git a/tools/compliance/cmd/textnotice/textnotice.go b/tools/compliance/cmd/textnotice/textnotice.go
index 9beaf58..450290c 100644
--- a/tools/compliance/cmd/textnotice/textnotice.go
+++ b/tools/compliance/cmd/textnotice/textnotice.go
@@ -23,6 +23,7 @@
"io/fs"
"os"
"path/filepath"
+ "sort"
"strings"
"android/soong/response"
@@ -230,7 +231,8 @@
fmt.Fprintln(ctx.stdout)
}
- *ctx.deps = ni.InputNoticeFiles()
+ *ctx.deps = ni.InputFiles()
+ sort.Strings(*ctx.deps)
return nil
}
diff --git a/tools/compliance/cmd/textnotice/textnotice_test.go b/tools/compliance/cmd/textnotice/textnotice_test.go
index e661a44..a902313 100644
--- a/tools/compliance/cmd/textnotice/textnotice_test.go
+++ b/tools/compliance/cmd/textnotice/textnotice_test.go
@@ -65,7 +65,16 @@
usedBy{"highest.apex/lib/libb.so"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/bin/bin1.meta_lic",
+ "testdata/firstparty/bin/bin2.meta_lic",
+ "testdata/firstparty/highest.apex.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libb.so.meta_lic",
+ "testdata/firstparty/lib/libc.a.meta_lic",
+ "testdata/firstparty/lib/libd.so.meta_lic",
+ },
},
{
condition: "firstparty",
@@ -81,7 +90,16 @@
usedBy{"container.zip/libb.so"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/bin/bin1.meta_lic",
+ "testdata/firstparty/bin/bin2.meta_lic",
+ "testdata/firstparty/container.zip.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libb.so.meta_lic",
+ "testdata/firstparty/lib/libc.a.meta_lic",
+ "testdata/firstparty/lib/libd.so.meta_lic",
+ },
},
{
condition: "firstparty",
@@ -93,7 +111,13 @@
usedBy{"application"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/application.meta_lic",
+ "testdata/firstparty/bin/bin3.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libb.so.meta_lic",
+ },
},
{
condition: "firstparty",
@@ -105,7 +129,12 @@
usedBy{"bin/bin1"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/bin/bin1.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libc.a.meta_lic",
+ },
},
{
condition: "firstparty",
@@ -117,7 +146,10 @@
usedBy{"lib/libd.so"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/lib/libd.so.meta_lic",
+ },
},
{
condition: "notice",
@@ -142,6 +174,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/bin/bin1.meta_lic",
+ "testdata/notice/bin/bin2.meta_lic",
+ "testdata/notice/highest.apex.meta_lic",
+ "testdata/notice/lib/liba.so.meta_lic",
+ "testdata/notice/lib/libb.so.meta_lic",
+ "testdata/notice/lib/libc.a.meta_lic",
+ "testdata/notice/lib/libd.so.meta_lic",
},
},
{
@@ -167,6 +206,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/bin/bin1.meta_lic",
+ "testdata/notice/bin/bin2.meta_lic",
+ "testdata/notice/container.zip.meta_lic",
+ "testdata/notice/lib/liba.so.meta_lic",
+ "testdata/notice/lib/libb.so.meta_lic",
+ "testdata/notice/lib/libc.a.meta_lic",
+ "testdata/notice/lib/libd.so.meta_lic",
},
},
{
@@ -186,6 +232,10 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/application.meta_lic",
+ "testdata/notice/bin/bin3.meta_lic",
+ "testdata/notice/lib/liba.so.meta_lic",
+ "testdata/notice/lib/libb.so.meta_lic",
},
},
{
@@ -207,6 +257,9 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/bin/bin1.meta_lic",
+ "testdata/notice/lib/liba.so.meta_lic",
+ "testdata/notice/lib/libc.a.meta_lic",
},
},
{
@@ -219,7 +272,10 @@
usedBy{"lib/libd.so"},
notice{},
},
- expectedDeps: []string{"testdata/notice/NOTICE_LICENSE"},
+ expectedDeps: []string{
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/lib/libd.so.meta_lic",
+ },
},
{
condition: "reciprocal",
@@ -244,6 +300,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/reciprocal/bin/bin1.meta_lic",
+ "testdata/reciprocal/bin/bin2.meta_lic",
+ "testdata/reciprocal/highest.apex.meta_lic",
+ "testdata/reciprocal/lib/liba.so.meta_lic",
+ "testdata/reciprocal/lib/libb.so.meta_lic",
+ "testdata/reciprocal/lib/libc.a.meta_lic",
+ "testdata/reciprocal/lib/libd.so.meta_lic",
},
},
{
@@ -269,6 +332,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/reciprocal/bin/bin1.meta_lic",
+ "testdata/reciprocal/bin/bin2.meta_lic",
+ "testdata/reciprocal/container.zip.meta_lic",
+ "testdata/reciprocal/lib/liba.so.meta_lic",
+ "testdata/reciprocal/lib/libb.so.meta_lic",
+ "testdata/reciprocal/lib/libc.a.meta_lic",
+ "testdata/reciprocal/lib/libd.so.meta_lic",
},
},
{
@@ -288,6 +358,10 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/reciprocal/application.meta_lic",
+ "testdata/reciprocal/bin/bin3.meta_lic",
+ "testdata/reciprocal/lib/liba.so.meta_lic",
+ "testdata/reciprocal/lib/libb.so.meta_lic",
},
},
{
@@ -309,6 +383,9 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/reciprocal/bin/bin1.meta_lic",
+ "testdata/reciprocal/lib/liba.so.meta_lic",
+ "testdata/reciprocal/lib/libc.a.meta_lic",
},
},
{
@@ -323,6 +400,7 @@
},
expectedDeps: []string{
"testdata/notice/NOTICE_LICENSE",
+ "testdata/reciprocal/lib/libd.so.meta_lic",
},
},
{
@@ -353,6 +431,13 @@
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
"testdata/restricted/RESTRICTED_LICENSE",
+ "testdata/restricted/bin/bin1.meta_lic",
+ "testdata/restricted/bin/bin2.meta_lic",
+ "testdata/restricted/highest.apex.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "testdata/restricted/lib/libb.so.meta_lic",
+ "testdata/restricted/lib/libc.a.meta_lic",
+ "testdata/restricted/lib/libd.so.meta_lic",
},
},
{
@@ -383,6 +468,13 @@
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
"testdata/restricted/RESTRICTED_LICENSE",
+ "testdata/restricted/bin/bin1.meta_lic",
+ "testdata/restricted/bin/bin2.meta_lic",
+ "testdata/restricted/container.zip.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "testdata/restricted/lib/libb.so.meta_lic",
+ "testdata/restricted/lib/libc.a.meta_lic",
+ "testdata/restricted/lib/libd.so.meta_lic",
},
},
{
@@ -402,6 +494,10 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/restricted/RESTRICTED_LICENSE",
+ "testdata/restricted/application.meta_lic",
+ "testdata/restricted/bin/bin3.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "testdata/restricted/lib/libb.so.meta_lic",
},
},
{
@@ -426,6 +522,9 @@
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
"testdata/restricted/RESTRICTED_LICENSE",
+ "testdata/restricted/bin/bin1.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "testdata/restricted/lib/libc.a.meta_lic",
},
},
{
@@ -438,7 +537,10 @@
usedBy{"lib/libd.so"},
notice{},
},
- expectedDeps: []string{"testdata/notice/NOTICE_LICENSE"},
+ expectedDeps: []string{
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/restricted/lib/libd.so.meta_lic",
+ },
},
{
condition: "proprietary",
@@ -468,6 +570,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/proprietary/PROPRIETARY_LICENSE",
+ "testdata/proprietary/bin/bin1.meta_lic",
+ "testdata/proprietary/bin/bin2.meta_lic",
+ "testdata/proprietary/highest.apex.meta_lic",
+ "testdata/proprietary/lib/liba.so.meta_lic",
+ "testdata/proprietary/lib/libb.so.meta_lic",
+ "testdata/proprietary/lib/libc.a.meta_lic",
+ "testdata/proprietary/lib/libd.so.meta_lic",
"testdata/restricted/RESTRICTED_LICENSE",
},
},
@@ -499,6 +608,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/proprietary/PROPRIETARY_LICENSE",
+ "testdata/proprietary/bin/bin1.meta_lic",
+ "testdata/proprietary/bin/bin2.meta_lic",
+ "testdata/proprietary/container.zip.meta_lic",
+ "testdata/proprietary/lib/liba.so.meta_lic",
+ "testdata/proprietary/lib/libb.so.meta_lic",
+ "testdata/proprietary/lib/libc.a.meta_lic",
+ "testdata/proprietary/lib/libd.so.meta_lic",
"testdata/restricted/RESTRICTED_LICENSE",
},
},
@@ -519,6 +635,10 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/proprietary/PROPRIETARY_LICENSE",
+ "testdata/proprietary/application.meta_lic",
+ "testdata/proprietary/bin/bin3.meta_lic",
+ "testdata/proprietary/lib/liba.so.meta_lic",
+ "testdata/proprietary/lib/libb.so.meta_lic",
},
},
{
@@ -540,6 +660,9 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/proprietary/PROPRIETARY_LICENSE",
+ "testdata/proprietary/bin/bin1.meta_lic",
+ "testdata/proprietary/lib/liba.so.meta_lic",
+ "testdata/proprietary/lib/libc.a.meta_lic",
},
},
{
@@ -552,7 +675,10 @@
usedBy{"lib/libd.so"},
notice{},
},
- expectedDeps: []string{"testdata/notice/NOTICE_LICENSE"},
+ expectedDeps: []string{
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/proprietary/lib/libd.so.meta_lic",
+ },
},
}
for _, tt := range tests {
diff --git a/tools/compliance/cmd/xmlnotice/xmlnotice.go b/tools/compliance/cmd/xmlnotice/xmlnotice.go
index 2097b7c..c3f8e4c 100644
--- a/tools/compliance/cmd/xmlnotice/xmlnotice.go
+++ b/tools/compliance/cmd/xmlnotice/xmlnotice.go
@@ -24,6 +24,7 @@
"io/fs"
"os"
"path/filepath"
+ "sort"
"strings"
"android/soong/response"
@@ -238,7 +239,8 @@
}
fmt.Fprintln(ctx.stdout, "</licenses>")
- *ctx.deps = ni.InputNoticeFiles()
+ *ctx.deps = ni.InputFiles()
+ sort.Strings(*ctx.deps)
return nil
}
diff --git a/tools/compliance/cmd/xmlnotice/xmlnotice_test.go b/tools/compliance/cmd/xmlnotice/xmlnotice_test.go
index 731e783..551006f 100644
--- a/tools/compliance/cmd/xmlnotice/xmlnotice_test.go
+++ b/tools/compliance/cmd/xmlnotice/xmlnotice_test.go
@@ -65,7 +65,16 @@
target{"highest.apex/lib/libb.so", "Android"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/bin/bin1.meta_lic",
+ "testdata/firstparty/bin/bin2.meta_lic",
+ "testdata/firstparty/highest.apex.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libb.so.meta_lic",
+ "testdata/firstparty/lib/libc.a.meta_lic",
+ "testdata/firstparty/lib/libd.so.meta_lic",
+ },
},
{
condition: "firstparty",
@@ -79,7 +88,16 @@
target{"container.zip/libb.so", "Android"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/bin/bin1.meta_lic",
+ "testdata/firstparty/bin/bin2.meta_lic",
+ "testdata/firstparty/container.zip.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libb.so.meta_lic",
+ "testdata/firstparty/lib/libc.a.meta_lic",
+ "testdata/firstparty/lib/libd.so.meta_lic",
+ },
},
{
condition: "firstparty",
@@ -89,7 +107,13 @@
target{"application", "Android"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/application.meta_lic",
+ "testdata/firstparty/bin/bin3.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libb.so.meta_lic",
+ },
},
{
condition: "firstparty",
@@ -99,7 +123,12 @@
target{"bin/bin1", "Android"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/bin/bin1.meta_lic",
+ "testdata/firstparty/lib/liba.so.meta_lic",
+ "testdata/firstparty/lib/libc.a.meta_lic",
+ },
},
{
condition: "firstparty",
@@ -109,7 +138,10 @@
target{"lib/libd.so", "Android"},
firstParty{},
},
- expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+ expectedDeps: []string{
+ "testdata/firstparty/FIRST_PARTY_LICENSE",
+ "testdata/firstparty/lib/libd.so.meta_lic",
+ },
},
{
condition: "notice",
@@ -129,6 +161,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/bin/bin1.meta_lic",
+ "testdata/notice/bin/bin2.meta_lic",
+ "testdata/notice/highest.apex.meta_lic",
+ "testdata/notice/lib/liba.so.meta_lic",
+ "testdata/notice/lib/libb.so.meta_lic",
+ "testdata/notice/lib/libc.a.meta_lic",
+ "testdata/notice/lib/libd.so.meta_lic",
},
},
{
@@ -149,6 +188,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/bin/bin1.meta_lic",
+ "testdata/notice/bin/bin2.meta_lic",
+ "testdata/notice/container.zip.meta_lic",
+ "testdata/notice/lib/liba.so.meta_lic",
+ "testdata/notice/lib/libb.so.meta_lic",
+ "testdata/notice/lib/libc.a.meta_lic",
+ "testdata/notice/lib/libd.so.meta_lic",
},
},
{
@@ -164,6 +210,10 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/application.meta_lic",
+ "testdata/notice/bin/bin3.meta_lic",
+ "testdata/notice/lib/liba.so.meta_lic",
+ "testdata/notice/lib/libb.so.meta_lic",
},
},
{
@@ -180,6 +230,9 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/bin/bin1.meta_lic",
+ "testdata/notice/lib/liba.so.meta_lic",
+ "testdata/notice/lib/libc.a.meta_lic",
},
},
{
@@ -190,7 +243,10 @@
target{"lib/libd.so", "External"},
notice{},
},
- expectedDeps: []string{"testdata/notice/NOTICE_LICENSE"},
+ expectedDeps: []string{
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/notice/lib/libd.so.meta_lic",
+ },
},
{
condition: "reciprocal",
@@ -210,6 +266,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/reciprocal/bin/bin1.meta_lic",
+ "testdata/reciprocal/bin/bin2.meta_lic",
+ "testdata/reciprocal/highest.apex.meta_lic",
+ "testdata/reciprocal/lib/liba.so.meta_lic",
+ "testdata/reciprocal/lib/libb.so.meta_lic",
+ "testdata/reciprocal/lib/libc.a.meta_lic",
+ "testdata/reciprocal/lib/libd.so.meta_lic",
},
},
{
@@ -230,6 +293,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/reciprocal/bin/bin1.meta_lic",
+ "testdata/reciprocal/bin/bin2.meta_lic",
+ "testdata/reciprocal/container.zip.meta_lic",
+ "testdata/reciprocal/lib/liba.so.meta_lic",
+ "testdata/reciprocal/lib/libb.so.meta_lic",
+ "testdata/reciprocal/lib/libc.a.meta_lic",
+ "testdata/reciprocal/lib/libd.so.meta_lic",
},
},
{
@@ -245,6 +315,10 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/reciprocal/application.meta_lic",
+ "testdata/reciprocal/bin/bin3.meta_lic",
+ "testdata/reciprocal/lib/liba.so.meta_lic",
+ "testdata/reciprocal/lib/libb.so.meta_lic",
},
},
{
@@ -261,6 +335,9 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
+ "testdata/reciprocal/bin/bin1.meta_lic",
+ "testdata/reciprocal/lib/liba.so.meta_lic",
+ "testdata/reciprocal/lib/libc.a.meta_lic",
},
},
{
@@ -271,7 +348,10 @@
target{"lib/libd.so", "External"},
notice{},
},
- expectedDeps: []string{"testdata/notice/NOTICE_LICENSE"},
+ expectedDeps: []string{
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/reciprocal/lib/libd.so.meta_lic",
+ },
},
{
condition: "restricted",
@@ -294,6 +374,13 @@
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
"testdata/restricted/RESTRICTED_LICENSE",
+ "testdata/restricted/bin/bin1.meta_lic",
+ "testdata/restricted/bin/bin2.meta_lic",
+ "testdata/restricted/highest.apex.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "testdata/restricted/lib/libb.so.meta_lic",
+ "testdata/restricted/lib/libc.a.meta_lic",
+ "testdata/restricted/lib/libd.so.meta_lic",
},
},
{
@@ -317,6 +404,13 @@
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
"testdata/restricted/RESTRICTED_LICENSE",
+ "testdata/restricted/bin/bin1.meta_lic",
+ "testdata/restricted/bin/bin2.meta_lic",
+ "testdata/restricted/container.zip.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "testdata/restricted/lib/libb.so.meta_lic",
+ "testdata/restricted/lib/libc.a.meta_lic",
+ "testdata/restricted/lib/libd.so.meta_lic",
},
},
{
@@ -332,6 +426,10 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/restricted/RESTRICTED_LICENSE",
+ "testdata/restricted/application.meta_lic",
+ "testdata/restricted/bin/bin3.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "testdata/restricted/lib/libb.so.meta_lic",
},
},
{
@@ -350,6 +448,9 @@
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/reciprocal/RECIPROCAL_LICENSE",
"testdata/restricted/RESTRICTED_LICENSE",
+ "testdata/restricted/bin/bin1.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "testdata/restricted/lib/libc.a.meta_lic",
},
},
{
@@ -360,7 +461,10 @@
target{"lib/libd.so", "External"},
notice{},
},
- expectedDeps: []string{"testdata/notice/NOTICE_LICENSE"},
+ expectedDeps: []string{
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/restricted/lib/libd.so.meta_lic",
+ },
},
{
condition: "proprietary",
@@ -382,6 +486,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/proprietary/PROPRIETARY_LICENSE",
+ "testdata/proprietary/bin/bin1.meta_lic",
+ "testdata/proprietary/bin/bin2.meta_lic",
+ "testdata/proprietary/highest.apex.meta_lic",
+ "testdata/proprietary/lib/liba.so.meta_lic",
+ "testdata/proprietary/lib/libb.so.meta_lic",
+ "testdata/proprietary/lib/libc.a.meta_lic",
+ "testdata/proprietary/lib/libd.so.meta_lic",
"testdata/restricted/RESTRICTED_LICENSE",
},
},
@@ -405,6 +516,13 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/proprietary/PROPRIETARY_LICENSE",
+ "testdata/proprietary/bin/bin1.meta_lic",
+ "testdata/proprietary/bin/bin2.meta_lic",
+ "testdata/proprietary/container.zip.meta_lic",
+ "testdata/proprietary/lib/liba.so.meta_lic",
+ "testdata/proprietary/lib/libb.so.meta_lic",
+ "testdata/proprietary/lib/libc.a.meta_lic",
+ "testdata/proprietary/lib/libd.so.meta_lic",
"testdata/restricted/RESTRICTED_LICENSE",
},
},
@@ -421,6 +539,10 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/proprietary/PROPRIETARY_LICENSE",
+ "testdata/proprietary/application.meta_lic",
+ "testdata/proprietary/bin/bin3.meta_lic",
+ "testdata/proprietary/lib/liba.so.meta_lic",
+ "testdata/proprietary/lib/libb.so.meta_lic",
},
},
{
@@ -437,6 +559,9 @@
expectedDeps: []string{
"testdata/firstparty/FIRST_PARTY_LICENSE",
"testdata/proprietary/PROPRIETARY_LICENSE",
+ "testdata/proprietary/bin/bin1.meta_lic",
+ "testdata/proprietary/lib/liba.so.meta_lic",
+ "testdata/proprietary/lib/libc.a.meta_lic",
},
},
{
@@ -447,7 +572,10 @@
target{"lib/libd.so", "External"},
notice{},
},
- expectedDeps: []string{"testdata/notice/NOTICE_LICENSE"},
+ expectedDeps: []string{
+ "testdata/notice/NOTICE_LICENSE",
+ "testdata/proprietary/lib/libd.so.meta_lic",
+ },
},
}
for _, tt := range tests {
diff --git a/tools/compliance/condition.go b/tools/compliance/condition.go
index 3145249..2aac78c 100644
--- a/tools/compliance/condition.go
+++ b/tools/compliance/condition.go
@@ -58,15 +58,15 @@
var (
// RecognizedConditionNames maps condition strings to LicenseCondition.
RecognizedConditionNames = map[string]LicenseCondition{
- "unencumbered": UnencumberedCondition,
- "permissive": PermissiveCondition,
- "notice": NoticeCondition,
- "reciprocal": ReciprocalCondition,
- "restricted": RestrictedCondition,
- "restricted_allows_dynamic_linking": WeaklyRestrictedCondition,
- "proprietary": ProprietaryCondition,
- "by_exception_only": ByExceptionOnlyCondition,
- "not_allowed": NotAllowedCondition,
+ "unencumbered": UnencumberedCondition,
+ "permissive": PermissiveCondition,
+ "notice": NoticeCondition,
+ "reciprocal": ReciprocalCondition,
+ "restricted": RestrictedCondition,
+ "restricted_if_statically_linked": WeaklyRestrictedCondition,
+ "proprietary": ProprietaryCondition,
+ "by_exception_only": ByExceptionOnlyCondition,
+ "not_allowed": NotAllowedCondition,
}
)
@@ -84,7 +84,7 @@
case RestrictedCondition:
return "restricted"
case WeaklyRestrictedCondition:
- return "restricted_allows_dynamic_linking"
+ return "restricted_if_statically_linked"
case ProprietaryCondition:
return "proprietary"
case ByExceptionOnlyCondition:
diff --git a/tools/compliance/conditionset_test.go b/tools/compliance/conditionset_test.go
index 020cc0c..e31360d 100644
--- a/tools/compliance/conditionset_test.go
+++ b/tools/compliance/conditionset_test.go
@@ -96,18 +96,18 @@
{
name: "everything",
conditions: []string{"unencumbered", "permissive", "notice", "reciprocal", "restricted", "proprietary"},
- plus: &[]string{"restricted_allows_dynamic_linking", "by_exception_only", "not_allowed"},
+ plus: &[]string{"restricted_if_statically_linked", "by_exception_only", "not_allowed"},
matchingAny: map[string][]string{
- "unencumbered": []string{"unencumbered"},
- "permissive": []string{"permissive"},
- "notice": []string{"notice"},
- "reciprocal": []string{"reciprocal"},
- "restricted": []string{"restricted"},
- "restricted_allows_dynamic_linking": []string{"restricted_allows_dynamic_linking"},
- "proprietary": []string{"proprietary"},
- "by_exception_only": []string{"by_exception_only"},
- "not_allowed": []string{"not_allowed"},
- "notice|proprietary": []string{"notice", "proprietary"},
+ "unencumbered": []string{"unencumbered"},
+ "permissive": []string{"permissive"},
+ "notice": []string{"notice"},
+ "reciprocal": []string{"reciprocal"},
+ "restricted": []string{"restricted"},
+ "restricted_if_statically_linked": []string{"restricted_if_statically_linked"},
+ "proprietary": []string{"proprietary"},
+ "by_exception_only": []string{"by_exception_only"},
+ "not_allowed": []string{"not_allowed"},
+ "notice|proprietary": []string{"notice", "proprietary"},
},
expected: []string{
"unencumbered",
@@ -115,7 +115,7 @@
"notice",
"reciprocal",
"restricted",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"proprietary",
"by_exception_only",
"not_allowed",
@@ -129,7 +129,7 @@
"notice",
"reciprocal",
"restricted",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"proprietary",
"by_exception_only",
"not_allowed",
@@ -148,7 +148,7 @@
"notice",
"reciprocal",
"restricted",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"proprietary",
"by_exception_only",
"not_allowed",
@@ -157,18 +157,18 @@
{
name: "allbutone",
conditions: []string{"unencumbered", "permissive", "notice", "reciprocal", "restricted", "proprietary"},
- plus: &[]string{"restricted_allows_dynamic_linking", "by_exception_only", "not_allowed"},
+ plus: &[]string{"restricted_if_statically_linked", "by_exception_only", "not_allowed"},
matchingAny: map[string][]string{
- "unencumbered": []string{"unencumbered"},
- "permissive": []string{"permissive"},
- "notice": []string{"notice"},
- "reciprocal": []string{"reciprocal"},
- "restricted": []string{"restricted"},
- "restricted_allows_dynamic_linking": []string{"restricted_allows_dynamic_linking"},
- "proprietary": []string{"proprietary"},
- "by_exception_only": []string{"by_exception_only"},
- "not_allowed": []string{"not_allowed"},
- "notice|proprietary": []string{"notice", "proprietary"},
+ "unencumbered": []string{"unencumbered"},
+ "permissive": []string{"permissive"},
+ "notice": []string{"notice"},
+ "reciprocal": []string{"reciprocal"},
+ "restricted": []string{"restricted"},
+ "restricted_if_statically_linked": []string{"restricted_if_statically_linked"},
+ "proprietary": []string{"proprietary"},
+ "by_exception_only": []string{"by_exception_only"},
+ "not_allowed": []string{"not_allowed"},
+ "notice|proprietary": []string{"notice", "proprietary"},
},
expected: []string{
"unencumbered",
@@ -176,7 +176,7 @@
"notice",
"reciprocal",
"restricted",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"proprietary",
"by_exception_only",
"not_allowed",
@@ -190,23 +190,23 @@
"notice",
"reciprocal",
"restricted",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"proprietary",
"by_exception_only",
"not_allowed",
},
- minus: &[]string{"restricted_allows_dynamic_linking"},
+ minus: &[]string{"restricted_if_statically_linked"},
matchingAny: map[string][]string{
- "unencumbered": []string{"unencumbered"},
- "permissive": []string{"permissive"},
- "notice": []string{"notice"},
- "reciprocal": []string{"reciprocal"},
- "restricted": []string{"restricted"},
- "restricted_allows_dynamic_linking": []string{},
- "proprietary": []string{"proprietary"},
- "by_exception_only": []string{"by_exception_only"},
- "not_allowed": []string{"not_allowed"},
- "restricted|proprietary": []string{"restricted", "proprietary"},
+ "unencumbered": []string{"unencumbered"},
+ "permissive": []string{"permissive"},
+ "notice": []string{"notice"},
+ "reciprocal": []string{"reciprocal"},
+ "restricted": []string{"restricted"},
+ "restricted_if_statically_linked": []string{},
+ "proprietary": []string{"proprietary"},
+ "by_exception_only": []string{"by_exception_only"},
+ "not_allowed": []string{"not_allowed"},
+ "restricted|proprietary": []string{"restricted", "proprietary"},
},
expected: []string{
"unencumbered",
@@ -227,7 +227,7 @@
"notice",
"reciprocal",
"restricted",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"proprietary",
"by_exception_only",
"not_allowed",
@@ -238,41 +238,41 @@
"notice",
"reciprocal",
"restricted",
- "restricted_allows_dynamic_linking",
+ "restricted_if_statically_linked",
"proprietary",
"by_exception_only",
"not_allowed",
},
matchingAny: map[string][]string{
- "unencumbered": []string{},
- "permissive": []string{},
- "notice": []string{},
- "reciprocal": []string{},
- "restricted": []string{},
- "restricted_allows_dynamic_linking": []string{},
- "proprietary": []string{},
- "by_exception_only": []string{},
- "not_allowed": []string{},
- "restricted|proprietary": []string{},
+ "unencumbered": []string{},
+ "permissive": []string{},
+ "notice": []string{},
+ "reciprocal": []string{},
+ "restricted": []string{},
+ "restricted_if_statically_linked": []string{},
+ "proprietary": []string{},
+ "by_exception_only": []string{},
+ "not_allowed": []string{},
+ "restricted|proprietary": []string{},
},
expected: []string{},
},
{
name: "restrictedplus",
- conditions: []string{"restricted", "restricted_allows_dynamic_linking"},
+ conditions: []string{"restricted", "restricted_if_statically_linked"},
plus: &[]string{"permissive", "notice", "restricted", "proprietary"},
matchingAny: map[string][]string{
- "unencumbered": []string{},
- "permissive": []string{"permissive"},
- "notice": []string{"notice"},
- "restricted": []string{"restricted"},
- "restricted_allows_dynamic_linking": []string{"restricted_allows_dynamic_linking"},
- "proprietary": []string{"proprietary"},
- "restricted|proprietary": []string{"restricted", "proprietary"},
- "by_exception_only": []string{},
- "proprietary|by_exception_only": []string{"proprietary"},
+ "unencumbered": []string{},
+ "permissive": []string{"permissive"},
+ "notice": []string{"notice"},
+ "restricted": []string{"restricted"},
+ "restricted_if_statically_linked": []string{"restricted_if_statically_linked"},
+ "proprietary": []string{"proprietary"},
+ "restricted|proprietary": []string{"restricted", "proprietary"},
+ "by_exception_only": []string{},
+ "proprietary|by_exception_only": []string{"proprietary"},
},
- expected: []string{"permissive", "notice", "restricted", "restricted_allows_dynamic_linking", "proprietary"},
+ expected: []string{"permissive", "notice", "restricted", "restricted_if_statically_linked", "proprietary"},
},
}
for _, tt := range tests {
diff --git a/tools/compliance/doc.go b/tools/compliance/doc.go
index a47c1cf..5ced9ee 100644
--- a/tools/compliance/doc.go
+++ b/tools/compliance/doc.go
@@ -11,6 +11,10 @@
// 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.
+
+// Much of this content appears too in README.md
+// When changing this file consider whether the change also applies to README.md
+
/*
Package compliance provides an approved means for reading, consuming, and
@@ -31,6 +35,13 @@
artifacts in a release or distribution. While conceptually immutable, parts of
the graph may be loaded or evaluated lazily.
+Conceptually, the graph itself will always be a directed acyclic graph. One
+representation is a set of directed edges. Another is a set of nodes with
+directed edges to their dependencies.
+
+The edges have annotations, which can distinguish between build tools, runtime
+dependencies, and dependencies like 'contains' that make a derivative work.
+
LicenseCondition
----------------
@@ -51,17 +62,13 @@
`ActsOn` is the target to share, give notice for, hide etc.
-`Resolves` is the license condition that the action resolves.
+`Resolves` is the set of condition types that the action resolves.
-Remember: Each license condition pairs a condition name with an originating
-target so each resolution in a ResolutionSet has two targets it applies to and
-one target from which it originates, all of which may be the same target.
-
-For most condition types, `ActsOn` and `Resolves.Origin` will be the same
-target. For example, a notice condition policy means attribution or notice must
-be given for the target where the condition originates. Likewise, a proprietary
-condition policy means the privacy of the target where the condition originates
-must be respected. i.e. The thing acted on is the origin.
+For most condition types, `ActsOn` will be the target where the condition
+originated. For example, a notice condition policy means attribution or notice
+must be given for the target where the condition originates. Likewise, a
+proprietary condition policy means the privacy of the target where the
+condition originates must be respected. i.e. The thing acted on is the origin.
Restricted conditions are different. The infectious nature of restricted often
means sharing code that is not the target where the restricted condition
diff --git a/tools/compliance/graph.go b/tools/compliance/graph.go
index e73ab46..9ad319b 100644
--- a/tools/compliance/graph.go
+++ b/tools/compliance/graph.go
@@ -58,13 +58,11 @@
/// (guarded by mu)
targets map[string]*TargetNode
- // wgBU becomes non-nil when the bottom-up resolve begins and reaches 0
- // (i.e. Wait() proceeds) when the bottom-up resolve completes. (guarded by mu)
- wgBU *sync.WaitGroup
+ // onceBottomUp makes sure the bottom-up resolve walk only happens one time.
+ onceBottomUp sync.Once
- // wgTD becomes non-nil when the top-down resolve begins and reaches 0 (i.e. Wait()
- // proceeds) when the top-down resolve completes. (guarded by mu)
- wgTD *sync.WaitGroup
+ // onceTopDown makes sure the top-down resolve walk only happens one time.
+ onceTopDown sync.Once
// shippedNodes caches the results of a full walk of nodes identifying targets
// distributed either directly or as derivative works. (creation guarded by mu)
@@ -90,6 +88,15 @@
return targets
}
+// TargetNames returns the list of target node names in the graph. (unordered)
+func (lg *LicenseGraph) TargetNames() []string {
+ targets := make([]string, 0, len(lg.targets))
+ for target := range lg.targets {
+ targets = append(targets, target)
+ }
+ return targets
+}
+
// compliance-only LicenseGraph methods
// newLicenseGraph constructs a new, empty instance of LicenseGraph.
@@ -139,6 +146,24 @@
return e.annotations
}
+// IsRuntimeDependency returns true for edges representing shared libraries
+// linked dynamically at runtime.
+func (e *TargetEdge) IsRuntimeDependency() bool {
+ return edgeIsDynamicLink(e)
+}
+
+// IsDerivation returns true for edges where the target is a derivative
+// work of dependency.
+func (e *TargetEdge) IsDerivation() bool {
+ return edgeIsDerivation(e)
+}
+
+// IsBuildTool returns true for edges where the target is built
+// by dependency.
+func (e *TargetEdge) IsBuildTool() bool {
+ return !edgeIsDerivation(e) && !edgeIsDynamicLink(e)
+}
+
// String returns a human-readable string representation of the edge.
func (e *TargetEdge) String() string {
return fmt.Sprintf("%s -[%s]> %s", e.target.name, strings.Join(e.annotations.AsList(), ", "), e.dependency.name)
@@ -188,6 +213,11 @@
return s.edge.dependency
}
+// Edge describes the target edge.
+func (s TargetEdgePathSegment) Edge() *TargetEdge {
+ return s.edge
+}
+
// Annotations describes the type of edge by the set of annotations attached to
// it.
//
@@ -300,21 +330,9 @@
return tn.proto.GetPackageName()
}
-// ModuleTypes returns the list of module types implementing the target.
-// (unordered)
-//
-// In an ideal world, only 1 module type would implement each target, but the
-// interactions between Soong and Make for host versus product and for a
-// variety of architectures sometimes causes multiple module types per target
-// (often a regular build target and a prebuilt.)
-func (tn *TargetNode) ModuleTypes() []string {
- return append([]string{}, tn.proto.ModuleTypes...)
-}
-
-// ModuleClasses returns the list of module classes implementing the target.
-// (unordered)
-func (tn *TargetNode) ModuleClasses() []string {
- return append([]string{}, tn.proto.ModuleClasses...)
+// ModuleName returns the module name of the target.
+func (tn *TargetNode) ModuleName() string {
+ return tn.proto.GetModuleName()
}
// Projects returns the projects defining the target node. (unordered)
@@ -326,14 +344,6 @@
return append([]string{}, tn.proto.Projects...)
}
-// LicenseKinds returns the list of license kind names for the module or
-// target. (unordered)
-//
-// e.g. SPDX-license-identifier-MIT or legacy_proprietary
-func (tn *TargetNode) LicenseKinds() []string {
- return append([]string{}, tn.proto.LicenseKinds...)
-}
-
// LicenseConditions returns a copy of the set of license conditions
// originating at the target. The values that appear and how each is resolved
// is a matter of policy. (unordered)
@@ -458,36 +468,25 @@
}
// TargetNodeSet describes a set of distinct nodes in a license graph.
-type TargetNodeSet struct {
- nodes map[*TargetNode]struct{}
-}
+type TargetNodeSet map[*TargetNode]struct{}
// Contains returns true when `target` is an element of the set.
-func (ts *TargetNodeSet) Contains(target *TargetNode) bool {
- _, isPresent := ts.nodes[target]
+func (ts TargetNodeSet) Contains(target *TargetNode) bool {
+ _, isPresent := ts[target]
return isPresent
}
-// AsList returns the list of target nodes in the set. (unordered)
-func (ts *TargetNodeSet) AsList() TargetNodeList {
- result := make(TargetNodeList, 0, len(ts.nodes))
- for tn := range ts.nodes {
- result = append(result, tn)
- }
- return result
-}
-
// Names returns the array of target node namess in the set. (unordered)
-func (ts *TargetNodeSet) Names() []string {
- result := make([]string, 0, len(ts.nodes))
- for tn := range ts.nodes {
+func (ts TargetNodeSet) Names() []string {
+ result := make([]string, 0, len(ts))
+ for tn := range ts {
result = append(result, tn.name)
}
return result
}
// String returns a human-readable string representation of the set.
-func (ts *TargetNodeSet) String() string {
+func (ts TargetNodeSet) String() string {
return fmt.Sprintf("{%s}", strings.Join(ts.Names(), ", "))
}
diff --git a/tools/compliance/noticeindex.go b/tools/compliance/noticeindex.go
index 86d42ac..c91a8df 100644
--- a/tools/compliance/noticeindex.go
+++ b/tools/compliance/noticeindex.go
@@ -15,7 +15,6 @@
package compliance
import (
- "bufio"
"crypto/md5"
"fmt"
"io"
@@ -25,16 +24,11 @@
"regexp"
"sort"
"strings"
-)
-const (
- noProjectName = "\u2205"
+ "android/soong/tools/compliance/projectmetadata"
)
var (
- nameRegexp = regexp.MustCompile(`^\s*name\s*:\s*"(.*)"\s*$`)
- descRegexp = regexp.MustCompile(`^\s*description\s*:\s*"(.*)"\s*$`)
- versionRegexp = regexp.MustCompile(`^\s*version\s*:\s*"(.*)"\s*$`)
licensesPathRegexp = regexp.MustCompile(`licen[cs]es?/`)
)
@@ -43,10 +37,12 @@
type NoticeIndex struct {
// lg identifies the license graph to which the index applies.
lg *LicenseGraph
+ // pmix indexes project metadata
+ pmix *projectmetadata.Index
// rs identifies the set of resolutions upon which the index is based.
rs ResolutionSet
// shipped identifies the set of target nodes shipped directly or as derivative works.
- shipped *TargetNodeSet
+ shipped TargetNodeSet
// rootFS locates the root of the file system from which to read the files.
rootFS fs.FS
// hash maps license text filenames to content hashes
@@ -75,6 +71,7 @@
}
ni := &NoticeIndex{
lg: lg,
+ pmix: projectmetadata.NewIndex(rootFS),
rs: rs,
shipped: ShippedNodes(lg),
rootFS: rootFS,
@@ -110,9 +107,12 @@
return hashes, nil
}
- link := func(tn *TargetNode, hashes map[hash]struct{}, installPaths []string) {
+ link := func(tn *TargetNode, hashes map[hash]struct{}, installPaths []string) error {
for h := range hashes {
- libName := ni.getLibName(tn, h)
+ libName, err := ni.getLibName(tn, h)
+ if err != nil {
+ return err
+ }
if _, ok := ni.libHash[libName]; !ok {
ni.libHash[libName] = make(map[hash]struct{})
}
@@ -145,6 +145,11 @@
}
}
}
+ return nil
+ }
+
+ cacheMetadata := func(tn *TargetNode) {
+ ni.pmix.MetadataForProjects(tn.Projects()...)
}
// returns error from walk below.
@@ -157,13 +162,17 @@
if !ni.shipped.Contains(tn) {
return false
}
+ go cacheMetadata(tn)
installPaths := getInstallPaths(tn, path)
var hashes map[hash]struct{}
hashes, err = index(tn)
if err != nil {
return false
}
- link(tn, hashes, installPaths)
+ err = link(tn, hashes, installPaths)
+ if err != nil {
+ return false
+ }
if tn.IsContainer() {
return true
}
@@ -173,7 +182,10 @@
if err != nil {
return false
}
- link(r.actsOn, hashes, installPaths)
+ err = link(r.actsOn, hashes, installPaths)
+ if err != nil {
+ return false
+ }
}
return false
})
@@ -214,12 +226,18 @@
close(c)
}()
return c
+
}
-// InputNoticeFiles returns the list of files that were hashed during IndexLicenseTexts.
-func (ni *NoticeIndex) InputNoticeFiles() []string {
- files := append([]string(nil), ni.files...)
- sort.Strings(files)
+// InputFiles returns the complete list of files read during indexing.
+func (ni *NoticeIndex) InputFiles() []string {
+ projectMeta := ni.pmix.AllMetadataFiles()
+ files := make([]string, 0, len(ni.files) + len(ni.lg.targets) + len(projectMeta))
+ files = append(files, ni.files...)
+ for f := range ni.lg.targets {
+ files = append(files, f)
+ }
+ files = append(files, projectMeta...)
return files
}
@@ -308,15 +326,18 @@
}
// getLibName returns the name of the library associated with `noticeFor`.
-func (ni *NoticeIndex) getLibName(noticeFor *TargetNode, h hash) string {
+func (ni *NoticeIndex) getLibName(noticeFor *TargetNode, h hash) (string, error) {
for _, text := range noticeFor.LicenseTexts() {
if !strings.Contains(text, ":") {
if ni.hash[text].key != h.key {
continue
}
- ln := ni.checkMetadataForLicenseText(noticeFor, text)
+ ln, err := ni.checkMetadataForLicenseText(noticeFor, text)
+ if err != nil {
+ return "", err
+ }
if len(ln) > 0 {
- return ln
+ return ln, nil
}
continue
}
@@ -331,17 +352,20 @@
if err != nil {
continue
}
- return ln
+ return ln, nil
}
// use name from METADATA if available
- ln := ni.checkMetadata(noticeFor)
+ ln, err := ni.checkMetadata(noticeFor)
+ if err != nil {
+ return "", err
+ }
if len(ln) > 0 {
- return ln
+ return ln, nil
}
// use package_name: from license{} module if available
pn := noticeFor.PackageName()
if len(pn) > 0 {
- return pn
+ return pn, nil
}
for _, p := range noticeFor.Projects() {
if strings.HasPrefix(p, "prebuilts/") {
@@ -385,7 +409,7 @@
match = match[:li]
}
}
- return match
+ return match, nil
}
break
}
@@ -393,9 +417,9 @@
for _, safePathPrefix := range safePathPrefixes {
if strings.HasPrefix(p, safePathPrefix.prefix) {
if safePathPrefix.strip {
- return p[len(safePathPrefix.prefix):]
+ return p[len(safePathPrefix.prefix):], nil
} else {
- return p
+ return p, nil
}
}
}
@@ -410,35 +434,26 @@
if fi > 0 {
n = n[:fi]
}
- return n
+ return n, nil
}
// checkMetadata tries to look up a library name from a METADATA file associated with `noticeFor`.
-func (ni *NoticeIndex) checkMetadata(noticeFor *TargetNode) string {
- for _, p := range noticeFor.Projects() {
- if name, ok := ni.projectName[p]; ok {
- if name == noProjectName {
- continue
- }
- return name
- }
- name, err := ni.checkMetadataFile(filepath.Join(p, "METADATA"))
- if err != nil {
- ni.projectName[p] = noProjectName
- continue
- }
- if len(name) == 0 {
- ni.projectName[p] = noProjectName
- continue
- }
- ni.projectName[p] = name
- return name
+func (ni *NoticeIndex) checkMetadata(noticeFor *TargetNode) (string, error) {
+ pms, err := ni.pmix.MetadataForProjects(noticeFor.Projects()...)
+ if err != nil {
+ return "", err
}
- return ""
+ for _, pm := range pms {
+ name := pm.VersionedName()
+ if name != "" {
+ return name, nil
+ }
+ }
+ return "", nil
}
// checkMetadataForLicenseText
-func (ni *NoticeIndex) checkMetadataForLicenseText(noticeFor *TargetNode, licenseText string) string {
+func (ni *NoticeIndex) checkMetadataForLicenseText(noticeFor *TargetNode, licenseText string) (string, error) {
p := ""
for _, proj := range noticeFor.Projects() {
if strings.HasPrefix(licenseText, proj) {
@@ -456,79 +471,17 @@
p = filepath.Dir(p)
continue
}
- return ""
+ return "", nil
}
}
- if name, ok := ni.projectName[p]; ok {
- if name == noProjectName {
- return ""
- }
- return name
- }
- name, err := ni.checkMetadataFile(filepath.Join(p, "METADATA"))
- if err == nil && len(name) > 0 {
- ni.projectName[p] = name
- return name
- }
- ni.projectName[p] = noProjectName
- return ""
-}
-
-// checkMetadataFile tries to look up a library name from a METADATA file at `path`.
-func (ni *NoticeIndex) checkMetadataFile(path string) (string, error) {
- f, err := ni.rootFS.Open(path)
+ pms, err := ni.pmix.MetadataForProjects(p)
if err != nil {
return "", err
}
- name := ""
- description := ""
- version := ""
- s := bufio.NewScanner(f)
- for s.Scan() {
- line := s.Text()
- m := nameRegexp.FindStringSubmatch(line)
- if m != nil {
- if 1 < len(m) && m[1] != "" {
- name = m[1]
- }
- if version != "" {
- break
- }
- continue
- }
- m = versionRegexp.FindStringSubmatch(line)
- if m != nil {
- if 1 < len(m) && m[1] != "" {
- version = m[1]
- }
- if name != "" {
- break
- }
- continue
- }
- m = descRegexp.FindStringSubmatch(line)
- if m != nil {
- if 1 < len(m) && m[1] != "" {
- description = m[1]
- }
- }
+ if pms == nil {
+ return "", nil
}
- _ = s.Err()
- _ = f.Close()
- if name != "" {
- if version != "" {
- if version[0] == 'v' || version[0] == 'V' {
- return name + "_" + version, nil
- } else {
- return name + "_v_" + version, nil
- }
- }
- return name, nil
- }
- if description != "" {
- return description, nil
- }
- return "", nil
+ return pms[0].VersionedName(), nil
}
// addText reads and indexes the content of a license text file.
diff --git a/tools/compliance/policy_policy.go b/tools/compliance/policy_policy.go
index 02d1d96..368a162 100644
--- a/tools/compliance/policy_policy.go
+++ b/tools/compliance/policy_policy.go
@@ -114,35 +114,9 @@
// LicenseConditionSetFromNames returns a set containing the recognized `names` and
// silently ignoring or discarding the unrecognized `names`.
-func LicenseConditionSetFromNames(tn *TargetNode, names ...string) LicenseConditionSet {
+func LicenseConditionSetFromNames(names ...string) LicenseConditionSet {
cs := NewLicenseConditionSet()
for _, name := range names {
- if name == "restricted" {
- if 0 == len(tn.LicenseKinds()) {
- cs = cs.Plus(RestrictedCondition)
- continue
- }
- hasLgpl := false
- hasGeneric := false
- for _, kind := range tn.LicenseKinds() {
- if anyLgpl.MatchString(kind) {
- cs = cs.Plus(WeaklyRestrictedCondition)
- hasLgpl = true
- } else if versionedGpl.MatchString(kind) {
- cs = cs.Plus(RestrictedCondition)
- } else if genericGpl.MatchString(kind) {
- hasGeneric = true
- } else if kind == "legacy_restricted" || ccBySa.MatchString(kind) {
- cs = cs.Plus(RestrictedCondition)
- } else {
- cs = cs.Plus(RestrictedCondition)
- }
- }
- if hasGeneric && !hasLgpl {
- cs = cs.Plus(RestrictedCondition)
- }
- continue
- }
if lc, ok := RecognizedConditionNames[name]; ok {
cs |= LicenseConditionSet(lc)
}
diff --git a/tools/compliance/policy_policy_test.go b/tools/compliance/policy_policy_test.go
index 6188eb2..f003314 100644
--- a/tools/compliance/policy_policy_test.go
+++ b/tools/compliance/policy_policy_test.go
@@ -49,8 +49,8 @@
name: "fponlgpl",
edge: annotated{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}},
expectedDepActions: []string{
- "apacheBin.meta_lic:lgplLib.meta_lic:restricted_allows_dynamic_linking",
- "lgplLib.meta_lic:lgplLib.meta_lic:restricted_allows_dynamic_linking",
+ "apacheBin.meta_lic:lgplLib.meta_lic:restricted_if_statically_linked",
+ "lgplLib.meta_lic:lgplLib.meta_lic:restricted_if_statically_linked",
},
expectedTargetConditions: []string{},
},
@@ -85,15 +85,15 @@
expectedTargetConditions: []string{},
},
{
- name: "independentmodulestatic",
- edge: annotated{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}},
- expectedDepActions: []string{},
+ name: "independentmodulestatic",
+ edge: annotated{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}},
+ expectedDepActions: []string{},
expectedTargetConditions: []string{},
},
{
- name: "dependentmodule",
- edge: annotated{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
- expectedDepActions: []string{},
+ name: "dependentmodule",
+ edge: annotated{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
+ expectedDepActions: []string{},
expectedTargetConditions: []string{},
},
@@ -101,7 +101,7 @@
name: "lgplonfp",
edge: annotated{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
expectedDepActions: []string{},
- expectedTargetConditions: []string{"lgplBin.meta_lic:restricted_allows_dynamic_linking"},
+ expectedTargetConditions: []string{"lgplBin.meta_lic:restricted_if_statically_linked"},
},
{
name: "lgplonfpdynamic",
diff --git a/tools/compliance/policy_resolve.go b/tools/compliance/policy_resolve.go
index 93335a9..0951ba1 100644
--- a/tools/compliance/policy_resolve.go
+++ b/tools/compliance/policy_resolve.go
@@ -14,10 +14,6 @@
package compliance
-import (
- "sync"
-)
-
var (
// AllResolutions is a TraceConditions function that resolves all
// unfiltered license conditions.
@@ -49,84 +45,57 @@
func TraceBottomUpConditions(lg *LicenseGraph, conditionsFn TraceConditions) {
// short-cut if already walked and cached
- lg.mu.Lock()
- wg := lg.wgBU
+ lg.onceBottomUp.Do(func() {
+ // amap identifes targets previously walked. (guarded by mu)
+ amap := make(map[*TargetNode]struct{})
- if wg != nil {
- lg.mu.Unlock()
- wg.Wait()
- return
- }
- wg = &sync.WaitGroup{}
- wg.Add(1)
- lg.wgBU = wg
- lg.mu.Unlock()
+ var walk func(target *TargetNode, treatAsAggregate bool) LicenseConditionSet
- // amap identifes targets previously walked. (guarded by mu)
- amap := make(map[*TargetNode]struct{})
-
- // mu guards concurrent access to amap
- var mu sync.Mutex
-
- var walk func(target *TargetNode, treatAsAggregate bool) LicenseConditionSet
-
- walk = func(target *TargetNode, treatAsAggregate bool) LicenseConditionSet {
- priorWalkResults := func() (LicenseConditionSet, bool) {
- mu.Lock()
- defer mu.Unlock()
-
- if _, alreadyWalked := amap[target]; alreadyWalked {
- if treatAsAggregate {
- return target.resolution, true
+ walk = func(target *TargetNode, treatAsAggregate bool) LicenseConditionSet {
+ priorWalkResults := func() (LicenseConditionSet, bool) {
+ if _, alreadyWalked := amap[target]; alreadyWalked {
+ if treatAsAggregate {
+ return target.resolution, true
+ }
+ if !target.pure {
+ return target.resolution, true
+ }
+ // previously walked in a pure aggregate context,
+ // needs to walk again in non-aggregate context
+ } else {
+ target.resolution |= conditionsFn(target)
+ amap[target] = struct{}{}
}
- if !target.pure {
- return target.resolution, true
- }
- // previously walked in a pure aggregate context,
- // needs to walk again in non-aggregate context
- } else {
- target.resolution |= conditionsFn(target)
- amap[target] = struct{}{}
+ target.pure = treatAsAggregate
+ return target.resolution, false
}
- target.pure = treatAsAggregate
- return target.resolution, false
- }
- cs, alreadyWalked := priorWalkResults()
- if alreadyWalked {
+ cs, alreadyWalked := priorWalkResults()
+ if alreadyWalked {
+ return cs
+ }
+
+ // add all the conditions from all the dependencies
+ for _, edge := range target.edges {
+ // walk dependency to get its conditions
+ dcs := walk(edge.dependency, treatAsAggregate && edge.dependency.IsContainer())
+
+ // turn those into the conditions that apply to the target
+ dcs = depConditionsPropagatingToTarget(lg, edge, dcs, treatAsAggregate)
+ cs |= dcs
+ }
+ target.resolution |= cs
+ cs = target.resolution
+
+ // return conditions up the tree
return cs
}
- c := make(chan LicenseConditionSet, len(target.edges))
- // add all the conditions from all the dependencies
- for _, edge := range target.edges {
- go func(edge *TargetEdge) {
- // walk dependency to get its conditions
- cs := walk(edge.dependency, treatAsAggregate && edge.dependency.IsContainer())
-
- // turn those into the conditions that apply to the target
- cs = depConditionsPropagatingToTarget(lg, edge, cs, treatAsAggregate)
-
- c <- cs
- }(edge)
+ // walk each of the roots
+ for _, rname := range lg.rootFiles {
+ rnode := lg.targets[rname]
+ _ = walk(rnode, rnode.IsContainer())
}
- for i := 0; i < len(target.edges); i++ {
- cs |= <-c
- }
- mu.Lock()
- target.resolution |= cs
- mu.Unlock()
-
- // return conditions up the tree
- return cs
- }
-
- // walk each of the roots
- for _, rname := range lg.rootFiles {
- rnode := lg.targets[rname]
- _ = walk(rnode, rnode.IsContainer())
- }
-
- wg.Done()
+ })
}
// ResolveTopDownCondtions performs a top-down walk of the LicenseGraph
@@ -145,78 +114,61 @@
func TraceTopDownConditions(lg *LicenseGraph, conditionsFn TraceConditions) {
// short-cut if already walked and cached
- lg.mu.Lock()
- wg := lg.wgTD
+ lg.onceTopDown.Do(func() {
+ // start with the conditions propagated up the graph
+ TraceBottomUpConditions(lg, conditionsFn)
- if wg != nil {
- lg.mu.Unlock()
- wg.Wait()
- return
- }
- wg = &sync.WaitGroup{}
- wg.Add(1)
- lg.wgTD = wg
- lg.mu.Unlock()
+ // amap contains the set of targets already walked. (guarded by mu)
+ amap := make(map[*TargetNode]struct{})
- // start with the conditions propagated up the graph
- TraceBottomUpConditions(lg, conditionsFn)
+ var walk func(fnode *TargetNode, cs LicenseConditionSet, treatAsAggregate bool)
- // amap contains the set of targets already walked. (guarded by mu)
- amap := make(map[*TargetNode]struct{})
-
- // mu guards concurrent access to amap
- var mu sync.Mutex
-
- var walk func(fnode *TargetNode, cs LicenseConditionSet, treatAsAggregate bool)
-
- walk = func(fnode *TargetNode, cs LicenseConditionSet, treatAsAggregate bool) {
- defer wg.Done()
- mu.Lock()
- fnode.resolution |= conditionsFn(fnode)
- fnode.resolution |= cs
- fnode.pure = treatAsAggregate
- amap[fnode] = struct{}{}
- cs = fnode.resolution
- mu.Unlock()
- // for each dependency
- for _, edge := range fnode.edges {
- func(edge *TargetEdge) {
- // dcs holds the dpendency conditions inherited from the target
- dcs := targetConditionsPropagatingToDep(lg, edge, cs, treatAsAggregate, conditionsFn)
- dnode := edge.dependency
- mu.Lock()
- defer mu.Unlock()
- depcs := dnode.resolution
- _, alreadyWalked := amap[dnode]
- if !dcs.IsEmpty() && alreadyWalked {
- if dcs.Difference(depcs).IsEmpty() {
+ walk = func(fnode *TargetNode, cs LicenseConditionSet, treatAsAggregate bool) {
+ continueWalk := func() bool {
+ if _, alreadyWalked := amap[fnode]; alreadyWalked {
+ if cs.IsEmpty() {
+ return false
+ }
+ if cs.Difference(fnode.resolution).IsEmpty() {
// no new conditions
// pure aggregates never need walking a 2nd time with same conditions
if treatAsAggregate {
- return
+ return false
}
// non-aggregates don't need walking as non-aggregate a 2nd time
- if !dnode.pure {
- return
+ if !fnode.pure {
+ return false
}
// previously walked as pure aggregate; need to re-walk as non-aggregate
}
+ } else {
+ fnode.resolution |= conditionsFn(fnode)
}
+ fnode.resolution |= cs
+ fnode.pure = treatAsAggregate
+ amap[fnode] = struct{}{}
+ cs = fnode.resolution
+ return true
+ }()
+ if !continueWalk {
+ return
+ }
+ // for each dependency
+ for _, edge := range fnode.edges {
+ // dcs holds the dpendency conditions inherited from the target
+ dcs := targetConditionsPropagatingToDep(lg, edge, cs, treatAsAggregate, conditionsFn)
+ dnode := edge.dependency
// add the conditions to the dependency
- wg.Add(1)
- go walk(dnode, dcs, treatAsAggregate && dnode.IsContainer())
- }(edge)
+ walk(dnode, dcs, treatAsAggregate && dnode.IsContainer())
+ }
}
- }
- // walk each of the roots
- for _, rname := range lg.rootFiles {
- rnode := lg.targets[rname]
- wg.Add(1)
- // add the conditions to the root and its transitive closure
- go walk(rnode, NewLicenseConditionSet(), rnode.IsContainer())
- }
- wg.Done()
- wg.Wait()
+ // walk each of the roots
+ for _, rname := range lg.rootFiles {
+ rnode := lg.targets[rname]
+ // add the conditions to the root and its transitive closure
+ walk(rnode, NewLicenseConditionSet(), rnode.IsContainer())
+ }
+ })
}
diff --git a/tools/compliance/policy_resolve_test.go b/tools/compliance/policy_resolve_test.go
index d6731fe..f9ea6a1 100644
--- a/tools/compliance/policy_resolve_test.go
+++ b/tools/compliance/policy_resolve_test.go
@@ -204,8 +204,8 @@
{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}},
},
expectedActions: []tcond{
- {"apacheBin.meta_lic", "notice|restricted_allows_dynamic_linking"},
- {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
+ {"apacheBin.meta_lic", "notice|restricted_if_statically_linked"},
+ {"lgplLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -216,7 +216,7 @@
},
expectedActions: []tcond{
{"apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
+ {"lgplLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -227,9 +227,9 @@
{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}},
},
expectedActions: []tcond{
- {"apacheContainer.meta_lic", "notice|restricted_allows_dynamic_linking"},
- {"apacheBin.meta_lic", "notice|restricted_allows_dynamic_linking"},
- {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
+ {"apacheContainer.meta_lic", "notice|restricted_if_statically_linked"},
+ {"apacheBin.meta_lic", "notice|restricted_if_statically_linked"},
+ {"lgplLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -240,9 +240,9 @@
{"apacheContainer.meta_lic", "lgplLib.meta_lic", []string{"static"}},
},
expectedActions: []tcond{
- {"apacheContainer.meta_lic", "notice|restricted_allows_dynamic_linking"},
+ {"apacheContainer.meta_lic", "notice|restricted_if_statically_linked"},
{"apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
+ {"lgplLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -253,7 +253,7 @@
},
expectedActions: []tcond{
{"apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
+ {"lgplLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -266,7 +266,7 @@
expectedActions: []tcond{
{"apacheContainer.meta_lic", "notice"},
{"apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
+ {"lgplLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -279,7 +279,7 @@
expectedActions: []tcond{
{"apacheContainer.meta_lic", "notice"},
{"apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
+ {"lgplLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -500,9 +500,9 @@
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedActions: []tcond{
- {"apacheBin.meta_lic", "notice|restricted_allows_dynamic_linking"},
- {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
- {"mitLib.meta_lic", "notice|restricted_allows_dynamic_linking"},
+ {"apacheBin.meta_lic", "notice|restricted_if_statically_linked"},
+ {"lgplLib.meta_lic", "restricted_if_statically_linked"},
+ {"mitLib.meta_lic", "notice|restricted_if_statically_linked"},
},
},
{
@@ -514,7 +514,7 @@
},
expectedActions: []tcond{
{"apacheBin.meta_lic", "notice"},
- {"lgplBin.meta_lic", "restricted_allows_dynamic_linking"},
+ {"lgplBin.meta_lic", "restricted_if_statically_linked"},
{"mitLib.meta_lic", "notice"},
},
},
@@ -527,10 +527,10 @@
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedActions: []tcond{
- {"apacheContainer.meta_lic", "notice|restricted_allows_dynamic_linking"},
- {"apacheBin.meta_lic", "notice|restricted_allows_dynamic_linking"},
- {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
- {"mitLib.meta_lic", "notice|restricted_allows_dynamic_linking"},
+ {"apacheContainer.meta_lic", "notice|restricted_if_statically_linked"},
+ {"apacheBin.meta_lic", "notice|restricted_if_statically_linked"},
+ {"lgplLib.meta_lic", "restricted_if_statically_linked"},
+ {"mitLib.meta_lic", "notice|restricted_if_statically_linked"},
},
},
{
@@ -541,9 +541,9 @@
{"apacheContainer.meta_lic", "lgplLib.meta_lic", []string{"static"}},
},
expectedActions: []tcond{
- {"apacheContainer.meta_lic", "notice|restricted_allows_dynamic_linking"},
+ {"apacheContainer.meta_lic", "notice|restricted_if_statically_linked"},
{"apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
+ {"lgplLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -555,7 +555,7 @@
},
expectedActions: []tcond{
{"apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
+ {"lgplLib.meta_lic", "restricted_if_statically_linked"},
{"mitLib.meta_lic", "notice"},
},
},
@@ -569,7 +569,7 @@
expectedActions: []tcond{
{"apacheContainer.meta_lic", "notice"},
{"apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
+ {"lgplLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -582,7 +582,7 @@
expectedActions: []tcond{
{"apacheContainer.meta_lic", "notice"},
{"apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
+ {"lgplLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
diff --git a/tools/compliance/policy_resolvenotices_test.go b/tools/compliance/policy_resolvenotices_test.go
index ee5e3b8..b23e587 100644
--- a/tools/compliance/policy_resolvenotices_test.go
+++ b/tools/compliance/policy_resolvenotices_test.go
@@ -33,8 +33,8 @@
{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheLib.meta_lic", "notice"},
},
},
{
@@ -44,7 +44,7 @@
{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
},
},
{
@@ -54,8 +54,8 @@
{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
},
},
{
@@ -66,11 +66,9 @@
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice|restricted"},
+ {"apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "mitLib.meta_lic", "notice|restricted"},
},
},
{
@@ -81,8 +79,8 @@
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "mitLib.meta_lic", "notice"},
},
},
{
@@ -96,22 +94,17 @@
{"mitBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "mitBin.meta_lic", "mitBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "mplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "mplLib.meta_lic", "mplLib.meta_lic", "reciprocal"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "mplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "mplLib.meta_lic", "mplLib.meta_lic", "reciprocal"},
- {"mitBin.meta_lic", "mitBin.meta_lic", "mitBin.meta_lic", "notice"},
- {"mitBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice|restricted"},
+ {"apacheContainer.meta_lic", "apacheBin.meta_lic", "notice|restricted"},
+ {"apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheContainer.meta_lic", "mitBin.meta_lic", "notice"},
+ {"apacheContainer.meta_lic", "mitLib.meta_lic", "notice"},
+ {"apacheContainer.meta_lic", "mplLib.meta_lic", "reciprocal|restricted"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice|restricted"},
+ {"apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "mplLib.meta_lic", "reciprocal|restricted"},
+ {"mitBin.meta_lic", "mitBin.meta_lic", "notice"},
+ {"mitBin.meta_lic", "mitLib.meta_lic", "notice"},
},
},
{
@@ -122,12 +115,11 @@
{"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice|restricted"},
+ {"apacheContainer.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
},
},
{
@@ -138,8 +130,8 @@
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "restricted"},
},
},
{
@@ -150,11 +142,9 @@
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice|restricted"},
+ {"apacheBin.meta_lic", "mitLib.meta_lic", "restricted"},
+ {"mitLib.meta_lic", "mitLib.meta_lic", "notice|restricted"},
},
},
{
@@ -168,14 +158,11 @@
{"mitBin.meta_lic", "mitLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "mitBin.meta_lic", "mitBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"mitBin.meta_lic", "mitBin.meta_lic", "mitBin.meta_lic", "notice"},
+ {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice|restricted"},
+ {"apacheContainer.meta_lic", "apacheBin.meta_lic", "notice|restricted"},
+ {"apacheContainer.meta_lic", "mitBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice|restricted"},
+ {"mitBin.meta_lic", "mitBin.meta_lic", "notice"},
},
},
{
@@ -186,10 +173,9 @@
{"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice|restricted"},
+ {"apacheContainer.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
},
},
{
@@ -200,12 +186,11 @@
{"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice|restricted"},
+ {"apacheContainer.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
},
},
{
@@ -216,11 +201,9 @@
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice|restricted_if_statically_linked"},
+ {"apacheBin.meta_lic", "lgplLib.meta_lic", "restricted_if_statically_linked"},
+ {"apacheBin.meta_lic", "mitLib.meta_lic", "notice|restricted_if_statically_linked"},
},
},
{
@@ -231,8 +214,8 @@
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "mitLib.meta_lic", "notice"},
},
},
{
@@ -243,9 +226,9 @@
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"lgplBin.meta_lic", "lgplBin.meta_lic", "lgplBin.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "mitLib.meta_lic", "notice"},
+ {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -257,18 +240,13 @@
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "mitLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice|restricted_if_statically_linked"},
+ {"apacheContainer.meta_lic", "apacheBin.meta_lic", "notice|restricted_if_statically_linked"},
+ {"apacheContainer.meta_lic", "lgplLib.meta_lic", "restricted_if_statically_linked"},
+ {"apacheContainer.meta_lic", "mitLib.meta_lic", "notice|restricted_if_statically_linked"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice|restricted_if_statically_linked"},
+ {"apacheBin.meta_lic", "lgplLib.meta_lic", "restricted_if_statically_linked"},
+ {"apacheBin.meta_lic", "mitLib.meta_lic", "notice|restricted_if_statically_linked"},
},
},
{
@@ -279,12 +257,11 @@
{"apacheContainer.meta_lic", "lgplLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice|restricted_if_statically_linked"},
+ {"apacheContainer.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheContainer.meta_lic", "lgplLib.meta_lic", "restricted_if_statically_linked"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"lgplLib.meta_lic", "lgplLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -295,8 +272,8 @@
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "mitLib.meta_lic", "notice"},
},
},
{
@@ -307,9 +284,9 @@
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "mitLib.meta_lic", "notice"},
+ {"lgplLib.meta_lic", "lgplLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -320,9 +297,9 @@
{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
+ {"apacheContainer.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
},
},
{
@@ -333,10 +310,10 @@
{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
+ {"apacheContainer.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"lgplLib.meta_lic", "lgplLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -347,9 +324,9 @@
{"apacheContainer.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
+ {"apacheContainer.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
},
},
{
@@ -360,10 +337,10 @@
{"apacheContainer.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
+ {"apacheContainer.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"lgplLib.meta_lic", "lgplLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -374,9 +351,9 @@
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
+ {"apacheBin.meta_lic", "mitLib.meta_lic", "notice"},
},
},
{
@@ -387,9 +364,9 @@
{"dependentModule.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"dependentModule.meta_lic", "dependentModule.meta_lic", "dependentModule.meta_lic", "notice"},
- {"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
- {"dependentModule.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ {"dependentModule.meta_lic", "dependentModule.meta_lic", "notice"},
+ {"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
+ {"dependentModule.meta_lic", "mitLib.meta_lic", "notice"},
},
},
{
@@ -400,8 +377,8 @@
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "mitLib.meta_lic", "notice"},
},
},
{
@@ -412,9 +389,9 @@
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "mitLib.meta_lic", "notice"},
+ {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
},
},
{
@@ -425,8 +402,8 @@
{"dependentModule.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"dependentModule.meta_lic", "dependentModule.meta_lic", "dependentModule.meta_lic", "notice"},
- {"dependentModule.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ {"dependentModule.meta_lic", "dependentModule.meta_lic", "notice"},
+ {"dependentModule.meta_lic", "mitLib.meta_lic", "notice"},
},
},
{
@@ -437,9 +414,9 @@
{"dependentModule.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"dependentModule.meta_lic", "dependentModule.meta_lic", "dependentModule.meta_lic", "notice"},
- {"dependentModule.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
+ {"dependentModule.meta_lic", "dependentModule.meta_lic", "notice"},
+ {"dependentModule.meta_lic", "mitLib.meta_lic", "notice"},
+ {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
},
},
}
diff --git a/tools/compliance/policy_resolveprivacy_test.go b/tools/compliance/policy_resolveprivacy_test.go
index e8c953a..d4d1967 100644
--- a/tools/compliance/policy_resolveprivacy_test.go
+++ b/tools/compliance/policy_resolveprivacy_test.go
@@ -57,7 +57,7 @@
{"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"proprietary.meta_lic", "proprietary.meta_lic", "proprietary.meta_lic", "proprietary"},
+ {"proprietary.meta_lic", "proprietary.meta_lic", "proprietary"},
},
},
{
@@ -67,7 +67,7 @@
{"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"gplBin.meta_lic", "proprietary.meta_lic", "proprietary.meta_lic", "proprietary"},
+ {"gplBin.meta_lic", "proprietary.meta_lic", "proprietary"},
},
},
}
diff --git a/tools/compliance/policy_resolveshare_test.go b/tools/compliance/policy_resolveshare_test.go
index d49dfa8..4abd960 100644
--- a/tools/compliance/policy_resolveshare_test.go
+++ b/tools/compliance/policy_resolveshare_test.go
@@ -73,8 +73,8 @@
{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"lgplBin.meta_lic", "lgplBin.meta_lic", "lgplBin.meta_lic", "restricted"},
- {"lgplBin.meta_lic", "apacheLib.meta_lic", "lgplBin.meta_lic", "restricted"},
+ {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"},
+ {"lgplBin.meta_lic", "apacheLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -84,7 +84,7 @@
{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"lgplBin.meta_lic", "lgplBin.meta_lic", "lgplBin.meta_lic", "restricted"},
+ {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -94,7 +94,7 @@
{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"lgplBin.meta_lic", "lgplBin.meta_lic", "lgplBin.meta_lic", "restricted"},
+ {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -104,8 +104,8 @@
{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"gplBin.meta_lic", "gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
- {"gplBin.meta_lic", "apacheLib.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "apacheLib.meta_lic", "restricted"},
},
},
{
@@ -115,9 +115,9 @@
{"gplContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"gplContainer.meta_lic", "gplContainer.meta_lic", "gplContainer.meta_lic", "restricted"},
- {"gplContainer.meta_lic", "apacheLib.meta_lic", "gplContainer.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "gplContainer.meta_lic", "restricted"},
+ {"gplContainer.meta_lic", "gplContainer.meta_lic", "restricted"},
+ {"gplContainer.meta_lic", "apacheLib.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "apacheLib.meta_lic", "restricted"},
},
},
{
@@ -128,9 +128,9 @@
{"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "restricted"},
+ {"apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
},
},
{
@@ -141,9 +141,9 @@
{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "apacheLib.meta_lic", "restricted"},
},
},
{
@@ -153,7 +153,7 @@
{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"gplBin.meta_lic", "gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
},
},
{
@@ -163,9 +163,9 @@
{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"gplBin.meta_lic", "gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
- {"gplBin.meta_lic", "apacheLib.meta_lic", "gplBin.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "apacheLib.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "apacheLib.meta_lic", "restricted"},
},
},
{
@@ -207,8 +207,8 @@
{"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"proprietary.meta_lic", "proprietary.meta_lic", "gplLib.meta_lic", "restricted"},
- {"proprietary.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"proprietary.meta_lic", "proprietary.meta_lic", "restricted"},
+ {"proprietary.meta_lic", "gplLib.meta_lic", "restricted"},
},
},
{
@@ -218,8 +218,8 @@
{"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"gplBin.meta_lic", "gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
- {"gplBin.meta_lic", "proprietary.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "proprietary.meta_lic", "restricted"},
},
},
{
@@ -245,7 +245,7 @@
{"mitBin.meta_lic", "mplLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"mitBin.meta_lic", "mplLib.meta_lic", "mplLib.meta_lic", "reciprocal"},
+ {"mitBin.meta_lic", "mplLib.meta_lic", "reciprocal"},
},
},
{
@@ -255,7 +255,7 @@
{"mplBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"mplBin.meta_lic", "mplBin.meta_lic", "mplBin.meta_lic", "reciprocal"},
+ {"mplBin.meta_lic", "mplBin.meta_lic", "reciprocal"},
},
},
}
diff --git a/tools/compliance/policy_shipped.go b/tools/compliance/policy_shipped.go
index 75c8399..b21a95a 100644
--- a/tools/compliance/policy_shipped.go
+++ b/tools/compliance/policy_shipped.go
@@ -16,15 +16,15 @@
// ShippedNodes returns the set of nodes in a license graph where the target or
// a derivative work gets distributed. (caches result)
-func ShippedNodes(lg *LicenseGraph) *TargetNodeSet {
+func ShippedNodes(lg *LicenseGraph) TargetNodeSet {
lg.mu.Lock()
shipped := lg.shippedNodes
lg.mu.Unlock()
if shipped != nil {
- return shipped
+ return *shipped
}
- tset := make(map[*TargetNode]struct{})
+ tset := make(TargetNodeSet)
WalkTopDown(NoEdgeContext{}, lg, func(lg *LicenseGraph, tn *TargetNode, path TargetEdgePath) bool {
if _, alreadyWalked := tset[tn]; alreadyWalked {
@@ -39,7 +39,7 @@
return true
})
- shipped = &TargetNodeSet{tset}
+ shipped = &tset
lg.mu.Lock()
if lg.shippedNodes == nil {
@@ -50,5 +50,5 @@
}
lg.mu.Unlock()
- return shipped
+ return *shipped
}
diff --git a/tools/compliance/policy_walk.go b/tools/compliance/policy_walk.go
index beb6d53..e6b94ab 100644
--- a/tools/compliance/policy_walk.go
+++ b/tools/compliance/policy_walk.go
@@ -247,40 +247,16 @@
// WalkActionsForCondition performs a top-down walk of the LicenseGraph
// resolving all distributed works for `conditions`.
func WalkActionsForCondition(lg *LicenseGraph, conditions LicenseConditionSet) ActionSet {
- shipped := ShippedNodes(lg)
-
- // cmap identifies previously walked target/condition pairs.
- cmap := make(map[resolutionKey]struct{})
-
// amap maps 'actsOn' targets to the applicable conditions
//
// amap is the resulting ActionSet
amap := make(ActionSet)
- WalkTopDown(ApplicableConditionsContext{conditions}, lg, func(lg *LicenseGraph, tn *TargetNode, path TargetEdgePath) bool {
- universe := conditions
- if len(path) > 0 {
- universe = path[len(path)-1].ctx.(LicenseConditionSet)
+
+ for tn := range ShippedNodes(lg) {
+ if cs := conditions.Intersection(tn.resolution); !cs.IsEmpty() {
+ amap[tn] = cs
}
- if universe.IsEmpty() {
- return false
- }
- key := resolutionKey{tn, universe}
- if _, ok := cmap[key]; ok {
- return false
- }
- if !shipped.Contains(tn) {
- return false
- }
- cs := universe.Intersection(tn.resolution)
- if !cs.IsEmpty() {
- if _, ok := amap[tn]; ok {
- amap[tn] = cs
- } else {
- amap[tn] = amap[tn].Union(cs)
- }
- }
- return true
- })
+ }
return amap
}
diff --git a/tools/compliance/policy_walk_test.go b/tools/compliance/policy_walk_test.go
index 0bc37f8..53af3be 100644
--- a/tools/compliance/policy_walk_test.go
+++ b/tools/compliance/policy_walk_test.go
@@ -48,8 +48,8 @@
{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheLib.meta_lic", "notice"},
},
},
{
@@ -60,8 +60,8 @@
{"mitBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"mitBin.meta_lic", "mitBin.meta_lic", "mitBin.meta_lic", "notice"},
- {"mitBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ {"mitBin.meta_lic", "mitBin.meta_lic", "notice"},
+ {"mitBin.meta_lic", "mitLib.meta_lic", "notice"},
},
},
{
@@ -72,9 +72,8 @@
{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice|restricted_if_statically_linked"},
+ {"apacheBin.meta_lic", "lgplLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -85,7 +84,7 @@
{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
},
},
{
@@ -96,7 +95,7 @@
{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
},
},
{
@@ -116,8 +115,8 @@
{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
},
},
{
@@ -137,7 +136,7 @@
{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"dependentModule.meta_lic", "dependentModule.meta_lic", "dependentModule.meta_lic", "notice"},
+ {"dependentModule.meta_lic", "dependentModule.meta_lic", "notice"},
},
},
{
@@ -157,9 +156,8 @@
{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"lgplBin.meta_lic", "lgplBin.meta_lic", "lgplBin.meta_lic", "restricted"},
- {"lgplBin.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"lgplBin.meta_lic", "apacheLib.meta_lic", "lgplBin.meta_lic", "restricted"},
+ {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"},
+ {"lgplBin.meta_lic", "apacheLib.meta_lic", "notice|restricted_if_statically_linked"},
},
},
{
@@ -170,8 +168,8 @@
{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"lgplBin.meta_lic", "lgplBin.meta_lic", "lgplBin.meta_lic", "restricted"},
- {"lgplBin.meta_lic", "apacheLib.meta_lic", "lgplBin.meta_lic", "restricted"},
+ {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"},
+ {"lgplBin.meta_lic", "apacheLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -182,7 +180,7 @@
{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"lgplBin.meta_lic", "lgplBin.meta_lic", "lgplBin.meta_lic", "restricted"},
+ {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -193,7 +191,7 @@
{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"lgplBin.meta_lic", "lgplBin.meta_lic", "lgplBin.meta_lic", "restricted"},
+ {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -204,9 +202,8 @@
{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"gplBin.meta_lic", "gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
- {"gplBin.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"gplBin.meta_lic", "apacheLib.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "apacheLib.meta_lic", "notice|restricted"},
},
},
{
@@ -217,8 +214,8 @@
{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"gplBin.meta_lic", "gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
- {"gplBin.meta_lic", "apacheLib.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "apacheLib.meta_lic", "restricted"},
},
},
{
@@ -229,11 +226,9 @@
{"gplContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"gplContainer.meta_lic", "gplContainer.meta_lic", "gplContainer.meta_lic", "restricted"},
- {"gplContainer.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"gplContainer.meta_lic", "apacheLib.meta_lic", "gplContainer.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "gplContainer.meta_lic", "restricted"},
+ {"gplContainer.meta_lic", "gplContainer.meta_lic", "restricted"},
+ {"gplContainer.meta_lic", "apacheLib.meta_lic", "notice|restricted"},
+ {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice|restricted"},
},
},
{
@@ -244,9 +239,9 @@
{"gplContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"gplContainer.meta_lic", "gplContainer.meta_lic", "gplContainer.meta_lic", "restricted"},
- {"gplContainer.meta_lic", "apacheLib.meta_lic", "gplContainer.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "gplContainer.meta_lic", "restricted"},
+ {"gplContainer.meta_lic", "gplContainer.meta_lic", "restricted"},
+ {"gplContainer.meta_lic", "apacheLib.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "apacheLib.meta_lic", "restricted"},
},
},
{
@@ -258,12 +253,11 @@
{"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice|restricted"},
+ {"apacheContainer.meta_lic", "apacheLib.meta_lic", "notice"},
+ {"apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
},
},
{
@@ -275,9 +269,9 @@
{"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "restricted"},
+ {"apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
},
},
{
@@ -289,11 +283,9 @@
{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice|restricted"},
+ {"apacheBin.meta_lic", "apacheLib.meta_lic", "notice|restricted"},
+ {"apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
},
},
{
@@ -305,9 +297,9 @@
{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "apacheLib.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
},
},
{
@@ -318,7 +310,7 @@
{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"gplBin.meta_lic", "gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
},
},
{
@@ -329,7 +321,7 @@
{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"gplBin.meta_lic", "gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
},
},
{
@@ -340,9 +332,9 @@
{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"gplBin.meta_lic", "gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
- {"gplBin.meta_lic", "apacheLib.meta_lic", "gplBin.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "apacheLib.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "apacheLib.meta_lic", "restricted"},
},
},
{
@@ -353,7 +345,7 @@
{"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
+ {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
},
},
{
@@ -382,8 +374,8 @@
{"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
- {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
+ {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", "notice"},
},
},
{
@@ -403,7 +395,7 @@
{"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", []string{"dynamic"}},
},
expectedResolutions: []res{
- {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
+ {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
},
},
{
@@ -432,9 +424,8 @@
{"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"proprietary.meta_lic", "proprietary.meta_lic", "proprietary.meta_lic", "proprietary"},
- {"proprietary.meta_lic", "proprietary.meta_lic", "gplLib.meta_lic", "restricted"},
- {"proprietary.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"proprietary.meta_lic", "proprietary.meta_lic", "restricted|proprietary"},
+ {"proprietary.meta_lic", "gplLib.meta_lic", "restricted"},
},
},
{
@@ -445,8 +436,8 @@
{"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"proprietary.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"proprietary.meta_lic", "proprietary.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"proprietary.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"proprietary.meta_lic", "proprietary.meta_lic", "restricted"},
},
},
{
@@ -457,7 +448,7 @@
{"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"proprietary.meta_lic", "proprietary.meta_lic", "proprietary.meta_lic", "proprietary"},
+ {"proprietary.meta_lic", "proprietary.meta_lic", "proprietary"},
},
},
{
@@ -468,9 +459,8 @@
{"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"gplBin.meta_lic", "gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
- {"gplBin.meta_lic", "proprietary.meta_lic", "proprietary.meta_lic", "proprietary"},
- {"gplBin.meta_lic", "proprietary.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "proprietary.meta_lic", "restricted|proprietary"},
},
},
{
@@ -481,8 +471,8 @@
{"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"gplBin.meta_lic", "gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
- {"gplBin.meta_lic", "proprietary.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "proprietary.meta_lic", "restricted"},
},
},
{
@@ -493,7 +483,7 @@
{"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"gplBin.meta_lic", "proprietary.meta_lic", "proprietary.meta_lic", "proprietary"},
+ {"gplBin.meta_lic", "proprietary.meta_lic", "proprietary"},
},
},
{
@@ -504,8 +494,8 @@
{"mitBin.meta_lic", "by_exception.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"mitBin.meta_lic", "mitBin.meta_lic", "mitBin.meta_lic", "notice"},
- {"mitBin.meta_lic", "by_exception.meta_lic", "by_exception.meta_lic", "by_exception_only"},
+ {"mitBin.meta_lic", "mitBin.meta_lic", "notice"},
+ {"mitBin.meta_lic", "by_exception.meta_lic", "by_exception_only"},
},
},
{
@@ -525,7 +515,7 @@
{"mitBin.meta_lic", "by_exception.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"mitBin.meta_lic", "by_exception.meta_lic", "by_exception.meta_lic", "by_exception_only"},
+ {"mitBin.meta_lic", "by_exception.meta_lic", "by_exception_only"},
},
},
{
@@ -536,8 +526,8 @@
{"by_exception.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"by_exception.meta_lic", "by_exception.meta_lic", "by_exception.meta_lic", "by_exception_only"},
- {"by_exception.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ {"by_exception.meta_lic", "by_exception.meta_lic", "by_exception_only"},
+ {"by_exception.meta_lic", "mitLib.meta_lic", "notice"},
},
},
{
@@ -557,7 +547,7 @@
{"by_exception.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"by_exception.meta_lic", "by_exception.meta_lic", "by_exception.meta_lic", "by_exception_only"},
+ {"by_exception.meta_lic", "by_exception.meta_lic", "by_exception_only"},
},
},
{
@@ -568,8 +558,8 @@
{"mitBin.meta_lic", "mplLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"mitBin.meta_lic", "mitBin.meta_lic", "mitBin.meta_lic", "notice"},
- {"mitBin.meta_lic", "mplLib.meta_lic", "mplLib.meta_lic", "reciprocal"},
+ {"mitBin.meta_lic", "mitBin.meta_lic", "notice"},
+ {"mitBin.meta_lic", "mplLib.meta_lic", "reciprocal"},
},
},
{
@@ -580,7 +570,7 @@
{"mitBin.meta_lic", "mplLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"mitBin.meta_lic", "mplLib.meta_lic", "mplLib.meta_lic", "reciprocal"},
+ {"mitBin.meta_lic", "mplLib.meta_lic", "reciprocal"},
},
},
{
@@ -591,8 +581,8 @@
{"mplBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"mplBin.meta_lic", "mplBin.meta_lic", "mplBin.meta_lic", "reciprocal"},
- {"mplBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ {"mplBin.meta_lic", "mplBin.meta_lic", "reciprocal"},
+ {"mplBin.meta_lic", "mitLib.meta_lic", "notice"},
},
},
{
@@ -603,7 +593,7 @@
{"mplBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedResolutions: []res{
- {"mplBin.meta_lic", "mplBin.meta_lic", "mplBin.meta_lic", "reciprocal"},
+ {"mplBin.meta_lic", "mplBin.meta_lic", "reciprocal"},
},
},
}
@@ -639,8 +629,8 @@
{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "notice"},
},
},
{
@@ -651,8 +641,8 @@
{"mitBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"mitBin.meta_lic", "mitBin.meta_lic", "notice"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ {"mitBin.meta_lic", "notice"},
+ {"mitLib.meta_lic", "notice"},
},
},
{
@@ -663,9 +653,8 @@
{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "notice"},
+ {"lgplLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -676,7 +665,7 @@
{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
},
expectedActions: []act{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "notice"},
},
},
{
@@ -687,7 +676,7 @@
{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
},
expectedActions: []act{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "notice"},
},
},
{
@@ -707,8 +696,8 @@
{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
+ {"apacheBin.meta_lic", "notice"},
+ {"gplWithClasspathException.meta_lic", "permissive"},
},
},
{
@@ -728,7 +717,7 @@
{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
},
expectedActions: []act{
- {"dependentModule.meta_lic", "dependentModule.meta_lic", "notice"},
+ {"dependentModule.meta_lic", "notice"},
},
},
{
@@ -748,9 +737,8 @@
{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"apacheLib.meta_lic", "lgplBin.meta_lic", "restricted"},
+ {"lgplBin.meta_lic", "restricted_if_statically_linked"},
+ {"apacheLib.meta_lic", "notice|restricted_if_statically_linked"},
},
},
{
@@ -761,8 +749,8 @@
{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "lgplBin.meta_lic", "restricted"},
+ {"lgplBin.meta_lic", "restricted_if_statically_linked"},
+ {"apacheLib.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -773,7 +761,7 @@
{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
expectedActions: []act{
- {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted"},
+ {"lgplBin.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -784,7 +772,7 @@
{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
expectedActions: []act{
- {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted"},
+ {"lgplBin.meta_lic", "restricted_if_statically_linked"},
},
},
{
@@ -795,9 +783,8 @@
{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"apacheLib.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "notice|restricted"},
},
},
{
@@ -808,8 +795,8 @@
{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "restricted"},
},
},
{
@@ -820,11 +807,8 @@
{"gplContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"gplContainer.meta_lic", "gplContainer.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"apacheLib.meta_lic", "gplContainer.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"apacheLib.meta_lic", "gplContainer.meta_lic", "restricted"},
+ {"gplContainer.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "notice|restricted"},
},
},
{
@@ -835,9 +819,8 @@
{"gplContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"gplContainer.meta_lic", "gplContainer.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "gplContainer.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "gplContainer.meta_lic", "restricted"},
+ {"gplContainer.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "restricted"},
},
},
{
@@ -849,11 +832,9 @@
{"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheContainer.meta_lic", "notice|restricted"},
+ {"apacheLib.meta_lic", "notice"},
+ {"gplLib.meta_lic", "restricted"},
},
},
{
@@ -865,8 +846,8 @@
{"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheContainer.meta_lic", "restricted"},
+ {"gplLib.meta_lic", "restricted"},
},
},
{
@@ -878,11 +859,9 @@
{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"apacheLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "notice|restricted"},
+ {"apacheLib.meta_lic", "notice|restricted"},
+ {"gplLib.meta_lic", "restricted"},
},
},
{
@@ -894,9 +873,9 @@
{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "restricted"},
+ {"gplLib.meta_lic", "restricted"},
},
},
{
@@ -907,7 +886,7 @@
{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
expectedActions: []act{
- {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "restricted"},
},
},
{
@@ -918,7 +897,7 @@
{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
expectedActions: []act{
- {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "restricted"},
},
},
{
@@ -929,8 +908,8 @@
{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
expectedActions: []act{
- {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
- {"apacheLib.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "restricted"},
},
},
{
@@ -941,7 +920,7 @@
{"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"dynamic"}},
},
expectedActions: []act{
- {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
+ {"gplWithClasspathException.meta_lic", "permissive"},
},
},
{
@@ -970,8 +949,8 @@
{"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"gplWithClasspathException.meta_lic", "permissive"},
+ {"apacheBin.meta_lic", "notice"},
},
},
{
@@ -991,7 +970,7 @@
{"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", []string{"dynamic"}},
},
expectedActions: []act{
- {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"},
+ {"gplWithClasspathException.meta_lic", "permissive"},
},
},
{
@@ -1020,9 +999,8 @@
{"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"proprietary.meta_lic", "proprietary.meta_lic", "proprietary"},
- {"proprietary.meta_lic", "gplLib.meta_lic", "restricted"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"proprietary.meta_lic", "restricted|proprietary"},
+ {"gplLib.meta_lic", "restricted"},
},
},
{
@@ -1033,8 +1011,8 @@
{"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"proprietary.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"gplLib.meta_lic", "restricted"},
+ {"proprietary.meta_lic", "restricted"},
},
},
{
@@ -1045,7 +1023,7 @@
{"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"proprietary.meta_lic", "proprietary.meta_lic", "proprietary"},
+ {"proprietary.meta_lic", "proprietary"},
},
},
{
@@ -1056,9 +1034,8 @@
{"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
- {"proprietary.meta_lic", "proprietary.meta_lic", "proprietary"},
- {"proprietary.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "restricted"},
+ {"proprietary.meta_lic", "restricted|proprietary"},
},
},
{
@@ -1069,8 +1046,8 @@
{"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
- {"proprietary.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"gplBin.meta_lic", "restricted"},
+ {"proprietary.meta_lic", "restricted"},
},
},
{
@@ -1081,7 +1058,7 @@
{"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"proprietary.meta_lic", "proprietary.meta_lic", "proprietary"},
+ {"proprietary.meta_lic", "proprietary"},
},
},
{
@@ -1092,8 +1069,8 @@
{"mitBin.meta_lic", "by_exception.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"mitBin.meta_lic", "mitBin.meta_lic", "notice"},
- {"by_exception.meta_lic", "by_exception.meta_lic", "by_exception_only"},
+ {"mitBin.meta_lic", "notice"},
+ {"by_exception.meta_lic", "by_exception_only"},
},
},
{
@@ -1113,7 +1090,7 @@
{"mitBin.meta_lic", "by_exception.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"by_exception.meta_lic", "by_exception.meta_lic", "by_exception_only"},
+ {"by_exception.meta_lic", "by_exception_only"},
},
},
{
@@ -1124,8 +1101,8 @@
{"by_exception.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"by_exception.meta_lic", "by_exception.meta_lic", "by_exception_only"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ {"by_exception.meta_lic", "by_exception_only"},
+ {"mitLib.meta_lic", "notice"},
},
},
{
@@ -1145,7 +1122,7 @@
{"by_exception.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"by_exception.meta_lic", "by_exception.meta_lic", "by_exception_only"},
+ {"by_exception.meta_lic", "by_exception_only"},
},
},
{
@@ -1156,8 +1133,8 @@
{"mitBin.meta_lic", "mplLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"mitBin.meta_lic", "mitBin.meta_lic", "notice"},
- {"mplLib.meta_lic", "mplLib.meta_lic", "reciprocal"},
+ {"mitBin.meta_lic", "notice"},
+ {"mplLib.meta_lic", "reciprocal"},
},
},
{
@@ -1168,7 +1145,7 @@
{"mitBin.meta_lic", "mplLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"mplLib.meta_lic", "mplLib.meta_lic", "reciprocal"},
+ {"mplLib.meta_lic", "reciprocal"},
},
},
{
@@ -1179,8 +1156,8 @@
{"mplBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"mplBin.meta_lic", "mplBin.meta_lic", "reciprocal"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ {"mplBin.meta_lic", "reciprocal"},
+ {"mitLib.meta_lic", "notice"},
},
},
{
@@ -1191,7 +1168,25 @@
{"mplBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
expectedActions: []act{
- {"mplBin.meta_lic", "mplBin.meta_lic", "reciprocal"},
+ {"mplBin.meta_lic", "reciprocal"},
+ },
+ },
+ {
+ name: "regress-walk-twice",
+ condition: ImpliesShared,
+ roots: []string{"mitBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic"},
+ edges: []annotated{
+ {"apacheBin.meta_lic", "mitLib.meta_lic", []string{"dynamic"}},
+ {"apacheBin.meta_lic", "gplLib.meta_lic", []string{"dynamic"}},
+ {"mitBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
+ {"mitBin.meta_lic", "lgplLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"apacheBin.meta_lic", "restricted"},
+ {"mitLib.meta_lic", "restricted|restricted_if_statically_linked"},
+ {"gplLib.meta_lic", "restricted"},
+ {"mitBin.meta_lic", "restricted_if_statically_linked"},
+ {"lgplLib.meta_lic", "restricted_if_statically_linked"},
},
},
}
diff --git a/tools/compliance/projectmetadata/projectmetadata.go b/tools/compliance/projectmetadata/projectmetadata.go
index b31413d..b137a12 100644
--- a/tools/compliance/projectmetadata/projectmetadata.go
+++ b/tools/compliance/projectmetadata/projectmetadata.go
@@ -40,11 +40,44 @@
project string
}
+// ProjectUrlMap maps url type name to url value
+type ProjectUrlMap map[string]string
+
+// DownloadUrl returns the address of a download location
+func (m ProjectUrlMap) DownloadUrl() string {
+ for _, urlType := range []string{"GIT", "SVN", "HG", "DARCS"} {
+ if url, ok := m[urlType]; ok {
+ return url
+ }
+ }
+ return ""
+}
+
// String returns a string representation of the metadata for error messages.
func (pm *ProjectMetadata) String() string {
return fmt.Sprintf("project: %q\n%s", pm.project, pm.proto.String())
}
+// Project returns the path to the directory containing the METADATA file
+func (pm *ProjectMetadata) Project() string {
+ return pm.project
+}
+
+// ProjectName returns the name of the project.
+func (pm *ProjectMetadata) Name() string {
+ return pm.proto.GetName()
+}
+
+// ProjectVersion returns the version of the project if available.
+func (pm *ProjectMetadata) Version() string {
+ tp := pm.proto.GetThirdParty()
+ if tp != nil {
+ version := tp.GetVersion()
+ return version
+ }
+ return ""
+}
+
// VersionedName returns the name of the project including the version if any.
func (pm *ProjectMetadata) VersionedName() string {
name := pm.proto.GetName()
@@ -65,13 +98,35 @@
return pm.proto.GetDescription()
}
+// UrlsByTypeName returns a map of URLs by Type Name
+func (pm *ProjectMetadata) UrlsByTypeName() ProjectUrlMap {
+ tp := pm.proto.GetThirdParty()
+ if tp == nil {
+ return nil
+ }
+ if len(tp.Url) == 0 {
+ return nil
+ }
+ urls := make(ProjectUrlMap)
+
+ for _, url := range tp.Url {
+ uri := url.GetValue()
+ if uri == "" {
+ continue
+ }
+ urls[project_metadata_proto.URL_Type_name[int32(url.GetType())]] = uri
+ }
+ return urls
+}
+
// projectIndex describes a project to be read; after `wg.Wait()`, will contain either
// a `ProjectMetadata`, pm (can be nil even without error), or a non-nil `err`.
type projectIndex struct {
project string
- pm *ProjectMetadata
- err error
- done chan struct{}
+ path string
+ pm *ProjectMetadata
+ err error
+ done chan struct{}
}
// finish marks the task to read the `projectIndex` completed.
@@ -181,6 +236,19 @@
return result, nil
}
+// AllMetadataFiles returns the sorted list of all METADATA files read thus far.
+func (ix *Index) AllMetadataFiles() []string {
+ var files []string
+ ix.projects.Range(func(key, value any) bool {
+ pi := value.(*projectIndex)
+ if pi.path != "" {
+ files = append(files, pi.path)
+ }
+ return true
+ })
+ return files
+}
+
// readMetadataFile tries to read and parse a METADATA file at `path` for `project`.
func (ix *Index) readMetadataFile(pi *projectIndex, path string) {
f, err := ix.rootFS.Open(path)
@@ -201,9 +269,24 @@
pm := &ProjectMetadata{project: pi.project}
err = uo.Unmarshal(data, &pm.proto)
if err != nil {
- pi.err = fmt.Errorf("error in project %q metadata %q: %w", pi.project, path, err)
+ pi.err = fmt.Errorf(`error in project %q METADATA %q: %v
+
+METADATA and METADATA.android files must parse as text protobufs
+defined by
+ build/soong/compliance/project_metadata_proto/project_metadata.proto
+
+* unknown fields don't matter
+* check invalid ENUM names
+* check quoting
+* check unescaped nested quotes
+* check the comment marker for protobuf is '#' not '//'
+
+if importing a library that uses a different sort of METADATA file, add
+a METADATA.android file beside it to parse instead
+`, pi.project, path, err)
return
}
+ pi.path = path
pi.pm = pm
}
diff --git a/tools/compliance/projectmetadata/projectmetadata_test.go b/tools/compliance/projectmetadata/projectmetadata_test.go
index 1e4256f..0af0cd7 100644
--- a/tools/compliance/projectmetadata/projectmetadata_test.go
+++ b/tools/compliance/projectmetadata/projectmetadata_test.go
@@ -19,6 +19,7 @@
"strings"
"testing"
+ "android/soong/compliance/project_metadata_proto"
"android/soong/tools/compliance/testfs"
)
@@ -40,8 +41,79 @@
// NO_NAME_0_1 represents a METADATA file with a description but no name
NO_NAME_0_1 = `description: "my library" third_party { version: "0.1" }`
+
+ // URL values per type
+ GIT_URL = "http://example.github.com/my_lib"
+ SVN_URL = "http://example.svn.com/my_lib"
+ HG_URL = "http://example.hg.com/my_lib"
+ DARCS_URL = "http://example.darcs.com/my_lib"
+ PIPER_URL = "http://google3/third_party/my/package"
+ HOMEPAGE_URL = "http://example.com/homepage"
+ OTHER_URL = "http://google.com/"
+ ARCHIVE_URL = "http://ftp.example.com/"
+ LOCAL_SOURCE_URL = "https://android.googlesource.com/platform/external/apache-http/"
)
+// libWithUrl returns a METADATA file with the right download url
+func libWithUrl(urlTypes ...string) string {
+ var sb strings.Builder
+
+ fmt.Fprintln(&sb, `name: "mylib" description: "my library"
+ third_party {
+ version: "1.0"`)
+
+ for _, urltype := range urlTypes {
+ var urlValue string
+ switch urltype {
+ case "GIT":
+ urlValue = GIT_URL
+ case "SVN":
+ urlValue = SVN_URL
+ case "HG":
+ urlValue = HG_URL
+ case "DARCS":
+ urlValue = DARCS_URL
+ case "PIPER":
+ urlValue = PIPER_URL
+ case "HOMEPAGE":
+ urlValue = HOMEPAGE_URL
+ case "OTHER":
+ urlValue = OTHER_URL
+ case "ARCHIVE":
+ urlValue = ARCHIVE_URL
+ case "LOCAL_SOURCE":
+ urlValue = LOCAL_SOURCE_URL
+ default:
+ panic(fmt.Errorf("unknown url type: %q. Please update libWithUrl() in build/make/tools/compliance/projectmetadata/projectmetadata_test.go", urltype))
+ }
+ fmt.Fprintf(&sb, " url { type: %s value: %q }\n", urltype, urlValue)
+ }
+ fmt.Fprintln(&sb, `}`)
+
+ return sb.String()
+}
+
+func TestVerifyAllUrlTypes(t *testing.T) {
+ t.Run("verifyAllUrlTypes", func(t *testing.T) {
+ types := make([]string, 0, len(project_metadata_proto.URL_Type_value))
+ for t := range project_metadata_proto.URL_Type_value {
+ types = append(types, t)
+ }
+ libWithUrl(types...)
+ })
+}
+
+func TestUnknownPanics(t *testing.T) {
+ t.Run("Unknown panics", func(t *testing.T) {
+ defer func() {
+ if r := recover(); r == nil {
+ t.Errorf("unexpected success: got no error, want panic")
+ }
+ }()
+ libWithUrl("SOME WILD VALUE THAT DOES NOT EXIST")
+ })
+}
+
func TestReadMetadataForProjects(t *testing.T) {
tests := []struct {
name string
@@ -56,7 +128,13 @@
"/a/METADATA": []byte("name: \"Android\"\n"),
},
projects: []string{"/a"},
- expected: []pmeta{{project: "/a", versionedName: "Android"}},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "Android",
+ name: "Android",
+ version: "",
+ downloadUrl: "",
+ }},
},
{
name: "versioned",
@@ -64,7 +142,237 @@
"/a/METADATA": []byte(MY_LIB_1_0),
},
projects: []string{"/a"},
- expected: []pmeta{{project: "/a", versionedName: "mylib_v_1.0"}},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: "",
+ }},
+ },
+ {
+ name: "lib_with_homepage",
+ fs: &testfs.TestFS{
+ "/a/METADATA": []byte(libWithUrl("HOMEPAGE")),
+ },
+ projects: []string{"/a"},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: "",
+ }},
+ },
+ {
+ name: "lib_with_git",
+ fs: &testfs.TestFS{
+ "/a/METADATA": []byte(libWithUrl("GIT")),
+ },
+ projects: []string{"/a"},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: GIT_URL,
+ }},
+ },
+ {
+ name: "lib_with_svn",
+ fs: &testfs.TestFS{
+ "/a/METADATA": []byte(libWithUrl("SVN")),
+ },
+ projects: []string{"/a"},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: SVN_URL,
+ }},
+ },
+ {
+ name: "lib_with_hg",
+ fs: &testfs.TestFS{
+ "/a/METADATA": []byte(libWithUrl("HG")),
+ },
+ projects: []string{"/a"},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: HG_URL,
+ }},
+ },
+ {
+ name: "lib_with_darcs",
+ fs: &testfs.TestFS{
+ "/a/METADATA": []byte(libWithUrl("DARCS")),
+ },
+ projects: []string{"/a"},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: DARCS_URL,
+ }},
+ },
+ {
+ name: "lib_with_piper",
+ fs: &testfs.TestFS{
+ "/a/METADATA": []byte(libWithUrl("PIPER")),
+ },
+ projects: []string{"/a"},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: "",
+ }},
+ },
+ {
+ name: "lib_with_other",
+ fs: &testfs.TestFS{
+ "/a/METADATA": []byte(libWithUrl("OTHER")),
+ },
+ projects: []string{"/a"},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: "",
+ }},
+ },
+ {
+ name: "lib_with_local_source",
+ fs: &testfs.TestFS{
+ "/a/METADATA": []byte(libWithUrl("LOCAL_SOURCE")),
+ },
+ projects: []string{"/a"},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: "",
+ }},
+ },
+ {
+ name: "lib_with_archive",
+ fs: &testfs.TestFS{
+ "/a/METADATA": []byte(libWithUrl("ARCHIVE")),
+ },
+ projects: []string{"/a"},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: "",
+ }},
+ },
+ {
+ name: "lib_with_all_downloads",
+ fs: &testfs.TestFS{
+ "/a/METADATA": []byte(libWithUrl("DARCS", "HG", "SVN", "GIT")),
+ },
+ projects: []string{"/a"},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: GIT_URL,
+ }},
+ },
+ {
+ name: "lib_with_all_downloads_in_different_order",
+ fs: &testfs.TestFS{
+ "/a/METADATA": []byte(libWithUrl("DARCS", "GIT", "SVN", "HG")),
+ },
+ projects: []string{"/a"},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: GIT_URL,
+ }},
+ },
+ {
+ name: "lib_with_all_but_git",
+ fs: &testfs.TestFS{
+ "/a/METADATA": []byte(libWithUrl("DARCS", "HG", "SVN")),
+ },
+ projects: []string{"/a"},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: SVN_URL,
+ }},
+ },
+ {
+ name: "lib_with_all_but_git_and_svn",
+ fs: &testfs.TestFS{
+ "/a/METADATA": []byte(libWithUrl("DARCS", "HG")),
+ },
+ projects: []string{"/a"},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: HG_URL,
+ }},
+ },
+ {
+ name: "lib_with_all_nondownloads_and_git",
+ fs: &testfs.TestFS{
+ "/a/METADATA": []byte(libWithUrl("HOMEPAGE", "LOCAL_SOURCE", "PIPER", "ARCHIVE", "GIT")),
+ },
+ projects: []string{"/a"},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: GIT_URL,
+ }},
+ },
+ {
+ name: "lib_with_all_nondownloads",
+ fs: &testfs.TestFS{
+ "/a/METADATA": []byte(libWithUrl("HOMEPAGE", "LOCAL_SOURCE", "PIPER", "ARCHIVE")),
+ },
+ projects: []string{"/a"},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: "",
+ }},
+ },
+ {
+ name: "lib_with_all_nondownloads",
+ fs: &testfs.TestFS{
+ "/a/METADATA": []byte(libWithUrl()),
+ },
+ projects: []string{"/a"},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: "",
+ }},
},
{
name: "versioneddesc",
@@ -72,7 +380,13 @@
"/a/METADATA": []byte(NO_NAME_0_1),
},
projects: []string{"/a"},
- expected: []pmeta{{project: "/a", versionedName: "my library"}},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "my library",
+ name: "",
+ version: "0.1",
+ downloadUrl: "",
+ }},
},
{
name: "unterminated",
@@ -91,9 +405,27 @@
},
projects: []string{"/a", "/b", "/c"},
expected: []pmeta{
- {project: "/a", versionedName: ""},
- {project: "/b", versionedName: "mylib_v_1.0"},
- {project: "/c", versionedName: "my library"},
+ {
+ project: "/a",
+ versionedName: "",
+ name: "",
+ version: "",
+ downloadUrl: "",
+ },
+ {
+ project: "/b",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: "",
+ },
+ {
+ project: "/c",
+ versionedName: "my library",
+ name: "",
+ version: "0.1",
+ downloadUrl: "",
+ },
},
},
{
@@ -104,8 +436,20 @@
},
projects: []string{"/a", "/b", "/c"},
expected: []pmeta{
- {project: "/a", versionedName: ""},
- {project: "/b", versionedName: "mylib_v_1.0"},
+ {
+ project: "/a",
+ versionedName: "",
+ name: "",
+ version: "",
+ downloadUrl: "",
+ },
+ {
+ project: "/b",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: "",
+ },
},
},
{
@@ -116,8 +460,20 @@
},
projects: []string{"/a", "/b", "/c"},
expected: []pmeta{
- {project: "/a", versionedName: ""},
- {project: "/c", versionedName: "my library"},
+ {
+ project: "/a",
+ versionedName: "",
+ name: "",
+ version: "",
+ downloadUrl: "",
+ },
+ {
+ project: "/c",
+ versionedName: "my library",
+ name: "",
+ version: "0.1",
+ downloadUrl: "",
+ },
},
},
{
@@ -128,8 +484,20 @@
},
projects: []string{"/a", "/b", "/c"},
expected: []pmeta{
- {project: "/b", versionedName: "mylib_v_1.0"},
- {project: "/c", versionedName: "my library"},
+ {
+ project: "/b",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: "",
+ },
+ {
+ project: "/c",
+ versionedName: "my library",
+ name: "",
+ version: "0.1",
+ downloadUrl: "",
+ },
},
},
{
@@ -170,7 +538,13 @@
"/a/METADATA": []byte(EMPTY),
},
projects: []string{"/a"},
- expected: []pmeta{{project: "/a", versionedName: ""}},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "",
+ name: "",
+ version: "",
+ downloadUrl: "",
+ }},
},
{
name: "emptyother",
@@ -191,7 +565,13 @@
"/a/METADATA.android": []byte(MY_LIB_1_0),
},
projects: []string{"/a"},
- expected: []pmeta{{project: "/a", versionedName: "mylib_v_1.0"}},
+ expected: []pmeta{{
+ project: "/a",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: "",
+ }},
},
{
name: "enchilada",
@@ -203,9 +583,27 @@
},
projects: []string{"/a", "/b", "/c"},
expected: []pmeta{
- {project: "/a", versionedName: ""},
- {project: "/b", versionedName: "mylib_v_1.0"},
- {project: "/c", versionedName: "my library"},
+ {
+ project: "/a",
+ versionedName: "",
+ name: "",
+ version: "",
+ downloadUrl: "",
+ },
+ {
+ project: "/b",
+ versionedName: "mylib_v_1.0",
+ name: "mylib",
+ version: "1.0",
+ downloadUrl: "",
+ },
+ {
+ project: "/c",
+ versionedName: "my library",
+ name: "",
+ version: "0.1",
+ downloadUrl: "",
+ },
},
},
}
@@ -255,10 +653,13 @@
type pmeta struct {
project string
versionedName string
+ name string
+ version string
+ downloadUrl string
}
func (pm pmeta) String() string {
- return fmt.Sprintf("project: %q versionedName: %q\n", pm.project, pm.versionedName)
+ return fmt.Sprintf("project: %q versionedName: %q name: %q version: %q downloadUrl: %q\n", pm.project, pm.versionedName, pm.name, pm.version, pm.downloadUrl)
}
func (pm pmeta) equals(other *ProjectMetadata) bool {
@@ -268,6 +669,15 @@
if pm.versionedName != other.VersionedName() {
return false
}
+ if pm.name != other.Name() {
+ return false
+ }
+ if pm.version != other.Version() {
+ return false
+ }
+ if pm.downloadUrl != other.UrlsByTypeName().DownloadUrl() {
+ return false
+ }
return true
}
@@ -283,6 +693,15 @@
if pm.versionedName != other.VersionedName() {
fmt.Fprintf(&sb, " versionedName: %q", other.VersionedName())
}
+ if pm.name != other.Name() {
+ fmt.Fprintf(&sb, " name: %q", other.Name())
+ }
+ if pm.version != other.Version() {
+ fmt.Fprintf(&sb, " version: %q", other.Version())
+ }
+ if pm.downloadUrl != other.UrlsByTypeName().DownloadUrl() {
+ fmt.Fprintf(&sb, " downloadUrl: %q", other.UrlsByTypeName().DownloadUrl())
+ }
fmt.Fprintf(&sb, ", want")
if pm.project != other.project {
fmt.Fprintf(&sb, " project: %q", pm.project)
@@ -290,5 +709,14 @@
if pm.versionedName != other.VersionedName() {
fmt.Fprintf(&sb, " versionedName: %q", pm.versionedName)
}
+ if pm.name != other.Name() {
+ fmt.Fprintf(&sb, " name: %q", pm.name)
+ }
+ if pm.version != other.Version() {
+ fmt.Fprintf(&sb, " version: %q", pm.version)
+ }
+ if pm.downloadUrl != other.UrlsByTypeName().DownloadUrl() {
+ fmt.Fprintf(&sb, " downloadUrl: %q", pm.downloadUrl)
+ }
return sb.String()
}
diff --git a/tools/compliance/readgraph.go b/tools/compliance/readgraph.go
index bf364e6..a413ebe 100644
--- a/tools/compliance/readgraph.go
+++ b/tools/compliance/readgraph.go
@@ -175,7 +175,7 @@
}
lg.edges = make(TargetEdgeList, 0, esize)
for _, tn := range lg.targets {
- tn.licenseConditions = LicenseConditionSetFromNames(tn, tn.proto.LicenseConditions...)
+ tn.licenseConditions = LicenseConditionSetFromNames(tn.proto.LicenseConditions...)
err = addDependencies(lg, tn)
if err != nil {
return nil, fmt.Errorf("error indexing dependencies for %q: %w", tn.name, err)
diff --git a/tools/compliance/resolutionset_test.go b/tools/compliance/resolutionset_test.go
index 89cdfeb..efdff82 100644
--- a/tools/compliance/resolutionset_test.go
+++ b/tools/compliance/resolutionset_test.go
@@ -27,48 +27,44 @@
// binc represents a compiler or other toolchain binary used for
// building the other binaries.
bottomUp = []res{
- {"image", "image", "image", "notice"},
- {"image", "image", "bin2", "restricted"},
- {"image", "bin1", "bin1", "reciprocal"},
- {"image", "bin2", "bin2", "restricted"},
- {"image", "lib1", "lib1", "notice"},
- {"image", "lib2", "lib2", "notice"},
- {"binc", "binc", "binc", "proprietary"},
- {"bin1", "bin1", "bin1", "reciprocal"},
- {"bin1", "lib1", "lib1", "notice"},
- {"bin2", "bin2", "bin2", "restricted"},
- {"bin2", "lib2", "lib2", "notice"},
- {"lib1", "lib1", "lib1", "notice"},
- {"lib2", "lib2", "lib2", "notice"},
+ {"image", "image", "notice|restricted"},
+ {"image", "bin1", "reciprocal"},
+ {"image", "bin2", "restricted"},
+ {"image", "lib1", "notice"},
+ {"image", "lib2", "notice"},
+ {"binc", "binc", "proprietary"},
+ {"bin1", "bin1", "reciprocal"},
+ {"bin1", "lib1", "notice"},
+ {"bin2", "bin2", "restricted"},
+ {"bin2", "lib2", "notice"},
+ {"lib1", "lib1", "notice"},
+ {"lib2", "lib2", "notice"},
}
// notice describes bottomUp after a top-down notice resolve.
notice = []res{
- {"image", "image", "image", "notice"},
- {"image", "image", "bin2", "restricted"},
- {"image", "bin1", "bin1", "reciprocal"},
- {"image", "bin2", "bin2", "restricted"},
- {"image", "lib1", "lib1", "notice"},
- {"image", "lib2", "bin2", "restricted"},
- {"image", "lib2", "lib2", "notice"},
- {"bin1", "bin1", "bin1", "reciprocal"},
- {"bin1", "lib1", "lib1", "notice"},
- {"bin2", "bin2", "bin2", "restricted"},
- {"bin2", "lib2", "bin2", "restricted"},
- {"bin2", "lib2", "lib2", "notice"},
- {"lib1", "lib1", "lib1", "notice"},
- {"lib2", "lib2", "lib2", "notice"},
+ {"image", "image", "notice|restricted"},
+ {"image", "bin1", "reciprocal"},
+ {"image", "bin2", "restricted"},
+ {"image", "lib1", "notice"},
+ {"image", "lib2", "notice|restricted"},
+ {"bin1", "bin1", "reciprocal"},
+ {"bin1", "lib1", "notice"},
+ {"bin2", "bin2", "restricted"},
+ {"bin2", "lib2", "notice|restricted"},
+ {"lib1", "lib1", "notice"},
+ {"lib2", "lib2", "notice"},
}
// share describes bottomUp after a top-down share resolve.
share = []res{
- {"image", "image", "bin2", "restricted"},
- {"image", "bin1", "bin1", "reciprocal"},
- {"image", "bin2", "bin2", "restricted"},
- {"image", "lib2", "bin2", "restricted"},
- {"bin1", "bin1", "bin1", "reciprocal"},
- {"bin2", "bin2", "bin2", "restricted"},
- {"bin2", "lib2", "bin2", "restricted"},
+ {"image", "image", "restricted"},
+ {"image", "bin1", "reciprocal"},
+ {"image", "bin2", "restricted"},
+ {"image", "lib2", "restricted"},
+ {"bin1", "bin1", "reciprocal"},
+ {"bin2", "bin2", "restricted"},
+ {"bin2", "lib2", "restricted"},
}
// proprietary describes bottomUp after a top-down proprietary resolve.
diff --git a/tools/compliance/test_util.go b/tools/compliance/test_util.go
index 6c50d3e..053b398 100644
--- a/tools/compliance/test_util.go
+++ b/tools/compliance/test_util.go
@@ -57,7 +57,7 @@
LGPL = `` +
`package_name: "Free Library"
license_kinds: "SPDX-license-identifier-LGPL-2.0"
-license_conditions: "restricted"
+license_conditions: "restricted_if_statically_linked"
`
// MPL starts a test metadata file for a module with MPL 2.0 reciprical licensing.
@@ -121,28 +121,24 @@
return tn
}
-// newTestCondition constructs a test license condition in the license graph.
-func newTestCondition(lg *LicenseGraph, targetName string, conditionName string) LicenseCondition {
- tn := newTestNode(lg, targetName)
- cl := LicenseConditionSetFromNames(tn, conditionName).AsList()
+// newTestCondition constructs a test license condition.
+func newTestCondition(conditionName string) LicenseCondition {
+ cl := LicenseConditionSetFromNames(conditionName).AsList()
if len(cl) == 0 {
panic(fmt.Errorf("attempt to create unrecognized condition: %q", conditionName))
} else if len(cl) != 1 {
panic(fmt.Errorf("unexpected multiple conditions from condition name: %q: got %d, want 1", conditionName, len(cl)))
}
lc := cl[0]
- tn.licenseConditions = tn.licenseConditions.Plus(lc)
return lc
}
-// newTestConditionSet constructs a test license condition set in the license graph.
-func newTestConditionSet(lg *LicenseGraph, targetName string, conditionName []string) LicenseConditionSet {
- tn := newTestNode(lg, targetName)
- cs := LicenseConditionSetFromNames(tn, conditionName...)
+// newTestConditionSet constructs a test license condition set.
+func newTestConditionSet(conditionName []string) LicenseConditionSet {
+ cs := LicenseConditionSetFromNames(conditionName...)
if cs.IsEmpty() {
panic(fmt.Errorf("attempt to create unrecognized condition: %q", conditionName))
}
- tn.licenseConditions = tn.licenseConditions.Union(cs)
return cs
}
@@ -283,12 +279,12 @@
// act describes test data resolution actions to define test action sets.
type act struct {
- actsOn, origin, condition string
+ actsOn, condition string
}
// String returns a human-readable string representing the test action.
func (a act) String() string {
- return fmt.Sprintf("%s{%s:%s}", a.actsOn, a.origin, a.condition)
+ return fmt.Sprintf("%s{%s}", a.actsOn, a.condition)
}
// toActionSet converts a list of act test data into a test action set.
@@ -296,7 +292,7 @@
as := make(ActionSet)
for _, a := range data {
actsOn := newTestNode(lg, a.actsOn)
- cs := newTestConditionSet(lg, a.origin, strings.Split(a.condition, "|"))
+ cs := newTestConditionSet(strings.Split(a.condition, "|"))
as[actsOn] = cs
}
return as
@@ -304,7 +300,7 @@
// res describes test data resolutions to define test resolution sets.
type res struct {
- attachesTo, actsOn, origin, condition string
+ attachesTo, actsOn, condition string
}
// toResolutionSet converts a list of res test data into a test resolution set.
@@ -316,7 +312,7 @@
if _, ok := rmap[attachesTo]; !ok {
rmap[attachesTo] = make(ActionSet)
}
- cs := newTestConditionSet(lg, r.origin, strings.Split(r.condition, ":"))
+ cs := newTestConditionSet(strings.Split(r.condition, "|"))
rmap[attachesTo][actsOn] |= cs
}
return rmap
@@ -416,15 +412,13 @@
result := make([]SourceSharePrivacyConflict, 0, len(data))
for _, c := range data {
fields := strings.Split(c.share, ":")
- oshare := fields[0]
cshare := fields[1]
fields = strings.Split(c.privacy, ":")
- oprivacy := fields[0]
cprivacy := fields[1]
result = append(result, SourceSharePrivacyConflict{
newTestNode(lg, c.sourceNode),
- newTestCondition(lg, oshare, cshare),
- newTestCondition(lg, oprivacy, cprivacy),
+ newTestCondition(cshare),
+ newTestCondition(cprivacy),
})
}
return result
diff --git a/tools/event_log_tags.bzl b/tools/event_log_tags.bzl
deleted file mode 100644
index 35305ae..0000000
--- a/tools/event_log_tags.bzl
+++ /dev/null
@@ -1,35 +0,0 @@
-"""Event log tags generation rule"""
-
-load("@bazel_skylib//lib:paths.bzl", "paths")
-
-def _event_log_tags_impl(ctx):
- out_files = []
- for logtag_file in ctx.files.srcs:
- out_filename = paths.replace_extension(logtag_file.basename, ".java")
- out_file = ctx.actions.declare_file(out_filename)
- out_files.append(out_file)
- ctx.actions.run(
- inputs = [logtag_file],
- outputs = [out_file],
- arguments = [
- "-o",
- out_file.path,
- logtag_file.path,
- ],
- progress_message = "Generating Java logtag file from %s" % logtag_file.short_path,
- executable = ctx.executable._logtag_to_java_tool,
- )
- return [DefaultInfo(files = depset(out_files))]
-
-event_log_tags = rule(
- implementation = _event_log_tags_impl,
- attrs = {
- "srcs": attr.label_list(allow_files = [".logtags"], mandatory = True),
- "_logtag_to_java_tool": attr.label(
- executable = True,
- cfg = "exec",
- allow_files = True,
- default = Label("//build/make/tools:java-event-log-tags"),
- ),
- },
-)
diff --git a/tools/fileslist_util.py b/tools/fileslist_util.py
index ff40d51..a1b1197 100755
--- a/tools/fileslist_util.py
+++ b/tools/fileslist_util.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright (C) 2016 The Android Open Source Project
#
@@ -15,7 +15,9 @@
# limitations under the License.
#
-import getopt, json, sys
+import argparse
+import json
+import sys
def PrintFileNames(path):
with open(path) as jf:
@@ -27,42 +29,25 @@
with open(path) as jf:
data = json.load(jf)
for line in data:
- print "{0:12d} {1}".format(line["Size"], line["Name"])
+ print(f"{line['Size']:12d} {line['Name']}")
-def PrintUsage(name):
- print("""
-Usage: %s -[nc] json_files_list
- -n produces list of files only
- -c produces classic installed-files.txt
-""" % (name))
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-n", action="store_true",
+ help="produces list of files only")
+ parser.add_argument("-c", action="store_true",
+ help="produces classic installed-files.txt")
+ parser.add_argument("json_files_list")
+ args = parser.parse_args()
-def main(argv):
- try:
- opts, args = getopt.getopt(argv[1:], "nc", "")
- except getopt.GetoptError, err:
- print(err)
- PrintUsage(argv[0])
- sys.exit(2)
-
- if len(opts) == 0:
- print("No conversion option specified")
- PrintUsage(argv[0])
- sys.exit(2)
-
- if len(args) == 0:
- print("No input file specified")
- PrintUsage(argv[0])
- sys.exit(2)
-
- for o, a in opts:
- if o == ("-n"):
- PrintFileNames(args[0])
- sys.exit()
- elif o == ("-c"):
- PrintCanonicalList(args[0])
- sys.exit()
- else:
- assert False, "Unsupported option"
+ if args.n and args.c:
+ sys.exit("Cannot specify both -n and -c")
+ elif args.n:
+ PrintFileNames(args.json_files_list)
+ elif args.c:
+ PrintCanonicalList(args.json_files_list)
+ else:
+ sys.exit("No conversion option specified")
if __name__ == '__main__':
- main(sys.argv)
+ main()
diff --git a/tools/finalization/OWNERS b/tools/finalization/OWNERS
new file mode 100644
index 0000000..518b60d
--- /dev/null
+++ b/tools/finalization/OWNERS
@@ -0,0 +1,5 @@
+include platform/build/soong:/OWNERS
+smoreland@google.com
+alexbuy@google.com
+patb@google.com
+zyy@google.com
diff --git a/tools/finalization/cleanup.sh b/tools/finalization/cleanup.sh
new file mode 100755
index 0000000..cd87b1d
--- /dev/null
+++ b/tools/finalization/cleanup.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# Brings local repository to a remote head state.
+
+# set -ex
+
+function finalize_revert_local_changes_main() {
+ local top="$(dirname "$0")"/../../../..
+ local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
+
+ # remove the out folder
+ $m clobber
+
+ repo selfupdate
+
+ repo forall -c '\
+ git checkout . ; git revert --abort ; git clean -fdx ;\
+ git checkout @ ; git branch fina-step1 -D ; git reset --hard; \
+ repo start fina-step1 ; git checkout @ ; git b fina-step1 -D ;'
+}
+
+finalize_revert_local_changes_main
diff --git a/tools/finalization/environment.sh b/tools/finalization/environment.sh
new file mode 100755
index 0000000..125c704
--- /dev/null
+++ b/tools/finalization/environment.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+set -ex
+
+export FINAL_BUG_ID='0'
+
+export FINAL_PLATFORM_CODENAME='UpsideDownCake'
+export FINAL_PLATFORM_CODENAME_JAVA='UPSIDE_DOWN_CAKE'
+export FINAL_PLATFORM_SDK_VERSION='34'
+export FINAL_PLATFORM_VERSION='14'
+
+export FINAL_BUILD_PREFIX='UP1A'
+
+export FINAL_MAINLINE_EXTENSION='6'
+export FINAL_MAINLINE_SDK_COMMIT_MESSAGE=''
+export FINAL_MAINLINE_SDK_BUILD_ID=0
diff --git a/tools/finalization/finalize-aidl-vndk-sdk-resources.sh b/tools/finalization/finalize-aidl-vndk-sdk-resources.sh
new file mode 100755
index 0000000..019ace6
--- /dev/null
+++ b/tools/finalization/finalize-aidl-vndk-sdk-resources.sh
@@ -0,0 +1,135 @@
+#!/bin/bash
+
+set -ex
+
+function finalize_modules_utils() {
+ local shortCodename="${FINAL_PLATFORM_CODENAME:0:1}"
+ local methodPlaceholder="INSERT_NEW_AT_LEAST_${shortCodename}_METHOD_HERE"
+
+ local tmpfile=$(mktemp /tmp/finalization.XXXXXX)
+ echo " /** Checks if the device is running on a release version of Android $FINAL_PLATFORM_CODENAME or newer */
+ @ChecksSdkIntAtLeast(api = $FINAL_PLATFORM_SDK_VERSION /* BUILD_VERSION_CODES.$FINAL_PLATFORM_CODENAME */)
+ public static boolean isAtLeast${FINAL_PLATFORM_CODENAME:0:1}() {
+ return SDK_INT >= $FINAL_PLATFORM_SDK_VERSION;
+ }" > "$tmpfile"
+
+ local javaFuncRegex='\/\*\*[^{]*isAtLeast'"${shortCodename}"'() {[^{}]*}'
+ local javaFuncReplace="N;N;N;N;N;N;N;N; s/$javaFuncRegex/$methodPlaceholder/; /$javaFuncRegex/!{P;D};"
+
+ local javaSdkLevel="$top/frameworks/libs/modules-utils/java/com/android/modules/utils/build/SdkLevel.java"
+ sed -i "$javaFuncReplace" $javaSdkLevel
+
+ sed -i "/${methodPlaceholder}"'/{
+ r '"$tmpfile"'
+ d}' $javaSdkLevel
+
+ echo "// Checks if the device is running on release version of Android ${FINAL_PLATFORM_CODENAME:0:1} or newer.
+inline bool IsAtLeast${FINAL_PLATFORM_CODENAME:0:1}() { return android_get_device_api_level() >= $FINAL_PLATFORM_SDK_VERSION; }" > "$tmpfile"
+
+ local cppFuncRegex='\/\/[^{]*IsAtLeast'"${shortCodename}"'() {[^{}]*}'
+ local cppFuncReplace="N;N;N;N;N;N; s/$cppFuncRegex/$methodPlaceholder/; /$cppFuncRegex/!{P;D};"
+
+ local cppSdkLevel="$top/frameworks/libs/modules-utils/build/include/android-modules-utils/sdk_level.h"
+ sed -i "$cppFuncReplace" $cppSdkLevel
+ sed -i "/${methodPlaceholder}"'/{
+ r '"$tmpfile"'
+ d}' $cppSdkLevel
+
+ rm "$tmpfile"
+}
+
+function finalize_aidl_vndk_sdk_resources() {
+ local top="$(dirname "$0")"/../../../..
+ source $top/build/make/tools/finalization/environment.sh
+
+ local SDK_CODENAME="public static final int $FINAL_PLATFORM_CODENAME_JAVA = CUR_DEVELOPMENT;"
+ local SDK_VERSION="public static final int $FINAL_PLATFORM_CODENAME_JAVA = $FINAL_PLATFORM_SDK_VERSION;"
+
+ # default target to modify tree and build SDK
+ local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
+
+ # This script is WIP and only finalizes part of the Android branch for release.
+ # The full process can be found at (INTERNAL) go/android-sdk-finalization.
+
+ # Update references in the codebase to new API version (TODO)
+
+ # bionic/NDK
+ # Adding __ANDROID_API_<>__.
+ # If this hasn't done then it's not used and not really needed. Still, let's check and add this.
+ if ! grep -q "\__.*$((${FINAL_PLATFORM_SDK_VERSION}))" api-level.h ; then
+ local tmpfile=$(mktemp /tmp/finalization.XXXXXX)
+ echo "
+/** Names the \"${FINAL_PLATFORM_CODENAME:0:1}\" API level ($FINAL_PLATFORM_SDK_VERSION), for comparison against \`__ANDROID_API__\`. */
+#define __ANDROID_API_${FINAL_PLATFORM_CODENAME:0:1}__ $FINAL_PLATFORM_SDK_VERSION" > "$tmpfile"
+
+ local api_level="$top/bionic/libc/include/android/api-level.h"
+ sed -i -e "/__.*$((${FINAL_PLATFORM_SDK_VERSION}-1))/r""$tmpfile" $api_level
+
+ rm "$tmpfile"
+ fi
+
+ # VNDK definitions for new SDK version
+ cp "$top/development/vndk/tools/definition-tool/datasets/vndk-lib-extra-list-current.txt" \
+ "$top/development/vndk/tools/definition-tool/datasets/vndk-lib-extra-list-$FINAL_PLATFORM_SDK_VERSION.txt"
+
+ AIDL_TRANSITIVE_FREEZE=true $m aidl-freeze-api create_reference_dumps
+
+ # Generate ABI dumps
+ ANDROID_BUILD_TOP="$top" \
+ out/host/linux-x86/bin/create_reference_dumps \
+ -p aosp_arm64 --build-variant user
+
+ echo "NOTE: THIS INTENTIONALLY MAY FAIL AND REPAIR ITSELF (until 'DONE')"
+ # Update new versions of files. See update-vndk-list.sh (which requires envsetup.sh)
+ $m check-vndk-list || \
+ { cp $top/out/soong/vndk/vndk.libraries.txt $top/build/make/target/product/gsi/current.txt; }
+ echo "DONE: THIS INTENTIONALLY MAY FAIL AND REPAIR ITSELF"
+
+ # Finalize SDK
+
+ # frameworks/libs/modules-utils
+ finalize_modules_utils
+
+ # build/make
+ local version_defaults="$top/build/make/core/version_defaults.mk"
+ sed -i -e "s/PLATFORM_SDK_VERSION := .*/PLATFORM_SDK_VERSION := ${FINAL_PLATFORM_SDK_VERSION}/g" $version_defaults
+ sed -i -e "s/PLATFORM_VERSION_LAST_STABLE := .*/PLATFORM_VERSION_LAST_STABLE := ${FINAL_PLATFORM_VERSION}/g" $version_defaults
+ sed -i -e "s/sepolicy_major_vers := .*/sepolicy_major_vers := ${FINAL_PLATFORM_SDK_VERSION}/g" "$top/build/make/core/config.mk"
+ cp "$top/build/make/target/product/gsi/current.txt" "$top/build/make/target/product/gsi/$FINAL_PLATFORM_SDK_VERSION.txt"
+
+ # build/soong
+ sed -i -e "/:.*$((${FINAL_PLATFORM_SDK_VERSION}-1)),/a \\\t\t\t\"${FINAL_PLATFORM_CODENAME}\": ${FINAL_PLATFORM_SDK_VERSION}," "$top/build/soong/android/api_levels.go"
+
+ # cts
+ echo ${FINAL_PLATFORM_VERSION} > "$top/cts/tests/tests/os/assets/platform_releases.txt"
+ sed -i -e "s/EXPECTED_SDK = $((${FINAL_PLATFORM_SDK_VERSION}-1))/EXPECTED_SDK = ${FINAL_PLATFORM_SDK_VERSION}/g" "$top/cts/tests/tests/os/src/android/os/cts/BuildVersionTest.java"
+
+ # libcore
+ sed -i "s%$SDK_CODENAME%$SDK_VERSION%g" "$top/libcore/dalvik/src/main/java/dalvik/annotation/compat/VersionCodes.java"
+
+ # platform_testing
+ local version_codes="$top/platform_testing/libraries/compatibility-common-util/src/com/android/compatibility/common/util/VersionCodes.java"
+ sed -i -e "/=.*$((${FINAL_PLATFORM_SDK_VERSION}-1));/a \\ ${SDK_VERSION}" $version_codes
+
+ # Finalize resources
+ "$top/frameworks/base/tools/aapt2/tools/finalize_res.py" \
+ "$top/frameworks/base/core/res/res/values/public-staging.xml" \
+ "$top/frameworks/base/core/res/res/values/public-final.xml"
+
+ # frameworks/base
+ sed -i "s%$SDK_CODENAME%$SDK_VERSION%g" "$top/frameworks/base/core/java/android/os/Build.java"
+ sed -i -e "/=.*$((${FINAL_PLATFORM_SDK_VERSION}-1)),/a \\ SDK_${FINAL_PLATFORM_CODENAME_JAVA} = ${FINAL_PLATFORM_SDK_VERSION}," "$top/frameworks/base/tools/aapt/SdkConstants.h"
+ sed -i -e "/=.*$((${FINAL_PLATFORM_SDK_VERSION}-1)),/a \\ SDK_${FINAL_PLATFORM_CODENAME_JAVA} = ${FINAL_PLATFORM_SDK_VERSION}," "$top/frameworks/base/tools/aapt2/SdkConstants.h"
+
+ # Bump Mainline SDK extension version.
+ "$top/packages/modules/SdkExtensions/gen_sdk/bump_sdk.sh" ${FINAL_MAINLINE_EXTENSION}
+ local version_defaults="$top/build/make/core/version_defaults.mk"
+ sed -i -e "s/PLATFORM_SDK_EXTENSION_VERSION := .*/PLATFORM_SDK_EXTENSION_VERSION := ${FINAL_MAINLINE_EXTENSION}/g" $version_defaults
+
+ # Force update current.txt
+ $m clobber
+ $m update-api
+}
+
+finalize_aidl_vndk_sdk_resources
+
diff --git a/tools/finalization/finalize-sdk-rel.sh b/tools/finalization/finalize-sdk-rel.sh
new file mode 100755
index 0000000..6e62a0e
--- /dev/null
+++ b/tools/finalization/finalize-sdk-rel.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+set -ex
+
+function finalize_sdk_rel() {
+ local top="$(dirname "$0")"/../../../..
+ source $top/build/make/tools/finalization/environment.sh
+
+ # default target to modify tree and build SDK
+ local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
+
+ # adb keys
+ $m adb
+ LOGNAME=android-eng HOSTNAME=google.com "$top/out/host/linux-x86/bin/adb" keygen "$top/vendor/google/security/adb/${FINAL_PLATFORM_VERSION}.adb_key"
+
+ # build/make/core/version_defaults.mk
+ sed -i -e "s/PLATFORM_VERSION_CODENAME.${FINAL_BUILD_PREFIX} := .*/PLATFORM_VERSION_CODENAME.${FINAL_BUILD_PREFIX} := REL/g" "$top/build/make/core/version_defaults.mk"
+
+ # cts
+ echo "$FINAL_PLATFORM_VERSION" > "$top/cts/tests/tests/os/assets/platform_versions.txt"
+ git -C "$top/cts" mv hostsidetests/theme/assets/${FINAL_PLATFORM_CODENAME} hostsidetests/theme/assets/${FINAL_PLATFORM_SDK_VERSION}
+
+ # system/sepolicy
+ mkdir -p "$top/system/sepolicy/prebuilts/api/${FINAL_PLATFORM_SDK_VERSION}.0/"
+ cp -r "$top/system/sepolicy/public/" "$top/system/sepolicy/prebuilts/api/${FINAL_PLATFORM_SDK_VERSION}.0/"
+ cp -r "$top/system/sepolicy/private/" "$top/system/sepolicy/prebuilts/api/${FINAL_PLATFORM_SDK_VERSION}.0/"
+
+ # prebuilts/abi-dumps/ndk
+ mv "$top/prebuilts/abi-dumps/ndk/current" "$top/prebuilts/abi-dumps/ndk/$FINAL_PLATFORM_SDK_VERSION"
+
+ # prebuilts/abi-dumps/vndk
+ mv "$top/prebuilts/abi-dumps/vndk/$FINAL_PLATFORM_CODENAME" "$top/prebuilts/abi-dumps/vndk/$FINAL_PLATFORM_SDK_VERSION"
+
+ # prebuilts/abi-dumps/platform
+ mv "$top/prebuilts/abi-dumps/platform/current" "$top/prebuilts/abi-dumps/platform/$FINAL_PLATFORM_SDK_VERSION"
+}
+
+finalize_sdk_rel
+
diff --git a/tools/finalization/localonly-finalize-mainline-sdk.sh b/tools/finalization/localonly-finalize-mainline-sdk.sh
new file mode 100755
index 0000000..fc887c3
--- /dev/null
+++ b/tools/finalization/localonly-finalize-mainline-sdk.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+set -ex
+
+function finalize_locally_mainline_sdk() {
+ local top="$(dirname "$0")"/../../../..
+ source $top/build/make/tools/finalization/environment.sh
+
+ # Build modules SDKs.
+ TARGET_BUILD_VARIANT=userdebug UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true "$top/vendor/google/build/mainline_modules_sdks.sh"
+
+ # Update prebuilts.
+ "$top/prebuilts/build-tools/path/linux-x86/python3" "$top/packages/modules/common/tools/finalize_sdk.py" -l -b 0 -f ${FINAL_MAINLINE_EXTENSION} -r '' 0
+}
+
+finalize_locally_mainline_sdk
+
diff --git a/tools/finalization/step-1.sh b/tools/finalization/step-1.sh
new file mode 100755
index 0000000..db7f1cc
--- /dev/null
+++ b/tools/finalization/step-1.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# Script to perform a 1st step of Android Finalization: API/SDK finalization, create CLs and upload to Gerrit.
+
+set -ex
+
+function commit_step_1_changes() {
+ set +e
+ repo forall -c '\
+ if [[ $(git status --short) ]]; then
+ repo start "$FINAL_PLATFORM_CODENAME-SDK-Finalization" ;
+ git add -A . ;
+ git commit -m "$FINAL_PLATFORM_CODENAME is now $FINAL_PLATFORM_SDK_VERSION" \
+ -m "Ignore-AOSP-First: $FINAL_PLATFORM_CODENAME Finalization
+Bug: $FINAL_BUG_ID
+Test: build";
+ repo upload --cbr --no-verify -o nokeycheck -t -y . ;
+ git clean -fdx ; git reset --hard ;
+ fi'
+}
+
+function finalize_step_1_main() {
+ local top="$(dirname "$0")"/../../../..
+ source $top/build/make/tools/finalization/environment.sh
+
+ local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
+
+ # vndk etc finalization
+ source $top/build/make/tools/finalization/finalize-aidl-vndk-sdk-resources.sh
+
+ # build to confirm everything is OK
+ AIDL_FROZEN_REL=true $m
+
+ # move all changes to finalization branch/topic and upload to gerrit
+ commit_step_1_changes
+}
+
+finalize_step_1_main
diff --git a/tools/finalization/step-2.sh b/tools/finalization/step-2.sh
new file mode 100755
index 0000000..926b850
--- /dev/null
+++ b/tools/finalization/step-2.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# Script to perform a 2nd step of Android Finalization: REL finalization, create CLs and upload to Gerrit.
+
+function commit_step_2_changes() {
+ repo forall -c '\
+ if [[ $(git status --short) ]]; then
+ repo start "$FINAL_PLATFORM_CODENAME-SDK-Finalization-Rel" ;
+ git add -A . ;
+ git commit -m "$FINAL_PLATFORM_CODENAME/$FINAL_PLATFORM_SDK_VERSION is now REL" \
+ -m "Ignore-AOSP-First: $FINAL_PLATFORM_CODENAME Finalization
+Bug: $FINAL_BUG_ID
+Test: build";
+
+ repo upload --cbr --no-verify -o nokeycheck -t -y . ;
+ git clean -fdx ; git reset --hard ;
+ fi'
+}
+
+function finalize_step_2_main() {
+ local top="$(dirname "$0")"/../../../..
+ source $top/build/make/tools/finalization/environment.sh
+
+ local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
+
+ # prebuilts etc
+ source $top/build/make/tools/finalization/finalize-sdk-rel.sh
+
+ # Update prebuilts.
+ "$top/prebuilts/build-tools/path/linux-x86/python3" "$top/packages/modules/common/tools/finalize_sdk.py" -b ${FINAL_BUG_ID} -f ${FINAL_MAINLINE_EXTENSION} -r "${FINAL_MAINLINE_SDK_COMMIT_MESSAGE}" ${FINAL_MAINLINE_SDK_BUILD_ID}
+
+ # build to confirm everything is OK
+ AIDL_FROZEN_REL=true $m
+
+ # move all changes to finalization branch/topic and upload to gerrit
+ commit_step_2_changes
+}
+
+finalize_step_2_main
diff --git a/tools/findleaves.py b/tools/findleaves.py
index 97302e9..86f3f3a 100755
--- a/tools/findleaves.py
+++ b/tools/findleaves.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright (C) 2009 The Android Open Source Project
#
@@ -121,7 +121,7 @@
results = list(set(perform_find(mindepth, prune, dirlist, filenames)))
results.sort()
for r in results:
- print r
+ print(r)
if __name__ == "__main__":
main(sys.argv)
diff --git a/tools/fs_config/Android.bp b/tools/fs_config/Android.bp
index d57893c..55fdca4 100644
--- a/tools/fs_config/Android.bp
+++ b/tools/fs_config/Android.bp
@@ -43,14 +43,6 @@
python_binary_host {
name: "fs_config_generator",
srcs: ["fs_config_generator.py"],
- version: {
- py2: {
- enabled: true,
- },
- py3: {
- enabled: false,
- },
- },
}
python_test_host {
@@ -60,14 +52,6 @@
"test_fs_config_generator.py",
"fs_config_generator.py",
],
- version: {
- py2: {
- enabled: true,
- },
- py3: {
- enabled: false,
- },
- },
}
target_fs_config_gen_filegroup {
diff --git a/tools/fs_config/fs_config_generator.py b/tools/fs_config/fs_config_generator.py
index cb1616a..44480b8 100755
--- a/tools/fs_config/fs_config_generator.py
+++ b/tools/fs_config/fs_config_generator.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
"""Generates config files for Android file system properties.
This script is used for generating configuration files for configuring
@@ -11,7 +11,7 @@
"""
import argparse
-import ConfigParser
+import configparser
import ctypes
import re
import sys
@@ -463,7 +463,7 @@
# No core AIDs should be within any oem range.
for aid in self._aid_value_to_name:
for ranges in self._ranges.values():
- if Utils.in_any_range(aid, ranges):
+ if Utils.in_any_range(int(aid, 0), ranges):
name = self._aid_value_to_name[aid]
raise ValueError(
'AID "%s" value: %u within reserved OEM Range: "%s"' %
@@ -569,7 +569,7 @@
# override previous
# sections.
- config = ConfigParser.ConfigParser()
+ config = configparser.ConfigParser()
config.read(file_name)
for section in config.sections():
@@ -613,7 +613,7 @@
ranges = None
- partitions = self._ranges.keys()
+ partitions = list(self._ranges.keys())
partitions.sort(key=len, reverse=True)
for partition in partitions:
if aid.friendly.startswith(partition):
@@ -1073,7 +1073,7 @@
user_binary = bytearray(ctypes.c_uint16(int(user, 0)))
group_binary = bytearray(ctypes.c_uint16(int(group, 0)))
caps_binary = bytearray(ctypes.c_uint64(caps_value))
- path_binary = ctypes.create_string_buffer(path,
+ path_binary = ctypes.create_string_buffer(path.encode(),
path_length_aligned_64).raw
out_file.write(length_binary)
@@ -1169,21 +1169,21 @@
hdr = AIDHeaderParser(args['hdrfile'])
max_name_length = max(len(aid.friendly) + 1 for aid in hdr.aids)
- print AIDArrayGen._GENERATED
- print
- print AIDArrayGen._INCLUDE
- print
- print AIDArrayGen._STRUCT_FS_CONFIG % max_name_length
- print
- print AIDArrayGen._OPEN_ID_ARRAY
+ print(AIDArrayGen._GENERATED)
+ print()
+ print(AIDArrayGen._INCLUDE)
+ print()
+ print(AIDArrayGen._STRUCT_FS_CONFIG % max_name_length)
+ print()
+ print(AIDArrayGen._OPEN_ID_ARRAY)
for aid in hdr.aids:
- print AIDArrayGen._ID_ENTRY % (aid.friendly, aid.identifier)
+ print(AIDArrayGen._ID_ENTRY % (aid.friendly, aid.identifier))
- print AIDArrayGen._CLOSE_FILE_STRUCT
- print
- print AIDArrayGen._COUNT
- print
+ print(AIDArrayGen._CLOSE_FILE_STRUCT)
+ print()
+ print(AIDArrayGen._COUNT)
+ print()
@generator('oemaid')
@@ -1225,15 +1225,15 @@
parser = FSConfigFileParser(args['fsconfig'], hdr_parser.ranges)
- print OEMAidGen._GENERATED
+ print(OEMAidGen._GENERATED)
- print OEMAidGen._FILE_IFNDEF_DEFINE
+ print(OEMAidGen._FILE_IFNDEF_DEFINE)
for aid in parser.aids:
self._print_aid(aid)
- print
+ print()
- print OEMAidGen._FILE_ENDIF
+ print(OEMAidGen._FILE_ENDIF)
def _print_aid(self, aid):
"""Prints a valid #define AID identifier to stdout.
@@ -1245,10 +1245,10 @@
# print the source file location of the AID
found_file = aid.found
if found_file != self._old_file:
- print OEMAidGen._FILE_COMMENT % found_file
+ print(OEMAidGen._FILE_COMMENT % found_file)
self._old_file = found_file
- print OEMAidGen._GENERIC_DEFINE % (aid.identifier, aid.value)
+ print(OEMAidGen._GENERIC_DEFINE % (aid.identifier, aid.value))
@generator('passwd')
@@ -1292,7 +1292,7 @@
return
aids_by_partition = {}
- partitions = hdr_parser.ranges.keys()
+ partitions = list(hdr_parser.ranges.keys())
partitions.sort(key=len, reverse=True)
for aid in aids:
@@ -1331,7 +1331,7 @@
except ValueError as exception:
sys.exit(exception)
- print "%s::%s:%s::/:%s" % (logon, uid, uid, aid.login_shell)
+ print("%s::%s:%s::/:%s" % (logon, uid, uid, aid.login_shell))
@generator('group')
@@ -1356,7 +1356,7 @@
except ValueError as exception:
sys.exit(exception)
- print "%s::%s:" % (logon, uid)
+ print("%s::%s:" % (logon, uid))
@generator('print')
@@ -1379,7 +1379,7 @@
aids.sort(key=lambda item: int(item.normalized_value))
for aid in aids:
- print '%s %s' % (aid.identifier, aid.normalized_value)
+ print('%s %s' % (aid.identifier, aid.normalized_value))
def main():
@@ -1393,7 +1393,7 @@
gens = generator.get()
# for each gen, instantiate and add them as an option
- for name, gen in gens.iteritems():
+ for name, gen in gens.items():
generator_option_parser = subparser.add_parser(name, help=gen.__doc__)
generator_option_parser.set_defaults(which=name)
diff --git a/tools/fs_config/test_fs_config_generator.py b/tools/fs_config/test_fs_config_generator.py
index 76ed8f4..cbf46a1 100755
--- a/tools/fs_config/test_fs_config_generator.py
+++ b/tools/fs_config/test_fs_config_generator.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
"""Unit test suite for the fs_config_genertor.py tool."""
import tempfile
@@ -64,7 +64,7 @@
def test_aid_header_parser_good(self):
"""Test AID Header Parser good input file"""
- with tempfile.NamedTemporaryFile() as temp_file:
+ with tempfile.NamedTemporaryFile(mode='w') as temp_file:
temp_file.write(
textwrap.dedent("""
#define AID_FOO 1000
@@ -91,7 +91,7 @@
def test_aid_header_parser_good_unordered(self):
"""Test AID Header Parser good unordered input file"""
- with tempfile.NamedTemporaryFile() as temp_file:
+ with tempfile.NamedTemporaryFile(mode='w') as temp_file:
temp_file.write(
textwrap.dedent("""
#define AID_FOO 1000
@@ -118,7 +118,7 @@
def test_aid_header_parser_bad_aid(self):
"""Test AID Header Parser bad aid input file"""
- with tempfile.NamedTemporaryFile() as temp_file:
+ with tempfile.NamedTemporaryFile(mode='w') as temp_file:
temp_file.write(
textwrap.dedent("""
#define AID_FOO "bad"
@@ -131,7 +131,7 @@
def test_aid_header_parser_bad_oem_range(self):
"""Test AID Header Parser bad oem range input file"""
- with tempfile.NamedTemporaryFile() as temp_file:
+ with tempfile.NamedTemporaryFile(mode='w') as temp_file:
temp_file.write(
textwrap.dedent("""
#define AID_OEM_RESERVED_START 2900
@@ -145,7 +145,7 @@
def test_aid_header_parser_bad_oem_range_no_end(self):
"""Test AID Header Parser bad oem range (no end) input file"""
- with tempfile.NamedTemporaryFile() as temp_file:
+ with tempfile.NamedTemporaryFile(mode='w') as temp_file:
temp_file.write(
textwrap.dedent("""
#define AID_OEM_RESERVED_START 2900
@@ -158,7 +158,7 @@
def test_aid_header_parser_bad_oem_range_no_start(self):
"""Test AID Header Parser bad oem range (no start) input file"""
- with tempfile.NamedTemporaryFile() as temp_file:
+ with tempfile.NamedTemporaryFile(mode='w') as temp_file:
temp_file.write(
textwrap.dedent("""
#define AID_OEM_RESERVED_END 2900
@@ -171,7 +171,7 @@
def test_aid_header_parser_bad_oem_range_duplicated(self):
"""Test AID Header Parser bad oem range (no start) input file"""
- with tempfile.NamedTemporaryFile() as temp_file:
+ with tempfile.NamedTemporaryFile(mode='w') as temp_file:
temp_file.write(
textwrap.dedent("""
#define AID_OEM_RESERVED_START 2000
@@ -187,7 +187,7 @@
def test_aid_header_parser_bad_oem_range_mismatch_start_end(self):
"""Test AID Header Parser bad oem range mismatched input file"""
- with tempfile.NamedTemporaryFile() as temp_file:
+ with tempfile.NamedTemporaryFile(mode='w') as temp_file:
temp_file.write(
textwrap.dedent("""
#define AID_OEM_RESERVED_START 2900
@@ -201,7 +201,7 @@
def test_aid_header_parser_bad_duplicate_ranges(self):
"""Test AID Header Parser exits cleanly on duplicate AIDs"""
- with tempfile.NamedTemporaryFile() as temp_file:
+ with tempfile.NamedTemporaryFile(mode='w') as temp_file:
temp_file.write(
textwrap.dedent("""
#define AID_FOO 100
@@ -222,7 +222,7 @@
- https://android-review.googlesource.com/#/c/313169
"""
- with tempfile.NamedTemporaryFile() as temp_file:
+ with tempfile.NamedTemporaryFile(mode='w') as temp_file:
temp_file.write(
textwrap.dedent("""
#define AID_APP 10000 /* TODO: switch users over to AID_APP_START */
@@ -257,7 +257,7 @@
def test_fs_config_file_parser_good(self):
"""Test FSConfig Parser good input file"""
- with tempfile.NamedTemporaryFile() as temp_file:
+ with tempfile.NamedTemporaryFile(mode='w') as temp_file:
temp_file.write(
textwrap.dedent("""
[/system/bin/file]
@@ -305,7 +305,7 @@
def test_fs_config_file_parser_bad(self):
"""Test FSConfig Parser bad input file"""
- with tempfile.NamedTemporaryFile() as temp_file:
+ with tempfile.NamedTemporaryFile(mode='w') as temp_file:
temp_file.write(
textwrap.dedent("""
[/system/bin/file]
@@ -319,7 +319,7 @@
def test_fs_config_file_parser_bad_aid_range(self):
"""Test FSConfig Parser bad aid range value input file"""
- with tempfile.NamedTemporaryFile() as temp_file:
+ with tempfile.NamedTemporaryFile(mode='w') as temp_file:
temp_file.write(
textwrap.dedent("""
[AID_OEM1]
diff --git a/tools/java-layers.py b/tools/java-layers.py
deleted file mode 100755
index b3aec2b..0000000
--- a/tools/java-layers.py
+++ /dev/null
@@ -1,257 +0,0 @@
-#!/usr/bin/env python
-
-import os
-import re
-import sys
-
-def fail_with_usage():
- sys.stderr.write("usage: java-layers.py DEPENDENCY_FILE SOURCE_DIRECTORIES...\n")
- sys.stderr.write("\n")
- sys.stderr.write("Enforces layering between java packages. Scans\n")
- sys.stderr.write("DIRECTORY and prints errors when the packages violate\n")
- sys.stderr.write("the rules defined in the DEPENDENCY_FILE.\n")
- sys.stderr.write("\n")
- sys.stderr.write("Prints a warning when an unknown package is encountered\n")
- sys.stderr.write("on the assumption that it should fit somewhere into the\n")
- sys.stderr.write("layering.\n")
- sys.stderr.write("\n")
- sys.stderr.write("DEPENDENCY_FILE format\n")
- sys.stderr.write(" - # starts comment\n")
- sys.stderr.write(" - Lines consisting of two java package names: The\n")
- sys.stderr.write(" first package listed must not contain any references\n")
- sys.stderr.write(" to any classes present in the second package, or any\n")
- sys.stderr.write(" of its dependencies.\n")
- sys.stderr.write(" - Lines consisting of one java package name: The\n")
- sys.stderr.write(" packge is assumed to be a high level package and\n")
- sys.stderr.write(" nothing may depend on it.\n")
- sys.stderr.write(" - Lines consisting of a dash (+) followed by one java\n")
- sys.stderr.write(" package name: The package is considered a low level\n")
- sys.stderr.write(" package and may not import any of the other packages\n")
- sys.stderr.write(" listed in the dependency file.\n")
- sys.stderr.write(" - Lines consisting of a plus (-) followed by one java\n")
- sys.stderr.write(" package name: The package is considered \'legacy\'\n")
- sys.stderr.write(" and excluded from errors.\n")
- sys.stderr.write("\n")
- sys.exit(1)
-
-class Dependency:
- def __init__(self, filename, lineno, lower, top, lowlevel, legacy):
- self.filename = filename
- self.lineno = lineno
- self.lower = lower
- self.top = top
- self.lowlevel = lowlevel
- self.legacy = legacy
- self.uppers = []
- self.transitive = set()
-
- def matches(self, imp):
- for d in self.transitive:
- if imp.startswith(d):
- return True
- return False
-
-class Dependencies:
- def __init__(self, deps):
- def recurse(obj, dep, visited):
- global err
- if dep in visited:
- sys.stderr.write("%s:%d: Circular dependency found:\n"
- % (dep.filename, dep.lineno))
- for v in visited:
- sys.stderr.write("%s:%d: Dependency: %s\n"
- % (v.filename, v.lineno, v.lower))
- err = True
- return
- visited.append(dep)
- for upper in dep.uppers:
- obj.transitive.add(upper)
- if upper in deps:
- recurse(obj, deps[upper], visited)
- self.deps = deps
- self.parts = [(dep.lower.split('.'),dep) for dep in deps.itervalues()]
- # transitive closure of dependencies
- for dep in deps.itervalues():
- recurse(dep, dep, [])
- # disallow everything from the low level components
- for dep in deps.itervalues():
- if dep.lowlevel:
- for d in deps.itervalues():
- if dep != d and not d.legacy:
- dep.transitive.add(d.lower)
- # disallow the 'top' components everywhere but in their own package
- for dep in deps.itervalues():
- if dep.top and not dep.legacy:
- for d in deps.itervalues():
- if dep != d and not d.legacy:
- d.transitive.add(dep.lower)
- for dep in deps.itervalues():
- dep.transitive = set([x+"." for x in dep.transitive])
- if False:
- for dep in deps.itervalues():
- print "-->", dep.lower, "-->", dep.transitive
-
- # Lookup the dep object for the given package. If pkg is a subpackage
- # of one with a rule, that one will be returned. If no matches are found,
- # None is returned.
- def lookup(self, pkg):
- # Returns the number of parts that match
- def compare_parts(parts, pkg):
- if len(parts) > len(pkg):
- return 0
- n = 0
- for i in range(0, len(parts)):
- if parts[i] != pkg[i]:
- return 0
- n = n + 1
- return n
- pkg = pkg.split(".")
- matched = 0
- result = None
- for (parts,dep) in self.parts:
- x = compare_parts(parts, pkg)
- if x > matched:
- matched = x
- result = dep
- return result
-
-def parse_dependency_file(filename):
- global err
- f = file(filename)
- lines = f.readlines()
- f.close()
- def lineno(s, i):
- i[0] = i[0] + 1
- return (i[0],s)
- n = [0]
- lines = [lineno(x,n) for x in lines]
- lines = [(n,s.split("#")[0].strip()) for (n,s) in lines]
- lines = [(n,s) for (n,s) in lines if len(s) > 0]
- lines = [(n,s.split()) for (n,s) in lines]
- deps = {}
- for n,words in lines:
- if len(words) == 1:
- lower = words[0]
- top = True
- legacy = False
- lowlevel = False
- if lower[0] == '+':
- lower = lower[1:]
- top = False
- lowlevel = True
- elif lower[0] == '-':
- lower = lower[1:]
- legacy = True
- if lower in deps:
- sys.stderr.write(("%s:%d: Package '%s' already defined on"
- + " line %d.\n") % (filename, n, lower, deps[lower].lineno))
- err = True
- else:
- deps[lower] = Dependency(filename, n, lower, top, lowlevel, legacy)
- elif len(words) == 2:
- lower = words[0]
- upper = words[1]
- if lower in deps:
- dep = deps[lower]
- if dep.top:
- sys.stderr.write(("%s:%d: Can't add dependency to top level package "
- + "'%s'\n") % (filename, n, lower))
- err = True
- else:
- dep = Dependency(filename, n, lower, False, False, False)
- deps[lower] = dep
- dep.uppers.append(upper)
- else:
- sys.stderr.write("%s:%d: Too many words on line starting at \'%s\'\n" % (
- filename, n, words[2]))
- err = True
- return Dependencies(deps)
-
-def find_java_files(srcs):
- result = []
- for d in srcs:
- if d[0] == '@':
- f = file(d[1:])
- result.extend([fn for fn in [s.strip() for s in f.readlines()]
- if len(fn) != 0])
- f.close()
- else:
- for root, dirs, files in os.walk(d):
- result.extend([os.sep.join((root,f)) for f in files
- if f.lower().endswith(".java")])
- return result
-
-COMMENTS = re.compile("//.*?\n|/\*.*?\*/", re.S)
-PACKAGE = re.compile("package\s+(.*)")
-IMPORT = re.compile("import\s+(.*)")
-
-def examine_java_file(deps, filename):
- global err
- # Yes, this is a crappy java parser. Write a better one if you want to.
- f = file(filename)
- text = f.read()
- f.close()
- text = COMMENTS.sub("", text)
- index = text.find("{")
- if index < 0:
- sys.stderr.write(("%s: Error: Unable to parse java. Can't find class "
- + "declaration.\n") % filename)
- err = True
- return
- text = text[0:index]
- statements = [s.strip() for s in text.split(";")]
- # First comes the package declaration. Then iterate while we see import
- # statements. Anything else is either bad syntax that we don't care about
- # because the compiler will fail, or the beginning of the class declaration.
- m = PACKAGE.match(statements[0])
- if not m:
- sys.stderr.write(("%s: Error: Unable to parse java. Missing package "
- + "statement.\n") % filename)
- err = True
- return
- pkg = m.group(1)
- imports = []
- for statement in statements[1:]:
- m = IMPORT.match(statement)
- if not m:
- break
- imports.append(m.group(1))
- # Do the checking
- if False:
- print filename
- print "'%s' --> %s" % (pkg, imports)
- dep = deps.lookup(pkg)
- if not dep:
- sys.stderr.write(("%s: Error: Package does not appear in dependency file: "
- + "%s\n") % (filename, pkg))
- err = True
- return
- for imp in imports:
- if dep.matches(imp):
- sys.stderr.write("%s: Illegal import in package '%s' of '%s'\n"
- % (filename, pkg, imp))
- err = True
-
-err = False
-
-def main(argv):
- if len(argv) < 3:
- fail_with_usage()
- deps = parse_dependency_file(argv[1])
-
- if err:
- sys.exit(1)
-
- java = find_java_files(argv[2:])
- for filename in java:
- examine_java_file(deps, filename)
-
- if err:
- sys.stderr.write("%s: Using this file as dependency file.\n" % argv[1])
- sys.exit(1)
-
- sys.exit(0)
-
-if __name__ == "__main__":
- main(sys.argv)
-
diff --git a/tools/parsedeps.py b/tools/parsedeps.py
deleted file mode 100755
index 32d8ad7..0000000
--- a/tools/parsedeps.py
+++ /dev/null
@@ -1,151 +0,0 @@
-#!/usr/bin/env python
-# vim: ts=2 sw=2
-
-import optparse
-import re
-import sys
-
-
-class Dependency:
- def __init__(self, tgt):
- self.tgt = tgt
- self.pos = ""
- self.prereqs = set()
- self.visit = 0
-
- def add(self, prereq):
- self.prereqs.add(prereq)
-
-
-class Dependencies:
- def __init__(self):
- self.lines = {}
- self.__visit = 0
- self.count = 0
-
- def add(self, tgt, prereq):
- t = self.lines.get(tgt)
- if not t:
- t = Dependency(tgt)
- self.lines[tgt] = t
- p = self.lines.get(prereq)
- if not p:
- p = Dependency(prereq)
- self.lines[prereq] = p
- t.add(p)
- self.count = self.count + 1
-
- def setPos(self, tgt, pos):
- t = self.lines.get(tgt)
- if not t:
- t = Dependency(tgt)
- self.lines[tgt] = t
- t.pos = pos
-
- def get(self, tgt):
- if self.lines.has_key(tgt):
- return self.lines[tgt]
- else:
- return None
-
- def __iter__(self):
- return self.lines.iteritems()
-
- def trace(self, tgt, prereq):
- self.__visit = self.__visit + 1
- d = self.lines.get(tgt)
- if not d:
- return
- return self.__trace(d, prereq)
-
- def __trace(self, d, prereq):
- if d.visit == self.__visit:
- return d.trace
- if d.tgt == prereq:
- return [ [ d ], ]
- d.visit = self.__visit
- result = []
- for pre in d.prereqs:
- recursed = self.__trace(pre, prereq)
- for r in recursed:
- result.append([ d ] + r)
- d.trace = result
- return result
-
-def help():
- print "Commands:"
- print " dep TARGET Print the prerequisites for TARGET"
- print " trace TARGET PREREQ Print the paths from TARGET to PREREQ"
-
-
-def main(argv):
- opts = optparse.OptionParser()
- opts.add_option("-i", "--interactive", action="store_true", dest="interactive",
- help="Interactive mode")
- (options, args) = opts.parse_args()
-
- deps = Dependencies()
-
- filename = args[0]
- print "Reading %s" % filename
-
- if True:
- f = open(filename)
- for line in f:
- line = line.strip()
- if len(line) > 0:
- if line[0] == '#':
- pos,tgt = line.rsplit(":", 1)
- pos = pos[1:].strip()
- tgt = tgt.strip()
- deps.setPos(tgt, pos)
- else:
- (tgt,prereq) = line.split(':', 1)
- tgt = tgt.strip()
- prereq = prereq.strip()
- deps.add(tgt, prereq)
- f.close()
-
- print "Read %d dependencies. %d targets." % (deps.count, len(deps.lines))
- while True:
- line = raw_input("target> ")
- if not line.strip():
- continue
- split = line.split()
- cmd = split[0]
- if len(split) == 2 and cmd == "dep":
- tgt = split[1]
- d = deps.get(tgt)
- if d:
- for prereq in d.prereqs:
- print prereq.tgt
- elif len(split) == 3 and cmd == "trace":
- tgt = split[1]
- prereq = split[2]
- if False:
- print "from %s to %s" % (tgt, prereq)
- trace = deps.trace(tgt, prereq)
- if trace:
- width = 0
- for g in trace:
- for t in g:
- if len(t.tgt) > width:
- width = len(t.tgt)
- for g in trace:
- for t in g:
- if t.pos:
- print t.tgt, " " * (width-len(t.tgt)), " #", t.pos
- else:
- print t.tgt
- print
- else:
- help()
-
-if __name__ == "__main__":
- try:
- main(sys.argv)
- except KeyboardInterrupt:
- print
- except EOFError:
- print
-
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 465e1a8..b45b0a3 100644
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -842,14 +842,13 @@
SYSTEM/ after rebuilding recovery.
"""
common.ZipDelete(zip_filename, files_list)
- output_zip = zipfile.ZipFile(zip_filename, "a",
+ with zipfile.ZipFile(zip_filename, "a",
compression=zipfile.ZIP_DEFLATED,
- allowZip64=True)
- for item in files_list:
- file_path = os.path.join(OPTIONS.input_tmp, item)
- assert os.path.exists(file_path)
- common.ZipWrite(output_zip, file_path, arcname=item)
- common.ZipClose(output_zip)
+ allowZip64=True) as output_zip:
+ for item in files_list:
+ file_path = os.path.join(OPTIONS.input_tmp, item)
+ assert os.path.exists(file_path)
+ common.ZipWrite(output_zip, file_path, arcname=item)
def HasPartition(partition_name):
@@ -1133,6 +1132,21 @@
item for item in vbmeta_partitions
if item not in vbmeta_vendor.split()]
vbmeta_partitions.append("vbmeta_vendor")
+ custom_avb_partitions = OPTIONS.info_dict.get("avb_custom_vbmeta_images_partition_list", "").strip().split()
+ if custom_avb_partitions:
+ for avb_part in custom_avb_partitions:
+ partition_name = "vbmeta_" + avb_part
+ included_partitions = OPTIONS.info_dict.get("avb_vbmeta_{}".format(avb_part), "").strip().split()
+ assert included_partitions, "Custom vbmeta partition {0} missing avb_vbmeta_{0} prop".format(avb_part)
+ banner(partition_name)
+ logger.info("VBMeta partition {} needs {}".format(partition_name, included_partitions))
+ partitions[partition_name] = AddVBMeta(
+ output_zip, partitions, partition_name, included_partitions)
+ vbmeta_partitions = [
+ item for item in vbmeta_partitions
+ if item not in included_partitions]
+ vbmeta_partitions.append(partition_name)
+
if OPTIONS.info_dict.get("avb_building_vbmeta_image") == "true":
banner("vbmeta")
@@ -1176,7 +1190,7 @@
AddVbmetaDigest(output_zip)
if output_zip:
- common.ZipClose(output_zip)
+ output_zip.close()
if OPTIONS.replace_updated_files_list:
ReplaceUpdatedFiles(output_zip.filename,
OPTIONS.replace_updated_files_list)
diff --git a/tools/releasetools/apex_utils.py b/tools/releasetools/apex_utils.py
index d7b0ba2..40f7c92 100644
--- a/tools/releasetools/apex_utils.py
+++ b/tools/releasetools/apex_utils.py
@@ -63,6 +63,10 @@
self.codename_to_api_level_map = codename_to_api_level_map
self.debugfs_path = os.path.join(
OPTIONS.search_path, "bin", "debugfs_static")
+ self.fsckerofs_path = os.path.join(
+ OPTIONS.search_path, "bin", "fsck.erofs")
+ self.blkid_path = os.path.join(
+ OPTIONS.search_path, "bin", "blkid_static")
self.avbtool = avbtool if avbtool else "avbtool"
self.sign_tool = sign_tool
@@ -80,8 +84,8 @@
"Couldn't find location of debugfs_static: " +
"Path {} does not exist. ".format(self.debugfs_path) +
"Make sure bin/debugfs_static can be found in -p <path>")
- list_cmd = ['deapexer', '--debugfs_path',
- self.debugfs_path, 'list', self.apex_path]
+ list_cmd = ['deapexer', '--debugfs_path', self.debugfs_path,
+ 'list', self.apex_path]
entries_names = common.RunAndCheckOutput(list_cmd).split()
apk_entries = [name for name in entries_names if name.endswith('.apk')]
sepolicy_entries = []
@@ -120,9 +124,21 @@
"Couldn't find location of debugfs_static: " +
"Path {} does not exist. ".format(self.debugfs_path) +
"Make sure bin/debugfs_static can be found in -p <path>")
+ if not os.path.exists(self.fsckerofs_path):
+ raise ApexSigningError(
+ "Couldn't find location of fsck.erofs: " +
+ "Path {} does not exist. ".format(self.fsckerofs_path) +
+ "Make sure bin/fsck.erofs can be found in -p <path>")
+ if not os.path.exists(self.blkid_path):
+ raise ApexSigningError(
+ "Couldn't find location of blkid: " +
+ "Path {} does not exist. ".format(self.blkid_path) +
+ "Make sure bin/blkid can be found in -p <path>")
payload_dir = common.MakeTempDir()
- extract_cmd = ['deapexer', '--debugfs_path',
- self.debugfs_path, 'extract', self.apex_path, payload_dir]
+ extract_cmd = ['deapexer', '--debugfs_path', self.debugfs_path,
+ '--fsckerofs_path', self.fsckerofs_path,
+ '--blkid_path', self.blkid_path, 'extract',
+ self.apex_path, payload_dir]
common.RunAndCheckOutput(extract_cmd)
assert os.path.exists(self.apex_path)
@@ -415,7 +431,7 @@
apex_zip = zipfile.ZipFile(apex_file, 'a', allowZip64=True)
common.ZipWrite(apex_zip, payload_file, arcname=APEX_PAYLOAD_IMAGE)
common.ZipWrite(apex_zip, payload_public_key, arcname=APEX_PUBKEY)
- common.ZipClose(apex_zip)
+ apex_zip.close()
# 3. Sign the APEX container with container_key.
signed_apex = common.MakeTempFile(prefix='apex-container-', suffix='.apex')
@@ -603,11 +619,13 @@
debugfs_path = "debugfs"
if OPTIONS.search_path:
debugfs_path = os.path.join(OPTIONS.search_path, "bin", "debugfs_static")
+
deapexer = 'deapexer'
if OPTIONS.search_path:
deapexer_path = os.path.join(OPTIONS.search_path, "bin", "deapexer")
if os.path.isfile(deapexer_path):
deapexer = deapexer_path
+
for apex_filename in os.listdir(target_dir):
apex_filepath = os.path.join(target_dir, apex_filename)
if not os.path.isfile(apex_filepath) or \
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index 211182a..8087fcd 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -1171,7 +1171,7 @@
try:
# Compresses with the default level
compress_obj = zlib.compressobj(6, zlib.DEFLATED, -zlib.MAX_WBITS)
- compressed_data = (compress_obj.compress("".join(tgt_data))
+ compressed_data = (compress_obj.compress(b"".join(tgt_data))
+ compress_obj.flush())
compressed_size = len(compressed_data)
except zlib.error as e:
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 7639ffd..9064136 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -232,11 +232,13 @@
mount_point, total_blocks, used_blocks, headroom_blocks,
adjusted_blocks))
+
def CalculateSizeAndReserved(prop_dict, size):
fs_type = prop_dict.get("fs_type", "")
partition_headroom = int(prop_dict.get("partition_headroom", 0))
# If not specified, give us 16MB margin for GetDiskUsage error ...
- reserved_size = int(prop_dict.get("partition_reserved_size", BYTES_IN_MB * 16))
+ reserved_size = int(prop_dict.get(
+ "partition_reserved_size", BYTES_IN_MB * 16))
if fs_type == "erofs":
reserved_size = int(prop_dict.get("partition_reserved_size", 0))
@@ -249,6 +251,7 @@
return size + reserved_size
+
def BuildImageMkfs(in_dir, prop_dict, out_file, target_out, fs_config):
"""Builds a pure image for the files under in_dir and writes it to out_file.
@@ -410,7 +413,7 @@
build_command.append("--casefold")
if (needs_compress or prop_dict.get("f2fs_compress") == "true"):
build_command.append("--compression")
- if (prop_dict.get("mount_point") != "data"):
+ if "ro_mount_point" in prop_dict:
build_command.append("--readonly")
if (prop_dict.get("f2fs_compress") == "true"):
build_command.append("--sldc")
@@ -518,11 +521,12 @@
disable_sparse = "disable_sparse" in prop_dict
mkfs_output = None
if (prop_dict.get("use_dynamic_partition_size") == "true" and
- "partition_size" not in prop_dict):
+ "partition_size" not in prop_dict):
# If partition_size is not defined, use output of `du' + reserved_size.
# For compressed file system, it's better to use the compressed size to avoid wasting space.
if fs_type.startswith("erofs"):
- mkfs_output = BuildImageMkfs(in_dir, prop_dict, out_file, target_out, fs_config)
+ mkfs_output = BuildImageMkfs(
+ in_dir, prop_dict, out_file, target_out, fs_config)
if "erofs_sparse_flag" in prop_dict and not disable_sparse:
image_path = UnsparseImage(out_file, replace=False)
size = GetDiskUsage(image_path)
@@ -612,7 +616,8 @@
prop_dict["image_size"] = str(max_image_size)
if not mkfs_output:
- mkfs_output = BuildImageMkfs(in_dir, prop_dict, out_file, target_out, fs_config)
+ mkfs_output = BuildImageMkfs(
+ in_dir, prop_dict, out_file, target_out, fs_config)
# Update the image (eg filesystem size). This can be different eg if mkfs
# rounds the requested size down due to alignment.
@@ -629,6 +634,7 @@
if verity_image_builder:
verity_image_builder.Build(out_file)
+
def ImagePropFromGlobalDict(glob_dict, mount_point):
"""Build an image property dictionary from the global dictionary.
@@ -738,7 +744,7 @@
# This property is legacy and only used on a few partitions. b/202600377
allowed_partitions = set(["system", "system_other", "data", "oem"])
if mount_point not in allowed_partitions:
- continue
+ continue
if (mount_point == "system_other") and (dest_prop != "partition_size"):
# Propagate system properties to system_other. They'll get overridden
@@ -757,6 +763,8 @@
if not copy_prop(prop, "extfs_rsv_pct"):
d["extfs_rsv_pct"] = "0"
+ d["ro_mount_point"] = "1"
+
# Copy partition-specific properties.
d["mount_point"] = mount_point
if mount_point == "system":
@@ -791,6 +799,7 @@
def GlobalDictFromImageProp(image_prop, mount_point):
d = {}
+
def copy_prop(src_p, dest_p):
if src_p in image_prop:
d[dest_p] = image_prop[src_p]
@@ -818,6 +827,56 @@
return d
+def BuildVBMeta(in_dir, glob_dict, output_path):
+ """Creates a VBMeta image.
+
+ It generates the requested VBMeta image. The requested image could be for
+ top-level or chained VBMeta image, which is determined based on the name.
+
+ Args:
+ output_path: Path to generated vbmeta.img
+ partitions: A dict that's keyed by partition names with image paths as
+ values. Only valid partition names are accepted, as partitions listed
+ in common.AVB_PARTITIONS and custom partitions listed in
+ OPTIONS.info_dict.get("avb_custom_images_partition_list")
+ name: Name of the VBMeta partition, e.g. 'vbmeta', 'vbmeta_system'.
+ needed_partitions: Partitions whose descriptors should be included into the
+ generated VBMeta image.
+
+ Returns:
+ Path to the created image.
+
+ Raises:
+ AssertionError: On invalid input args.
+ """
+ vbmeta_partitions = common.AVB_PARTITIONS[:]
+ name = os.path.basename(output_path).rstrip(".img")
+ vbmeta_system = glob_dict.get("avb_vbmeta_system", "").strip()
+ vbmeta_vendor = glob_dict.get("avb_vbmeta_vendor", "").strip()
+ if "vbmeta_system" in name:
+ vbmeta_partitions = vbmeta_system.split()
+ elif "vbmeta_vendor" in name:
+ vbmeta_partitions = vbmeta_vendor.split()
+ else:
+ if vbmeta_system:
+ vbmeta_partitions = [
+ item for item in vbmeta_partitions
+ if item not in vbmeta_system.split()]
+ vbmeta_partitions.append("vbmeta_system")
+
+ if vbmeta_vendor:
+ vbmeta_partitions = [
+ item for item in vbmeta_partitions
+ if item not in vbmeta_vendor.split()]
+ vbmeta_partitions.append("vbmeta_vendor")
+
+
+ partitions = {part: os.path.join(in_dir, part + ".img")
+ for part in vbmeta_partitions}
+ partitions = {part:path for (part, path) in partitions.items() if os.path.exists(path)}
+ common.BuildVBMeta(output_path, partitions, name, vbmeta_partitions)
+
+
def main(argv):
args = common.ParseOptions(argv, __doc__)
@@ -864,14 +923,21 @@
mount_point = "product"
elif image_filename == "system_ext.img":
mount_point = "system_ext"
+ elif "vbmeta" in image_filename:
+ mount_point = "vbmeta"
else:
logger.error("Unknown image file name %s", image_filename)
sys.exit(1)
- image_properties = ImagePropFromGlobalDict(glob_dict, mount_point)
+ if "vbmeta" != mount_point:
+ image_properties = ImagePropFromGlobalDict(glob_dict, mount_point)
try:
- BuildImage(in_dir, image_properties, out_file, target_out)
+ if "vbmeta" in os.path.basename(out_file):
+ OPTIONS.info_dict = glob_dict
+ BuildVBMeta(in_dir, glob_dict, out_file)
+ else:
+ BuildImage(in_dir, image_properties, out_file, target_out)
except:
logger.error("Failed to build %s from %s", out_file, in_dir)
raise
diff --git a/tools/releasetools/check_ota_package_signature.py b/tools/releasetools/check_ota_package_signature.py
index b395c19..97957be 100755
--- a/tools/releasetools/check_ota_package_signature.py
+++ b/tools/releasetools/check_ota_package_signature.py
@@ -142,7 +142,7 @@
"""Verifies the payload and metadata signatures in an A/B OTA payload."""
package_zip = zipfile.ZipFile(package, 'r', allowZip64=True)
if 'payload.bin' not in package_zip.namelist():
- common.ZipClose(package_zip)
+ package_zip.close()
return
print('Verifying A/B OTA payload signatures...')
@@ -160,7 +160,7 @@
'--in_file=' + payload_file,
'--public_key=' + pubkey]
common.RunAndCheckOutput(cmd)
- common.ZipClose(package_zip)
+ package_zip.close()
# Verified successfully upon reaching here.
print('\nPayload signatures VERIFIED\n\n')
diff --git a/tools/releasetools/check_target_files_vintf.py b/tools/releasetools/check_target_files_vintf.py
index c369a59..5b71c72 100755
--- a/tools/releasetools/check_target_files_vintf.py
+++ b/tools/releasetools/check_target_files_vintf.py
@@ -129,8 +129,8 @@
dirmap = GetDirmap(input_tmp)
- apex_root, apex_info_file = PrepareApexDirectory(input_tmp)
- dirmap['/apex'] = apex_root
+ # Simulate apexd from target-files.
+ dirmap['/apex'] = PrepareApexDirectory(input_tmp)
args_for_skus = GetArgsForSkus(info_dict)
shipping_api_level_args = GetArgsForShippingApiLevel(info_dict)
@@ -140,7 +140,6 @@
'checkvintf',
'--check-compat',
]
- common_command += ['--apex-info-file', apex_info_file]
for device_path, real_path in sorted(dirmap.items()):
common_command += ['--dirmap', '{}:{}'.format(device_path, real_path)]
@@ -206,34 +205,40 @@
return patterns
def PrepareApexDirectory(inp):
- """ Prepare the APEX data.
+ """ Prepare /apex directory before running checkvintf
Apex binaries do not support dirmaps, in order to use these binaries we
need to move the APEXes from the extracted target file archives to the
expected device locations.
- The APEXes will also be extracted under the APEX/ directory
- matching what would be on the target.
+ This simulates how apexd activates APEXes.
+ 1. create {inp}/APEX which is treated as a "/" on device.
+ 2. copy apexes from target-files to {root}/{partition}/apex.
+ 3. mount apexes under {root}/{partition}/apex at {root}/apex.
+ 4. generate info files with dump_apex_info.
- Create the following structure under the input inp directory:
- APEX/apex # Extracted APEXes
- APEX/system/apex/ # System APEXes
- APEX/vendor/apex/ # Vendor APEXes
+ We'll get the following layout
+ {inp}/APEX/apex # Activated APEXes + some info files
+ {inp}/APEX/system/apex # System APEXes
+ {inp}/APEX/vendor/apex # Vendor APEXes
...
Args:
inp: path to the directory that contains the extracted target files archive.
Returns:
- extracted apex directory
- apex-info-list.xml file
+ directory representing /apex on device
"""
- debugfs_path = 'debugfs'
deapexer = 'deapexer'
+ debugfs_path = 'debugfs'
+ blkid_path = 'blkid'
+ fsckerofs_path = 'fsck.erofs'
if OPTIONS.search_path:
debugfs_path = os.path.join(OPTIONS.search_path, 'bin', 'debugfs_static')
deapexer_path = os.path.join(OPTIONS.search_path, 'bin', 'deapexer')
+ blkid_path = os.path.join(OPTIONS.search_path, 'bin', 'blkid_static')
+ fsckerofs_path = os.path.join(OPTIONS.search_path, 'bin', 'fsck.erofs')
if os.path.isfile(deapexer_path):
deapexer = deapexer_path
@@ -257,6 +262,8 @@
cmd = [deapexer,
'--debugfs_path', debugfs_path,
+ '--fsckerofs_path', fsckerofs_path,
+ '--blkid_path', blkid_path,
'extract',
apex,
os.path.join(outp, info['name'])]
@@ -267,35 +274,34 @@
root_dir_name = 'APEX'
root_dir = os.path.join(inp, root_dir_name)
extracted_root = os.path.join(root_dir, 'apex')
- apex_info_file = os.path.join(extracted_root, 'apex-info-list.xml')
- # Always create APEX directory for dirmap
+ # Always create /apex directory for dirmap
os.makedirs(extracted_root)
create_info_file = False
# Loop through search path looking for and processing apex/ directories.
for device_path, target_files_rel_paths in DIR_SEARCH_PATHS.items():
+ # checkvintf only needs vendor apexes. skip other partitions for efficiency
+ if device_path not in ['/vendor', '/odm']:
+ continue
+ # First, copy VENDOR/apex/foo.apex to APEX/vendor/apex/foo.apex
+ # Then, extract the contents to APEX/apex/foo/
for target_files_rel_path in target_files_rel_paths:
inp_partition = os.path.join(inp, target_files_rel_path,"apex")
if os.path.exists(inp_partition):
apex_dir = root_dir + os.path.join(device_path + "/apex");
- os.makedirs(apex_dir)
- os.rename(inp_partition, apex_dir)
+ os.makedirs(root_dir + device_path)
+ shutil.copytree(inp_partition, apex_dir, symlinks=True)
ExtractApexes(apex_dir, extracted_root)
create_info_file = True
if create_info_file:
- ### Create apex-info-list.xml
- dump_cmd = ['dump_apex_info',
- '--root_dir', root_dir,
- '--out_file', apex_info_file]
+ ### Dump apex info files
+ dump_cmd = ['dump_apex_info', '--root_dir', root_dir]
common.RunAndCheckOutput(dump_cmd)
- if not os.path.exists(apex_info_file):
- raise RuntimeError('Failed to create apex info file %s', apex_info_file)
- logger.info('Created %s', apex_info_file)
- return extracted_root, apex_info_file
+ return extracted_root
def CheckVintfFromTargetFiles(inp, info_dict=None):
"""
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 3c5ba10..9919029 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -723,7 +723,16 @@
with open(tmp_file, 'wb') as f:
f.write(input_file.read(fn))
return tmp_file
+ elif zipfile.is_zipfile(input_file):
+ with zipfile.ZipFile(input_file, "r", allowZip64=True) as zfp:
+ tmp_file = MakeTempFile(os.path.basename(fn))
+ with open(tmp_file, "wb") as fp:
+ fp.write(zfp.read(fn))
+ return tmp_file
else:
+ if not os.path.isdir(input_file):
+ raise ValueError(
+ "Invalid input_file, accepted inputs are ZipFile object, path to .zip file on disk, or path to extracted directory. Actual: " + input_file)
file = os.path.join(input_file, *fn.split("/"))
if not os.path.exists(file):
raise KeyError(fn)
@@ -1494,12 +1503,14 @@
custom_partitions = OPTIONS.info_dict.get(
"avb_custom_images_partition_list", "").strip().split()
+ custom_avb_partitions = ["vbmeta_" + part for part in OPTIONS.info_dict.get("avb_custom_vbmeta_images_partition_list", "").strip().split()]
for partition, path in partitions.items():
if partition not in needed_partitions:
continue
assert (partition in AVB_PARTITIONS or
partition in AVB_VBMETA_PARTITIONS or
+ partition in custom_avb_partitions or
partition in custom_partitions), \
'Unknown partition: {}'.format(partition)
assert os.path.exists(path), \
@@ -2788,18 +2799,6 @@
def ZipWrite(zip_file, filename, arcname=None, perms=0o644,
compress_type=None):
- # http://b/18015246
- # Python 2.7's zipfile implementation wrongly thinks that zip64 is required
- # for files larger than 2GiB. We can work around this by adjusting their
- # limit. Note that `zipfile.writestr()` will not work for strings larger than
- # 2GiB. The Python interpreter sometimes rejects strings that large (though
- # it isn't clear to me exactly what circumstances cause this).
- # `zipfile.write()` must be used directly to work around this.
- #
- # This mess can be avoided if we port to python3.
- saved_zip64_limit = zipfile.ZIP64_LIMIT
- zipfile.ZIP64_LIMIT = (1 << 32) - 1
-
if compress_type is None:
compress_type = zip_file.compression
if arcname is None:
@@ -2825,14 +2824,13 @@
finally:
os.chmod(filename, saved_stat.st_mode)
os.utime(filename, (saved_stat.st_atime, saved_stat.st_mtime))
- zipfile.ZIP64_LIMIT = saved_zip64_limit
def ZipWriteStr(zip_file, zinfo_or_arcname, data, perms=None,
compress_type=None):
"""Wrap zipfile.writestr() function to work around the zip64 limit.
- Even with the ZIP64_LIMIT workaround, it won't allow writing a string
+ Python's zip implementation won't allow writing a string
longer than 2GiB. It gives 'OverflowError: size does not fit in an int'
when calling crc32(bytes).
@@ -2841,9 +2839,6 @@
when we know the string won't be too long.
"""
- saved_zip64_limit = zipfile.ZIP64_LIMIT
- zipfile.ZIP64_LIMIT = (1 << 32) - 1
-
if not isinstance(zinfo_or_arcname, zipfile.ZipInfo):
zinfo = zipfile.ZipInfo(filename=zinfo_or_arcname)
zinfo.compress_type = zip_file.compression
@@ -2876,7 +2871,6 @@
zinfo.date_time = (2009, 1, 1, 0, 0, 0)
zip_file.writestr(zinfo, data)
- zipfile.ZIP64_LIMIT = saved_zip64_limit
def ZipDelete(zip_filename, entries, force=False):
@@ -2910,18 +2904,6 @@
os.replace(new_zipfile, zip_filename)
-def ZipClose(zip_file):
- # http://b/18015246
- # zipfile also refers to ZIP64_LIMIT during close() when it writes out the
- # central directory.
- saved_zip64_limit = zipfile.ZIP64_LIMIT
- zipfile.ZIP64_LIMIT = (1 << 32) - 1
-
- zip_file.close()
-
- zipfile.ZIP64_LIMIT = saved_zip64_limit
-
-
class DeviceSpecificParams(object):
module = None
diff --git a/tools/releasetools/img_from_target_files.py b/tools/releasetools/img_from_target_files.py
index 76da89c..f8bdd81 100755
--- a/tools/releasetools/img_from_target_files.py
+++ b/tools/releasetools/img_from_target_files.py
@@ -173,7 +173,7 @@
logger.info('Writing super.img to archive...')
with zipfile.ZipFile(
output_file, 'a', compression=zipfile.ZIP_DEFLATED,
- allowZip64=not OPTIONS.sparse_userimages) as output_zip:
+ allowZip64=True) as output_zip:
common.ZipWrite(output_zip, super_file, 'super.img')
diff --git a/tools/releasetools/merge/merge_dexopt.py b/tools/releasetools/merge/merge_dexopt.py
index 7bf9bd4..16182b5 100644
--- a/tools/releasetools/merge/merge_dexopt.py
+++ b/tools/releasetools/merge/merge_dexopt.py
@@ -164,6 +164,10 @@
'deapexer',
'--debugfs_path',
'debugfs_static',
+ '--blkid_path',
+ 'blkid',
+ '--fsckerofs_path',
+ 'fsck.erofs',
'extract',
apex,
apex_extract_dir,
diff --git a/tools/releasetools/merge/merge_meta.py b/tools/releasetools/merge/merge_meta.py
index 580b3ce..3288ef7 100644
--- a/tools/releasetools/merge/merge_meta.py
+++ b/tools/releasetools/merge/merge_meta.py
@@ -52,6 +52,49 @@
MODULE_KEY_PATTERN = re.compile(r'name="(.+)\.(apex|apk)"')
+def ParseUpdateEngineConfig(path: str):
+ """Parse the update_engine config stored in file `path`
+ Args
+ path: Path to update_engine_config.txt file in target_files
+
+ Returns
+ A tuple of (major, minor) version number . E.g. (2, 8)
+ """
+ with open(path, "r") as fp:
+ # update_engine_config.txt is only supposed to contain two lines,
+ # PAYLOAD_MAJOR_VERSION and PAYLOAD_MINOR_VERSION. 1024 should be more than
+ # sufficient. If the length is more than that, something is wrong.
+ data = fp.read(1024)
+ major = re.search(r"PAYLOAD_MAJOR_VERSION=(\d+)", data)
+ if not major:
+ raise ValueError(
+ f"{path} is an invalid update_engine config, missing PAYLOAD_MAJOR_VERSION {data}")
+ minor = re.search(r"PAYLOAD_MINOR_VERSION=(\d+)", data)
+ if not minor:
+ raise ValueError(
+ f"{path} is an invalid update_engine config, missing PAYLOAD_MINOR_VERSION {data}")
+ return (int(major.group(1)), int(minor.group(1)))
+
+
+def MergeUpdateEngineConfig(input_metadir1, input_metadir2, merged_meta_dir):
+ UPDATE_ENGINE_CONFIG_NAME = "update_engine_config.txt"
+ config1_path = os.path.join(
+ input_metadir1, UPDATE_ENGINE_CONFIG_NAME)
+ config2_path = os.path.join(
+ input_metadir2, UPDATE_ENGINE_CONFIG_NAME)
+ config1 = ParseUpdateEngineConfig(config1_path)
+ config2 = ParseUpdateEngineConfig(config2_path)
+ # Copy older config to merged target files for maximum compatibility
+ # update_engine in system partition is from system side, but
+ # update_engine_sideload in recovery is from vendor side.
+ if config1 < config2:
+ shutil.copy(config1_path, os.path.join(
+ merged_meta_dir, UPDATE_ENGINE_CONFIG_NAME))
+ else:
+ shutil.copy(config2_path, os.path.join(
+ merged_meta_dir, UPDATE_ENGINE_CONFIG_NAME))
+
+
def MergeMetaFiles(temp_dir, merged_dir):
"""Merges various files in META/*."""
@@ -102,6 +145,11 @@
merged_meta_dir=merged_meta_dir,
file_name=file_name)
+ MergeUpdateEngineConfig(
+ framework_meta_dir,
+ vendor_meta_dir, merged_meta_dir,
+ )
+
# Write the now-finalized OPTIONS.merged_misc_info.
merge_utils.WriteSortedData(
data=OPTIONS.merged_misc_info,
diff --git a/tools/releasetools/merge/merge_utils.py b/tools/releasetools/merge/merge_utils.py
index e253b02..e056195 100644
--- a/tools/releasetools/merge/merge_utils.py
+++ b/tools/releasetools/merge/merge_utils.py
@@ -178,7 +178,6 @@
item_set.update([
'META/liblz4.so',
'META/postinstall_config.txt',
- 'META/update_engine_config.txt',
'META/zucchini_config.txt',
])
else: # vendor
diff --git a/tools/releasetools/merge/test_merge_utils.py b/tools/releasetools/merge/test_merge_utils.py
index eceb734..1ae1f54 100644
--- a/tools/releasetools/merge/test_merge_utils.py
+++ b/tools/releasetools/merge/test_merge_utils.py
@@ -142,7 +142,6 @@
'META/liblz4.so',
'META/postinstall_config.txt',
'META/product_filesystem_config.txt',
- 'META/update_engine_config.txt',
'META/zucchini_config.txt',
'PRODUCT/*',
'SYSTEM/*',
diff --git a/tools/releasetools/non_ab_ota.py b/tools/releasetools/non_ab_ota.py
index 6c927ec..7078d67 100644
--- a/tools/releasetools/non_ab_ota.py
+++ b/tools/releasetools/non_ab_ota.py
@@ -48,17 +48,12 @@
# if the filesystem is ext4.
partition_source_info = source_info["fstab"]["/" + name]
check_first_block = partition_source_info.fs_type == "ext4"
- # Disable using imgdiff for squashfs. 'imgdiff -z' expects input files to be
- # in zip formats. However with squashfs, a) all files are compressed in LZ4;
- # b) the blocks listed in block map may not contain all the bytes for a
- # given file (because they're rounded to be 4K-aligned).
- partition_target_info = target_info["fstab"]["/" + name]
- disable_imgdiff = (partition_source_info.fs_type == "squashfs" or
- partition_target_info.fs_type == "squashfs")
+ # Disable imgdiff because it relies on zlib to produce stable output
+ # across different versions, which is often not the case.
return common.BlockDifference(name, partition_tgt, partition_src,
check_first_block,
version=blockimgdiff_version,
- disable_imgdiff=disable_imgdiff)
+ disable_imgdiff=True)
if source_zip:
# See notes in common.GetUserImage()
@@ -277,12 +272,12 @@
# We haven't written the metadata entry, which will be done in
# FinalizeMetadata.
- common.ZipClose(output_zip)
+ output_zip.close()
needed_property_files = (
NonAbOtaPropertyFiles(),
)
- FinalizeMetadata(metadata, staging_file, output_file, needed_property_files)
+ FinalizeMetadata(metadata, staging_file, output_file, needed_property_files, package_key=OPTIONS.package_key)
def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_file):
@@ -409,7 +404,7 @@
if updating_boot:
boot_type, boot_device_expr = common.GetTypeAndDeviceExpr("/boot",
source_info)
- d = common.Difference(target_boot, source_boot)
+ d = common.Difference(target_boot, source_boot, "bsdiff")
_, _, d = d.ComputePatch()
if d is None:
include_full_boot = True
@@ -531,13 +526,13 @@
# We haven't written the metadata entry yet, which will be handled in
# FinalizeMetadata().
- common.ZipClose(output_zip)
+ output_zip.close()
# Sign the generated zip package unless no_signing is specified.
needed_property_files = (
NonAbOtaPropertyFiles(),
)
- FinalizeMetadata(metadata, staging_file, output_file, needed_property_files)
+ FinalizeMetadata(metadata, staging_file, output_file, needed_property_files, package_key=OPTIONS.package_key)
def GenerateNonAbOtaPackage(target_file, output_file, source_file=None):
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 9d5c67d..d6c39c6 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -205,7 +205,8 @@
--partial "<PARTITION> [<PARTITION>[...]]"
Generate partial updates, overriding ab_partitions list with the given
- list.
+ list. Specify --partial= without partition list to let tooling auto detect
+ partial partition list.
--custom_image <custom_partition=custom_image>
Use the specified custom_image to update custom_partition when generating
@@ -487,7 +488,7 @@
else:
common.ZipWrite(target_zip, unzipped_file, arcname=info.filename)
- common.ZipClose(target_zip)
+ target_zip.close()
return target_file
@@ -624,7 +625,7 @@
# TODO(xunchang) handle META/postinstall_config.txt'
- common.ZipClose(partial_target_zip)
+ partial_target_zip.close()
return partial_target_file
@@ -709,7 +710,7 @@
# Write new ab_partitions.txt file
common.ZipWrite(target_zip, new_ab_partitions, arcname=AB_PARTITIONS)
- common.ZipClose(target_zip)
+ target_zip.close()
return target_file
@@ -856,6 +857,31 @@
target_info = common.BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)
source_info = None
+ if OPTIONS.partial == []:
+ logger.info(
+ "Automatically detecting partial partition list from input target files.")
+ OPTIONS.partial = target_info.get(
+ "partial_ota_update_partitions_list").split()
+ assert OPTIONS.partial, "Input target_file does not have"
+ " partial_ota_update_partitions_list defined, failed to auto detect partial"
+ " partition list. Please specify list of partitions to update manually via"
+ " --partial=a,b,c , or generate a complete OTA by removing the --partial"
+ " option"
+ OPTIONS.partial.sort()
+ if source_info:
+ source_partial_list = source_info.get(
+ "partial_ota_update_partitions_list").split()
+ if source_partial_list:
+ source_partial_list.sort()
+ if source_partial_list != OPTIONS.partial:
+ logger.warning("Source build and target build have different partial partition lists. Source: %s, target: %s, taking the intersection.",
+ source_partial_list, OPTIONS.partial)
+ OPTIONS.partial = list(
+ set(OPTIONS.partial) and set(source_partial_list))
+ OPTIONS.partial.sort()
+ logger.info("Automatically deduced partial partition list: %s",
+ OPTIONS.partial)
+
if target_info.vendor_suppressed_vabc:
logger.info("Vendor suppressed VABC. Disabling")
OPTIONS.disable_vabc = True
@@ -1017,11 +1043,11 @@
common.ZipWriteStr(output_zip, "apex_info.pb", ota_apex_info,
compress_type=zipfile.ZIP_STORED)
- common.ZipClose(target_zip)
+ target_zip.close()
# We haven't written the metadata entry yet, which will be handled in
# FinalizeMetadata().
- common.ZipClose(output_zip)
+ output_zip.close()
FinalizeMetadata(metadata, staging_file, output_file,
package_key=OPTIONS.package_key)
@@ -1107,9 +1133,12 @@
elif o == "--boot_variable_file":
OPTIONS.boot_variable_file = a
elif o == "--partial":
- partitions = a.split()
- if not partitions:
- raise ValueError("Cannot parse partitions in {}".format(a))
+ if a:
+ partitions = a.split()
+ if not partitions:
+ raise ValueError("Cannot parse partitions in {}".format(a))
+ else:
+ partitions = []
OPTIONS.partial = partitions
elif o == "--custom_image":
custom_partition, custom_image = a.split("=")
@@ -1190,13 +1219,12 @@
"vabc_compression_param=",
"security_patch_level=",
], extra_option_handler=option_handler)
+ common.InitLogging()
if len(args) != 2:
common.Usage(__doc__)
sys.exit(1)
- common.InitLogging()
-
# Load the build info dicts from the zip directly or the extracted input
# directory. We don't need to unzip the entire target-files zips, because they
# won't be needed for A/B OTAs (brillo_update_payload does that on its own).
diff --git a/tools/releasetools/ota_utils.py b/tools/releasetools/ota_utils.py
index 9f41874..e2ce31d 100644
--- a/tools/releasetools/ota_utils.py
+++ b/tools/releasetools/ota_utils.py
@@ -22,7 +22,7 @@
import ota_metadata_pb2
import common
-from common import (ZipDelete, ZipClose, OPTIONS, MakeTempFile,
+from common import (ZipDelete, OPTIONS, MakeTempFile,
ZipWriteStr, BuildInfo, LoadDictionaryFromFile,
SignFile, PARTITIONS_WITH_BUILD_PROP, PartitionBuildProps,
GetRamdiskFormat)
@@ -132,8 +132,10 @@
# Re-sign the package after updating the metadata entry.
if no_signing:
+ logger.info(f"Signing disabled for output file {output_file}")
shutil.copy(prelim_signing, output_file)
else:
+ logger.info(f"Signing the output file {output_file} with key {package_key}")
SignOutput(prelim_signing, output_file, package_key, pw)
# Reopen the final signed zip to double check the streaming metadata.
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index d3fbdad..4a12e74 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -99,14 +99,14 @@
The second dir will be used for lookup if BOARD_USES_RECOVERY_AS_BOOT is
set to true.
- --avb_{boot,recovery,system,system_other,vendor,dtbo,vbmeta,vbmeta_system,
- vbmeta_vendor}_algorithm <algorithm>
- --avb_{boot,recovery,system,system_other,vendor,dtbo,vbmeta,vbmeta_system,
- vbmeta_vendor}_key <key>
+ --avb_{boot,init_boot,recovery,system,system_other,vendor,dtbo,vbmeta,
+ vbmeta_system,vbmeta_vendor}_algorithm <algorithm>
+ --avb_{boot,init_boot,recovery,system,system_other,vendor,dtbo,vbmeta,
+ vbmeta_system,vbmeta_vendor}_key <key>
Use the specified algorithm (e.g. SHA256_RSA4096) and the key to AVB-sign
the specified image. Otherwise it uses the existing values in info dict.
- --avb_{apex,boot,recovery,system,system_other,vendor,dtbo,vbmeta,
+ --avb_{apex,init_boot,boot,recovery,system,system_other,vendor,dtbo,vbmeta,
vbmeta_system,vbmeta_vendor}_extra_args <args>
Specify any additional args that are needed to AVB-sign the image
(e.g. "--signing_helper /path/to/helper"). The args will be appended to
@@ -531,7 +531,14 @@
# RECOVERY/RAMDISK/default.prop is a legacy path, but will always exist
# as a symlink in the current code. So it's a no-op here. Keeping the
# path here for clarity.
- "RECOVERY/RAMDISK/default.prop") or filename.endswith("build.prop")
+ # Some build props might be stored under path
+ # VENDOR_BOOT/RAMDISK_FRAGMENTS/recovery/RAMDISK/default.prop, and
+ # default.prop can be a symbolic link to prop.default, so overwrite all
+ # files that ends with build.prop, default.prop or prop.default
+ "RECOVERY/RAMDISK/default.prop") or \
+ filename.endswith("build.prop") or \
+ filename.endswith("/default.prop") or \
+ filename.endswith("/prop.default")
def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info,
@@ -901,7 +908,7 @@
certs_zip = zipfile.ZipFile(temp_file, "w", allowZip64=True)
for k in keys:
common.ZipWrite(certs_zip, k)
- common.ZipClose(certs_zip)
+ certs_zip.close()
common.ZipWriteStr(output_zip, filename, temp_file.getvalue())
@@ -1363,6 +1370,12 @@
OPTIONS.avb_algorithms['dtbo'] = a
elif o == "--avb_dtbo_extra_args":
OPTIONS.avb_extra_args['dtbo'] = a
+ elif o == "--avb_init_boot_key":
+ OPTIONS.avb_keys['init_boot'] = a
+ elif o == "--avb_init_boot_algorithm":
+ OPTIONS.avb_algorithms['init_boot'] = a
+ elif o == "--avb_init_boot_extra_args":
+ OPTIONS.avb_extra_args['init_boot'] = a
elif o == "--avb_recovery_key":
OPTIONS.avb_keys['recovery'] = a
elif o == "--avb_recovery_algorithm":
@@ -1458,6 +1471,9 @@
"avb_dtbo_algorithm=",
"avb_dtbo_key=",
"avb_dtbo_extra_args=",
+ "avb_init_boot_algorithm=",
+ "avb_init_boot_key=",
+ "avb_init_boot_extra_args=",
"avb_recovery_algorithm=",
"avb_recovery_key=",
"avb_recovery_extra_args=",
@@ -1529,8 +1545,8 @@
platform_api_level, codename_to_api_level_map,
compressed_extension)
- common.ZipClose(input_zip)
- common.ZipClose(output_zip)
+ input_zip.close()
+ output_zip.close()
if OPTIONS.vendor_partitions and OPTIONS.vendor_otatools:
BuildVendorPartitions(args[1])
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index 2a0e592..8c9655ad0 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -222,17 +222,17 @@
info_dict = copy.deepcopy(self.TEST_INFO_FINGERPRINT_DICT)
build_info = common.BuildInfo(info_dict)
self.assertEqual(
- 'product-brand/product-name/product-device:version-release/build-id/'
- 'version-incremental:build-type/build-tags', build_info.fingerprint)
+ 'product-brand/product-name/product-device:version-release/build-id/'
+ 'version-incremental:build-type/build-tags', build_info.fingerprint)
build_props = info_dict['build.prop'].build_props
del build_props['ro.build.id']
build_props['ro.build.legacy.id'] = 'legacy-build-id'
build_info = common.BuildInfo(info_dict, use_legacy_id=True)
self.assertEqual(
- 'product-brand/product-name/product-device:version-release/'
- 'legacy-build-id/version-incremental:build-type/build-tags',
- build_info.fingerprint)
+ 'product-brand/product-name/product-device:version-release/'
+ 'legacy-build-id/version-incremental:build-type/build-tags',
+ build_info.fingerprint)
self.assertRaises(common.ExternalError, common.BuildInfo, info_dict, None,
False)
@@ -241,9 +241,9 @@
info_dict['vbmeta_digest'] = 'abcde12345'
build_info = common.BuildInfo(info_dict, use_legacy_id=False)
self.assertEqual(
- 'product-brand/product-name/product-device:version-release/'
- 'legacy-build-id.abcde123/version-incremental:build-type/build-tags',
- build_info.fingerprint)
+ 'product-brand/product-name/product-device:version-release/'
+ 'legacy-build-id.abcde123/version-incremental:build-type/build-tags',
+ build_info.fingerprint)
def test___getitem__(self):
target_info = common.BuildInfo(self.TEST_INFO_DICT, None)
@@ -376,7 +376,7 @@
info_dict['build.prop'].build_props[
'ro.product.property_source_order'] = 'bad-source'
with self.assertRaisesRegexp(common.ExternalError,
- 'Invalid ro.product.property_source_order'):
+ 'Invalid ro.product.property_source_order'):
info = common.BuildInfo(info_dict, None)
info.GetBuildProp('ro.product.device')
@@ -459,7 +459,7 @@
time.sleep(5) # Make sure the atime/mtime will change measurably.
common.ZipWrite(zip_file, test_file_name, **extra_zipwrite_args)
- common.ZipClose(zip_file)
+ zip_file.close()
self._verify(zip_file, zip_file_name, arcname, sha1_hash.hexdigest(),
test_file_name, expected_stat, expected_mode,
@@ -494,7 +494,7 @@
expected_mode = extra_args.get("perms", zinfo_perms)
common.ZipWriteStr(zip_file, zinfo_or_arcname, contents, **extra_args)
- common.ZipClose(zip_file)
+ zip_file.close()
self._verify(zip_file, zip_file_name, arcname, sha1(contents).hexdigest(),
expected_mode=expected_mode,
@@ -536,7 +536,7 @@
common.ZipWrite(zip_file, test_file_name, **extra_args)
common.ZipWriteStr(zip_file, arcname_small, small, **extra_args)
- common.ZipClose(zip_file)
+ zip_file.close()
# Verify the contents written by ZipWrite().
self._verify(zip_file, zip_file_name, arcname_large,
@@ -551,12 +551,6 @@
os.remove(zip_file_name)
os.remove(test_file_name)
- def _test_reset_ZIP64_LIMIT(self, func, *args):
- default_limit = (1 << 31) - 1
- self.assertEqual(default_limit, zipfile.ZIP64_LIMIT)
- func(*args)
- self.assertEqual(default_limit, zipfile.ZIP64_LIMIT)
-
def test_ZipWrite(self):
file_contents = os.urandom(1024)
self._test_ZipWrite(file_contents)
@@ -581,7 +575,7 @@
})
def test_ZipWrite_resets_ZIP64_LIMIT(self):
- self._test_reset_ZIP64_LIMIT(self._test_ZipWrite, "")
+ self._test_ZipWrite("")
def test_ZipWriteStr(self):
random_string = os.urandom(1024)
@@ -632,9 +626,9 @@
})
def test_ZipWriteStr_resets_ZIP64_LIMIT(self):
- self._test_reset_ZIP64_LIMIT(self._test_ZipWriteStr, 'foo', b'')
+ self._test_ZipWriteStr('foo', b'')
zinfo = zipfile.ZipInfo(filename="foo")
- self._test_reset_ZIP64_LIMIT(self._test_ZipWriteStr, zinfo, b'')
+ self._test_ZipWriteStr(zinfo, b'')
def test_bug21309935(self):
zip_file = tempfile.NamedTemporaryFile(delete=False)
@@ -656,7 +650,7 @@
zinfo = zipfile.ZipInfo(filename="qux")
zinfo.external_attr = 0o700 << 16
common.ZipWriteStr(zip_file, zinfo, random_string, perms=0o400)
- common.ZipClose(zip_file)
+ zip_file.close()
self._verify(zip_file, zip_file_name, "foo",
sha1(random_string).hexdigest(),
@@ -683,7 +677,7 @@
common.ZipWrite(output_zip, entry_file.name, arcname='Test1')
common.ZipWrite(output_zip, entry_file.name, arcname='Test2')
common.ZipWrite(output_zip, entry_file.name, arcname='Test3')
- common.ZipClose(output_zip)
+ output_zip.close()
zip_file.close()
try:
@@ -731,8 +725,8 @@
common.ZipWrite(output_zip, entry_file.name, arcname='Foo3')
common.ZipWrite(output_zip, entry_file.name, arcname='Bar4')
common.ZipWrite(output_zip, entry_file.name, arcname='Dir5/Baz5')
- common.ZipClose(output_zip)
- common.ZipClose(output_zip)
+ output_zip.close()
+ output_zip.close()
return zip_file
@test_utils.SkipIfExternalToolsUnavailable()
@@ -819,9 +813,9 @@
)
APKCERTS_CERTMAP1 = {
- 'RecoveryLocalizer.apk' : 'certs/devkey',
- 'Settings.apk' : 'build/make/target/product/security/platform',
- 'TV.apk' : 'PRESIGNED',
+ 'RecoveryLocalizer.apk': 'certs/devkey',
+ 'Settings.apk': 'build/make/target/product/security/platform',
+ 'TV.apk': 'PRESIGNED',
}
APKCERTS_TXT2 = (
@@ -836,10 +830,10 @@
)
APKCERTS_CERTMAP2 = {
- 'Compressed1.apk' : 'certs/compressed1',
- 'Compressed2a.apk' : 'certs/compressed2',
- 'Compressed2b.apk' : 'certs/compressed2',
- 'Compressed3.apk' : 'certs/compressed3',
+ 'Compressed1.apk': 'certs/compressed1',
+ 'Compressed2a.apk': 'certs/compressed2',
+ 'Compressed2b.apk': 'certs/compressed2',
+ 'Compressed3.apk': 'certs/compressed3',
}
APKCERTS_TXT3 = (
@@ -848,7 +842,7 @@
)
APKCERTS_CERTMAP3 = {
- 'Compressed4.apk' : 'certs/compressed4',
+ 'Compressed4.apk': 'certs/compressed4',
}
# Test parsing with no optional fields, both optional fields, and only the
@@ -865,9 +859,9 @@
)
APKCERTS_CERTMAP4 = {
- 'RecoveryLocalizer.apk' : 'certs/devkey',
- 'Settings.apk' : 'build/make/target/product/security/platform',
- 'TV.apk' : 'PRESIGNED',
+ 'RecoveryLocalizer.apk': 'certs/devkey',
+ 'Settings.apk': 'build/make/target/product/security/platform',
+ 'TV.apk': 'PRESIGNED',
}
def setUp(self):
@@ -971,7 +965,7 @@
extracted_from_privkey = common.ExtractAvbPublicKey('avbtool', privkey)
extracted_from_pubkey = common.ExtractAvbPublicKey('avbtool', pubkey)
with open(extracted_from_privkey, 'rb') as privkey_fp, \
- open(extracted_from_pubkey, 'rb') as pubkey_fp:
+ open(extracted_from_pubkey, 'rb') as pubkey_fp:
self.assertEqual(privkey_fp.read(), pubkey_fp.read())
def test_ParseCertificate(self):
@@ -1235,7 +1229,8 @@
self.assertEqual(
'1-5 9-10',
sparse_image.file_map['//system/file1'].extra['text_str'])
- self.assertTrue(sparse_image.file_map['//system/file2'].extra['incomplete'])
+ self.assertTrue(
+ sparse_image.file_map['//system/file2'].extra['incomplete'])
self.assertTrue(
sparse_image.file_map['/system/app/file3'].extra['incomplete'])
@@ -1343,7 +1338,7 @@
'recovery_api_version': 3,
'fstab_version': 2,
'system_root_image': 'true',
- 'no_recovery' : 'true',
+ 'no_recovery': 'true',
'recovery_as_boot': 'true',
}
@@ -1664,6 +1659,7 @@
self.assertRaises(common.ExternalError, common._GenerateGkiCertificate,
test_file.name, 'generic_kernel')
+
class InstallRecoveryScriptFormatTest(test_utils.ReleaseToolsTestCase):
"""Checks the format of install-recovery.sh.
@@ -1673,7 +1669,7 @@
def setUp(self):
self._tempdir = common.MakeTempDir()
# Create a fake dict that contains the fstab info for boot&recovery.
- self._info = {"fstab" : {}}
+ self._info = {"fstab": {}}
fake_fstab = [
"/dev/soc.0/by-name/boot /boot emmc defaults defaults",
"/dev/soc.0/by-name/recovery /recovery emmc defaults defaults"]
@@ -2020,11 +2016,11 @@
input_zip, 'odm', placeholder_values)
self.assertEqual({
- 'ro.odm.build.date.utc': '1578430045',
- 'ro.odm.build.fingerprint':
- 'google/coral/coral:10/RP1A.200325.001/6337676:user/dev-keys',
- 'ro.product.odm.device': 'coral',
- 'ro.product.odm.name': 'product1',
+ 'ro.odm.build.date.utc': '1578430045',
+ 'ro.odm.build.fingerprint':
+ 'google/coral/coral:10/RP1A.200325.001/6337676:user/dev-keys',
+ 'ro.product.odm.device': 'coral',
+ 'ro.product.odm.name': 'product1',
}, partition_props.build_props)
with zipfile.ZipFile(input_file, 'r', allowZip64=True) as input_zip:
@@ -2207,8 +2203,8 @@
copied_props = copy.deepcopy(partition_props)
self.assertEqual({
- 'ro.odm.build.date.utc': '1578430045',
- 'ro.odm.build.fingerprint':
- 'google/coral/coral:10/RP1A.200325.001/6337676:user/dev-keys',
- 'ro.product.odm.device': 'coral',
+ 'ro.odm.build.date.utc': '1578430045',
+ 'ro.odm.build.fingerprint':
+ 'google/coral/coral:10/RP1A.200325.001/6337676:user/dev-keys',
+ 'ro.product.odm.device': 'coral',
}, copied_props.build_props)
diff --git a/tools/signapk/Android.bp b/tools/signapk/Android.bp
index bee6a6f..c4f25f8 100644
--- a/tools/signapk/Android.bp
+++ b/tools/signapk/Android.bp
@@ -31,6 +31,10 @@
"conscrypt-unbundled",
],
+ // b/267608166: Prevent target Java 17 so the host-side tool can run in an
+ // environment where JDK 11 is available.
+ java_version: "11",
+
jni_libs: ["libconscrypt_openjdk_jni"],
// The post-build signing tools need signapk.jar (and its shared libraries,
diff --git a/tools/soong_to_convert.py b/tools/soong_to_convert.py
index 949131b..649829f 100755
--- a/tools/soong_to_convert.py
+++ b/tools/soong_to_convert.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright (C) 2016 The Android Open Source Project
#
@@ -50,9 +50,6 @@
Not all problems can be discovered, but this is a starting point.
"""
-
-from __future__ import print_function
-
import csv
import sys
@@ -113,7 +110,7 @@
def main(filename):
"""Read the CSV file, print the results"""
- with open(filename, 'rb') as csvfile:
+ with open(filename, 'r') as csvfile:
results = process(csv.reader(csvfile))
native_results = filter(results, "native")
diff --git a/tools/stub_diff_analyzer.py b/tools/stub_diff_analyzer.py
new file mode 100644
index 0000000..e49d092
--- /dev/null
+++ b/tools/stub_diff_analyzer.py
@@ -0,0 +1,328 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2022 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.
+
+from sys import exit
+from typing import List
+from glob import glob
+from pathlib import Path
+from collections import defaultdict
+from difflib import Differ
+from re import split
+from tqdm import tqdm
+import argparse
+
+
+DIFFER_CODE_LEN = 2
+
+class DifferCodes:
+ COMMON = ' '
+ UNIQUE_FIRST = '- '
+ UNIQUE_SECOND = '+ '
+ DIFF_IDENT = '? '
+
+class FilesDiffAnalyzer:
+ def __init__(self, args) -> None:
+ self.out_dir = args.out_dir
+ self.show_diff = args.show_diff
+ self.skip_words = args.skip_words
+ self.first_dir = args.first_dir
+ self.second_dir = args.second_dir
+ self.include_common = args.include_common
+
+ self.first_dir_files = self.get_files(self.first_dir)
+ self.second_dir_files = self.get_files(self.second_dir)
+ self.common_file_map = defaultdict(set)
+
+ self.map_common_files(self.first_dir_files, self.first_dir)
+ self.map_common_files(self.second_dir_files, self.second_dir)
+
+ def get_files(self, dir: str) -> List[str]:
+ """Get all files directory in the input directory including the files in the subdirectories
+
+ Recursively finds all files in the input directory.
+ Returns a list of file directory strings, which do not include directories but only files.
+ List is sorted in alphabetical order of the file directories.
+
+ Args:
+ dir: Directory to get the files. String.
+
+ Returns:
+ A list of file directory strings within the input directory.
+ Sorted in Alphabetical order.
+
+ Raises:
+ FileNotFoundError: An error occurred accessing the non-existing directory
+ """
+
+ if not dir_exists(dir):
+ raise FileNotFoundError("Directory does not exist")
+
+ if dir[:-2] != "**":
+ if dir[:-1] != "/":
+ dir += "/"
+ dir += "**"
+
+ return [file for file in sorted(glob(dir, recursive=True)) if Path(file).is_file()]
+
+ def map_common_files(self, files: List[str], dir: str) -> None:
+ for file in files:
+ file_name = file.split(dir, 1)[-1]
+ self.common_file_map[file_name].add(dir)
+ return
+
+ def compare_file_contents(self, first_file: str, second_file: str) -> List[str]:
+ """Compare the contents of the files and return different lines
+
+ Given two file directory strings, compare the contents of the two files
+ and return the list of file contents string prepended with unique identifier codes.
+ The identifier codes include:
+ - ' '(two empty space characters): Line common to two files
+ - '- '(minus followed by a space) : Line unique to first file
+ - '+ '(plus followed by a space) : Line unique to second file
+
+ Args:
+ first_file: First file directory string to compare the content
+ second_file: Second file directory string to compare the content
+
+ Returns:
+ A list of the file content strings. For example:
+
+ [
+ " Foo",
+ "- Bar",
+ "+ Baz"
+ ]
+ """
+
+ d = Differ()
+ first_file_contents = sort_methods(get_file_contents(first_file))
+ second_file_contents = sort_methods(get_file_contents(second_file))
+ diff = list(d.compare(first_file_contents, second_file_contents))
+ ret = [f"diff {first_file} {second_file}"]
+
+ idx = 0
+ while idx < len(diff):
+ line = diff[idx]
+ line_code = line[:DIFFER_CODE_LEN]
+
+ match line_code:
+ case DifferCodes.COMMON:
+ if self.include_common:
+ ret.append(line)
+
+ case DifferCodes.UNIQUE_FIRST:
+ # Should compare line
+ if (idx < len(diff) - 1 and
+ (next_line_code := diff[idx + 1][:DIFFER_CODE_LEN])
+ not in (DifferCodes.UNIQUE_FIRST, DifferCodes.COMMON)):
+ delta = 1 if next_line_code == DifferCodes.UNIQUE_SECOND else 2
+ line_to_compare = diff[idx + delta]
+ if self.lines_differ(line, line_to_compare):
+ ret.extend([line, line_to_compare])
+ else:
+ if self.include_common:
+ ret.append(DifferCodes.COMMON +
+ line[DIFFER_CODE_LEN:])
+ idx += delta
+ else:
+ ret.append(line)
+
+ case DifferCodes.UNIQUE_SECOND:
+ ret.append(line)
+
+ case DifferCodes.DIFF_IDENT:
+ pass
+ idx += 1
+ return ret
+
+ def lines_differ(self, line1: str, line2: str) -> bool:
+ """Check if the input lines are different or not
+
+ Compare the two lines word by word and check if the two lines are different or not.
+ If the different words in the comparing lines are included in skip_words,
+ the lines are not considered different.
+
+ Args:
+ line1: first line to compare
+ line2: second line to compare
+
+ Returns:
+ Boolean value indicating if the two lines are different or not
+
+ """
+ # Split by '.' or ' '(whitespace)
+ def split_words(line: str) -> List[str]:
+ return split('\\s|\\.', line[DIFFER_CODE_LEN:])
+
+ line1_words, line2_words = split_words(line1), split_words(line2)
+ if len(line1_words) != len(line2_words):
+ return True
+
+ for word1, word2 in zip(line1_words, line2_words):
+ if word1 != word2:
+ # not check if words are equal to skip word, but
+ # check if words contain skip word as substring
+ if all(sw not in word1 and sw not in word2 for sw in self.skip_words):
+ return True
+
+ return False
+
+ def analyze(self) -> None:
+ """Analyze file contents in both directories and write to output or console.
+ """
+ for file in tqdm(sorted(self.common_file_map.keys())):
+ val = self.common_file_map[file]
+
+ # When file exists in both directories
+ lines = list()
+ if val == set([self.first_dir, self.second_dir]):
+ lines = self.compare_file_contents(
+ self.first_dir + file, self.second_dir + file)
+ else:
+ existing_dir, not_existing_dir = (
+ (self.first_dir, self.second_dir) if self.first_dir in val
+ else (self.second_dir, self.first_dir))
+
+ lines = [f"{not_existing_dir}{file} does not exist."]
+
+ if self.show_diff:
+ lines.append(f"Content of {existing_dir}{file}: \n")
+ lines.extend(get_file_contents(existing_dir + file))
+
+ self.write(lines)
+
+ def write(self, lines: List[str]) -> None:
+ if self.out_dir == "":
+ pprint(lines)
+ else:
+ write_lines(self.out_dir, lines)
+
+###
+# Helper functions
+###
+
+def sort_methods(lines: List[str]) -> List[str]:
+ """Sort class methods in the file contents by alphabetical order
+
+ Given lines of Java file contents, return lines with class methods sorted in alphabetical order.
+ Also omit empty lines or lines with spaces.
+ For example:
+ l = [
+ "package android.test;",
+ "",
+ "public static final int ORANGE = 1;",
+ "",
+ "public class TestClass {",
+ "public TestClass() { throw new RuntimeException("Stub!"); }",
+ "public void foo() { throw new RuntimeException("Stub!"); }",
+ "public void bar() { throw new RuntimeException("Stub!"); }",
+ "}"
+ ]
+ sort_methods(l) returns
+ [
+ "package android.test;",
+ "public static final int ORANGE = 1;",
+ "public class TestClass {",
+ "public TestClass() { throw new RuntimeException("Stub!"); }",
+ "public void bar() { throw new RuntimeException("Stub!"); }",
+ "public void foo() { throw new RuntimeException("Stub!"); }",
+ "}"
+ ]
+
+ Args:
+ lines: List of strings consisted of Java file contents.
+
+ Returns:
+ A list of string with sorted class methods.
+
+ """
+ def is_not_blank(l: str) -> bool:
+ return bool(l) and not l.isspace()
+
+ ret = list()
+
+ in_class = False
+ buffer = list()
+ for line in lines:
+ if not in_class:
+ if "class" in line:
+ in_class = True
+ ret.append(line)
+ else:
+ # Adding static variables, package info, etc.
+ # Skipping empty or space lines.
+ if is_not_blank(line):
+ ret.append(line)
+ else:
+ # End of class
+ if line and line[0] == "}":
+ in_class = False
+ ret.extend(sorted(buffer))
+ buffer = list()
+ ret.append(line)
+ else:
+ if is_not_blank(line):
+ buffer.append(line)
+
+ return ret
+
+def get_file_contents(file_path: str) -> List[str]:
+ lines = list()
+ with open(file_path) as f:
+ lines = [line.rstrip('\n') for line in f]
+ f.close()
+ return lines
+
+def pprint(l: List[str]) -> None:
+ for line in l:
+ print(line)
+
+def write_lines(out_dir: str, lines: List[str]) -> None:
+ with open(out_dir, "a") as f:
+ f.writelines(line + '\n' for line in lines)
+ f.write("\n")
+ f.close()
+
+def dir_exists(dir: str) -> bool:
+ return Path(dir).exists()
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('first_dir', action='store', type=str,
+ help="first path to compare file directory and contents")
+ parser.add_argument('second_dir', action='store', type=str,
+ help="second path to compare file directory and contents")
+ parser.add_argument('--out', dest='out_dir',
+ action='store', default="", type=str,
+ help="optional directory to write log. If not set, will print to console")
+ parser.add_argument('--show-diff-file', dest='show_diff',
+ action=argparse.BooleanOptionalAction,
+ help="optional flag. If passed, will print out the content of the file unique to each directories")
+ parser.add_argument('--include-common', dest='include_common',
+ action=argparse.BooleanOptionalAction,
+ help="optional flag. If passed, will print out the contents common to both files as well,\
+ instead of printing only diff lines.")
+ parser.add_argument('--skip-words', nargs='+',
+ dest='skip_words', default=[], help="optional words to skip in comparison")
+
+ args = parser.parse_args()
+
+ if not args.first_dir or not args.second_dir:
+ parser.print_usage()
+ exit(0)
+
+ analyzer = FilesDiffAnalyzer(args)
+ analyzer.analyze()
diff --git a/tools/warn/tidy_warn_patterns.py b/tools/warn/tidy_warn_patterns.py
index c138f1c..5ee66c0 100644
--- a/tools/warn/tidy_warn_patterns.py
+++ b/tools/warn/tidy_warn_patterns.py
@@ -224,6 +224,7 @@
analyzer_warn_check('clang-analyzer-valist.Unterminated'),
analyzer_group_check('clang-analyzer-core.uninitialized'),
analyzer_group_check('clang-analyzer-deadcode'),
+ analyzer_warn_check('clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling'),
analyzer_warn_check('clang-analyzer-security.insecureAPI.bcmp'),
analyzer_warn_check('clang-analyzer-security.insecureAPI.bcopy'),
analyzer_warn_check('clang-analyzer-security.insecureAPI.bzero'),
diff --git a/tools/whichgit b/tools/whichgit
index 24d6d87..b0bf2e4 100755
--- a/tools/whichgit
+++ b/tools/whichgit
@@ -95,11 +95,12 @@
# Print the list of git directories that has one or more of the sources in it
for project in sorted(get_referenced_projects(get_git_dirs(), sources)):
print(project)
- if "*" in args.why or project in args.why:
- prefix = project + "/"
- for f in sources:
- if f.startswith(prefix):
- print(" " + f)
+ if args.why:
+ if "*" in args.why or project in args.why:
+ prefix = project + "/"
+ for f in sources:
+ if f.startswith(prefix):
+ print(" " + f)
if __name__ == "__main__":
diff --git a/tools/zipalign/ZipEntry.cpp b/tools/zipalign/ZipEntry.cpp
index fcad96c..689999e 100644
--- a/tools/zipalign/ZipEntry.cpp
+++ b/tools/zipalign/ZipEntry.cpp
@@ -40,14 +40,10 @@
*/
status_t ZipEntry::initFromCDE(FILE* fp)
{
- status_t result;
- long posn; // NOLINT(google-runtime-int), for ftell/fseek
- bool hasDD;
-
//ALOGV("initFromCDE ---\n");
/* read the CDE */
- result = mCDE.read(fp);
+ status_t result = mCDE.read(fp);
if (result != OK) {
ALOGD("mCDE.read failed\n");
return result;
@@ -56,8 +52,8 @@
//mCDE.dump();
/* using the info in the CDE, go load up the LFH */
- posn = ftell(fp);
- if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {
+ off_t posn = ftello(fp);
+ if (fseeko(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {
ALOGD("local header seek failed (%" PRIu32 ")\n",
mCDE.mLocalHeaderRelOffset);
return UNKNOWN_ERROR;
@@ -69,7 +65,7 @@
return result;
}
- if (fseek(fp, posn, SEEK_SET) != 0)
+ if (fseeko(fp, posn, SEEK_SET) != 0)
return UNKNOWN_ERROR;
//mLFH.dump();
@@ -80,7 +76,7 @@
* compressed size, and uncompressed size will be zero. In practice
* these seem to be rare.
*/
- hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0;
+ bool hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0;
if (hasDD) {
// do something clever
//ALOGD("+++ has data descriptor\n");
diff --git a/tools/zipalign/ZipFile.cpp b/tools/zipalign/ZipFile.cpp
index f2f65a6..42cc349 100644
--- a/tools/zipalign/ZipFile.cpp
+++ b/tools/zipalign/ZipFile.cpp
@@ -35,6 +35,8 @@
#include <assert.h>
#include <inttypes.h>
+_Static_assert(sizeof(off_t) == 8, "off_t too small");
+
namespace android {
/*
@@ -205,56 +207,43 @@
*/
status_t ZipFile::readCentralDir(void)
{
- status_t result = OK;
- uint8_t* buf = NULL;
- off_t fileLength, seekStart;
- long readAmount;
- int i;
-
- fseek(mZipFp, 0, SEEK_END);
- fileLength = ftell(mZipFp);
+ fseeko(mZipFp, 0, SEEK_END);
+ off_t fileLength = ftello(mZipFp);
rewind(mZipFp);
/* too small to be a ZIP archive? */
if (fileLength < EndOfCentralDir::kEOCDLen) {
- ALOGD("Length is %ld -- too small\n", (long)fileLength);
- result = INVALID_OPERATION;
- goto bail;
+ ALOGD("Length is %lld -- too small\n", (long long) fileLength);
+ return INVALID_OPERATION;
}
- buf = new uint8_t[EndOfCentralDir::kMaxEOCDSearch];
- if (buf == NULL) {
- ALOGD("Failure allocating %d bytes for EOCD search",
- EndOfCentralDir::kMaxEOCDSearch);
- result = NO_MEMORY;
- goto bail;
- }
-
+ off_t seekStart;
+ size_t readAmount;
if (fileLength > EndOfCentralDir::kMaxEOCDSearch) {
seekStart = fileLength - EndOfCentralDir::kMaxEOCDSearch;
readAmount = EndOfCentralDir::kMaxEOCDSearch;
} else {
seekStart = 0;
- readAmount = (long) fileLength;
+ readAmount = fileLength;
}
- if (fseek(mZipFp, seekStart, SEEK_SET) != 0) {
- ALOGD("Failure seeking to end of zip at %ld", (long) seekStart);
- result = UNKNOWN_ERROR;
- goto bail;
+ if (fseeko(mZipFp, seekStart, SEEK_SET) != 0) {
+ ALOGD("Failure seeking to end of zip at %lld", (long long) seekStart);
+ return UNKNOWN_ERROR;
}
/* read the last part of the file into the buffer */
- if (fread(buf, 1, readAmount, mZipFp) != (size_t) readAmount) {
+ uint8_t buf[EndOfCentralDir::kMaxEOCDSearch];
+ if (fread(buf, 1, readAmount, mZipFp) != readAmount) {
if (feof(mZipFp)) {
- ALOGW("fread %ld bytes failed, unexpected EOF", readAmount);
+ ALOGW("fread %zu bytes failed, unexpected EOF", readAmount);
} else {
- ALOGW("fread %ld bytes failed, %s", readAmount, strerror(errno));
+ ALOGW("fread %zu bytes failed, %s", readAmount, strerror(errno));
}
- result = UNKNOWN_ERROR;
- goto bail;
+ return UNKNOWN_ERROR;
}
/* find the end-of-central-dir magic */
+ int i;
for (i = readAmount - 4; i >= 0; i--) {
if (buf[i] == 0x50 &&
ZipEntry::getLongLE(&buf[i]) == EndOfCentralDir::kSignature)
@@ -265,15 +254,14 @@
}
if (i < 0) {
ALOGD("EOCD not found, not Zip\n");
- result = INVALID_OPERATION;
- goto bail;
+ return INVALID_OPERATION;
}
/* extract eocd values */
- result = mEOCD.readBuf(buf + i, readAmount - i);
+ status_t result = mEOCD.readBuf(buf + i, readAmount - i);
if (result != OK) {
- ALOGD("Failure reading %ld bytes of EOCD values", readAmount - i);
- goto bail;
+ ALOGD("Failure reading %zu bytes of EOCD values", readAmount - i);
+ return result;
}
//mEOCD.dump();
@@ -281,8 +269,7 @@
mEOCD.mNumEntries != mEOCD.mTotalNumEntries)
{
ALOGD("Archive spanning not supported\n");
- result = INVALID_OPERATION;
- goto bail;
+ return INVALID_OPERATION;
}
/*
@@ -299,11 +286,10 @@
* The only thing we really need right now is the file comment, which
* we're hoping to preserve.
*/
- if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+ if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
ALOGD("Failure seeking to central dir offset %" PRIu32 "\n",
mEOCD.mCentralDirOffset);
- result = UNKNOWN_ERROR;
- goto bail;
+ return UNKNOWN_ERROR;
}
/*
@@ -318,7 +304,7 @@
if (result != OK) {
ALOGD("initFromCDE failed\n");
delete pEntry;
- goto bail;
+ return result;
}
mEntries.add(pEntry);
@@ -336,20 +322,16 @@
} else {
ALOGW("fread EOCD failed, %s", strerror(errno));
}
- result = INVALID_OPERATION;
- goto bail;
+ return INVALID_OPERATION;
}
if (ZipEntry::getLongLE(checkBuf) != EndOfCentralDir::kSignature) {
ALOGD("EOCD read check failed\n");
- result = UNKNOWN_ERROR;
- goto bail;
+ return UNKNOWN_ERROR;
}
ALOGV("+++ EOCD read check passed\n");
}
-bail:
- delete[] buf;
- return result;
+ return OK;
}
@@ -370,9 +352,8 @@
{
ZipEntry* pEntry = NULL;
status_t result = OK;
- long lfhPosn, startPosn, endPosn, uncompressedLen;
- FILE* inputFp = NULL;
- uint32_t crc;
+ off_t lfhPosn, startPosn, endPosn, uncompressedLen;
+ uint32_t crc = 0;
time_t modWhen;
if (mReadOnly)
@@ -389,13 +370,14 @@
if (getEntryByName(storageName) != NULL)
return ALREADY_EXISTS;
+ FILE* inputFp = NULL;
if (!data) {
inputFp = fopen(fileName, FILE_OPEN_RO);
if (inputFp == NULL)
return errnoToStatus(errno);
}
- if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+ if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
result = UNKNOWN_ERROR;
goto bail;
}
@@ -413,9 +395,9 @@
* as a place-holder. In theory the LFH isn't necessary, but in
* practice some utilities demand it.
*/
- lfhPosn = ftell(mZipFp);
+ lfhPosn = ftello(mZipFp);
pEntry->mLFH.write(mZipFp);
- startPosn = ftell(mZipFp);
+ startPosn = ftello(mZipFp);
/*
* Copy the data in, possibly compressing it as we go.
@@ -432,11 +414,11 @@
* to be set through an API call, but I don't expect our
* criteria to change over time.
*/
- long src = inputFp ? ftell(inputFp) : size;
- long dst = ftell(mZipFp) - startPosn;
+ off_t src = inputFp ? ftello(inputFp) : size;
+ off_t dst = ftello(mZipFp) - startPosn;
if (dst + (dst / 10) > src) {
- ALOGD("insufficient compression (src=%ld dst=%ld), storing\n",
- src, dst);
+ ALOGD("insufficient compression (src=%lld dst=%lld), storing\n",
+ (long long) src, (long long) dst);
failed = true;
}
}
@@ -444,7 +426,7 @@
if (failed) {
compressionMethod = ZipEntry::kCompressStored;
if (inputFp) rewind(inputFp);
- fseek(mZipFp, startPosn, SEEK_SET);
+ fseeko(mZipFp, startPosn, SEEK_SET);
/* fall through to kCompressStored case */
}
}
@@ -463,7 +445,7 @@
}
// currently seeked to end of file
- uncompressedLen = inputFp ? ftell(inputFp) : size;
+ uncompressedLen = inputFp ? ftello(inputFp) : size;
/*
* We could write the "Data Descriptor", but there doesn't seem to
@@ -471,7 +453,7 @@
*
* Update file offsets.
*/
- endPosn = ftell(mZipFp); // seeked to end of compressed data
+ endPosn = ftello(mZipFp); // seeked to end of compressed data
/*
* Success! Fill out new values.
@@ -489,7 +471,7 @@
/*
* Go back and write the LFH.
*/
- if (fseek(mZipFp, lfhPosn, SEEK_SET) != 0) {
+ if (fseeko(mZipFp, lfhPosn, SEEK_SET) != 0) {
result = UNKNOWN_ERROR;
goto bail;
}
@@ -522,7 +504,7 @@
// Calculate where the entry payload offset will end up if we were to write
// it as-is.
- uint64_t expectedPayloadOffset = ftell(mZipFp) +
+ uint64_t expectedPayloadOffset = ftello(mZipFp) +
android::ZipEntry::LocalFileHeader::kLFHLen +
pEntry->mLFH.mFileNameLength +
pEntry->mLFH.mExtraFieldLength;
@@ -548,7 +530,7 @@
{
ZipEntry* pEntry = NULL;
status_t result;
- long lfhPosn, endPosn;
+ off_t lfhPosn, endPosn;
if (mReadOnly)
return INVALID_OPERATION;
@@ -557,7 +539,7 @@
assert(mZipFp != NULL);
assert(mEntries.size() == mEOCD.mTotalNumEntries);
- if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+ if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
result = UNKNOWN_ERROR;
goto bail;
}
@@ -585,7 +567,7 @@
* Write the LFH. Since we're not recompressing the data, we already
* have all of the fields filled out.
*/
- lfhPosn = ftell(mZipFp);
+ lfhPosn = ftello(mZipFp);
pEntry->mLFH.write(mZipFp);
/*
@@ -595,8 +577,7 @@
* fields as well. This is a fixed-size area immediately following
* the data.
*/
- if (fseek(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0)
- {
+ if (fseeko(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0) {
result = UNKNOWN_ERROR;
goto bail;
}
@@ -617,7 +598,7 @@
/*
* Update file offsets.
*/
- endPosn = ftell(mZipFp);
+ endPosn = ftello(mZipFp);
/*
* Success! Fill out new values.
@@ -654,7 +635,7 @@
{
ZipEntry* pEntry = NULL;
status_t result;
- long lfhPosn, uncompressedLen;
+ off_t lfhPosn, uncompressedLen;
if (mReadOnly)
return INVALID_OPERATION;
@@ -663,7 +644,7 @@
assert(mZipFp != NULL);
assert(mEntries.size() == mEOCD.mTotalNumEntries);
- if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+ if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
result = UNKNOWN_ERROR;
goto bail;
}
@@ -688,7 +669,7 @@
* as a place-holder. In theory the LFH isn't necessary, but in
* practice some utilities demand it.
*/
- lfhPosn = ftell(mZipFp);
+ lfhPosn = ftello(mZipFp);
pEntry->mLFH.write(mZipFp);
/*
@@ -698,8 +679,7 @@
* fields as well. This is a fixed-size area immediately following
* the data.
*/
- if (fseek(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0)
- {
+ if (fseeko(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0) {
result = UNKNOWN_ERROR;
goto bail;
}
@@ -712,7 +692,7 @@
result = NO_MEMORY;
goto bail;
}
- long startPosn = ftell(mZipFp);
+ off_t startPosn = ftello(mZipFp);
uint32_t crc;
if (compressFpToFp(mZipFp, NULL, buf, uncompressedLen, &crc) != OK) {
ALOGW("recompress of '%s' failed\n", pEntry->mCDE.mFileName);
@@ -720,13 +700,12 @@
free(buf);
goto bail;
}
- long endPosn = ftell(mZipFp);
+ off_t endPosn = ftello(mZipFp);
pEntry->setDataInfo(uncompressedLen, endPosn - startPosn,
pSourceEntry->getCRC32(), ZipEntry::kCompressDeflated);
free(buf);
} else {
- off_t copyLen;
- copyLen = pSourceEntry->getCompressedLen();
+ off_t copyLen = pSourceEntry->getCompressedLen();
if ((pSourceEntry->mLFH.mGPBitFlag & ZipEntry::kUsesDataDescr) != 0)
copyLen += ZipEntry::kDataDescriptorLen;
@@ -746,12 +725,12 @@
mEOCD.mNumEntries++;
mEOCD.mTotalNumEntries++;
mEOCD.mCentralDirSize = 0; // mark invalid; set by flush()
- mEOCD.mCentralDirOffset = ftell(mZipFp);
+ mEOCD.mCentralDirOffset = ftello(mZipFp);
/*
* Go back and write the LFH.
*/
- if (fseek(mZipFp, lfhPosn, SEEK_SET) != 0) {
+ if (fseeko(mZipFp, lfhPosn, SEEK_SET) != 0) {
result = UNKNOWN_ERROR;
goto bail;
}
@@ -978,7 +957,7 @@
status_t ZipFile::flush(void)
{
status_t result = OK;
- long eocdPosn;
+ off_t eocdPosn;
int i, count;
if (mReadOnly)
@@ -992,8 +971,7 @@
if (result != OK)
return result;
- if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0)
- return UNKNOWN_ERROR;
+ if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) return UNKNOWN_ERROR;
count = mEntries.size();
for (i = 0; i < count; i++) {
@@ -1001,7 +979,7 @@
pEntry->mCDE.write(mZipFp);
}
- eocdPosn = ftell(mZipFp);
+ eocdPosn = ftello(mZipFp);
mEOCD.mCentralDirSize = eocdPosn - mEOCD.mCentralDirOffset;
mEOCD.write(mZipFp);
@@ -1011,8 +989,8 @@
* with plain files, or if we deleted some entries, there's a lot
* of wasted space at the end of the file. Remove it now.
*/
- if (ftruncate(fileno(mZipFp), ftell(mZipFp)) != 0) {
- ALOGW("ftruncate failed %ld: %s\n", ftell(mZipFp), strerror(errno));
+ if (ftruncate(fileno(mZipFp), ftello(mZipFp)) != 0) {
+ ALOGW("ftruncate failed %lld: %s\n", (long long) ftello(mZipFp), strerror(errno));
// not fatal
}
@@ -1141,32 +1119,32 @@
if (getSize > n)
getSize = n;
- if (fseek(fp, (long) src, SEEK_SET) != 0) {
- ALOGW("filemove src seek %ld failed, %s",
- (long) src, strerror(errno));
+ if (fseeko(fp, src, SEEK_SET) != 0) {
+ ALOGW("filemove src seek %lld failed, %s",
+ (long long) src, strerror(errno));
return UNKNOWN_ERROR;
}
if (fread(readBuf, 1, getSize, fp) != getSize) {
if (feof(fp)) {
- ALOGW("fread %zu bytes off=%ld failed, unexpected EOF",
- getSize, (long) src);
+ ALOGW("fread %zu bytes off=%lld failed, unexpected EOF",
+ getSize, (long long) src);
} else {
- ALOGW("fread %zu bytes off=%ld failed, %s",
- getSize, (long) src, strerror(errno));
+ ALOGW("fread %zu bytes off=%lld failed, %s",
+ getSize, (long long) src, strerror(errno));
}
return UNKNOWN_ERROR;
}
- if (fseek(fp, (long) dst, SEEK_SET) != 0) {
- ALOGW("filemove dst seek %ld failed, %s",
- (long) dst, strerror(errno));
+ if (fseeko(fp, dst, SEEK_SET) != 0) {
+ ALOGW("filemove dst seek %lld failed, %s",
+ (long long) dst, strerror(errno));
return UNKNOWN_ERROR;
}
if (fwrite(readBuf, 1, getSize, fp) != getSize) {
- ALOGW("filemove write %zu off=%ld failed, %s",
- getSize, (long) dst, strerror(errno));
+ ALOGW("filemove write %zu off=%lld failed, %s",
+ getSize, (long long) dst, strerror(errno));
return UNKNOWN_ERROR;
}
@@ -1263,10 +1241,10 @@
bool ReadAtOffset(uint8_t* buf, size_t len, off64_t offset) const {
// Data is usually requested sequentially, so this helps avoid pointless
- // fseeks every time we perform a read. There's an impedence mismatch
+ // seeks every time we perform a read. There's an impedence mismatch
// here because the original API was designed around pread and pwrite.
if (offset != current_offset_) {
- if (fseek(fp_, offset, SEEK_SET) != 0) {
+ if (fseeko(fp_, offset, SEEK_SET) != 0) {
return false;
}
@@ -1298,10 +1276,10 @@
return NULL;
}
- fseek(mZipFp, 0, SEEK_SET);
+ fseeko(mZipFp, 0, SEEK_SET);
off_t offset = entry->getFileOffset();
- if (fseek(mZipFp, offset, SEEK_SET) != 0) {
+ if (fseeko(mZipFp, offset, SEEK_SET) != 0) {
goto bail;
}
diff --git a/tools/ziptime/ZipEntry.cpp b/tools/ziptime/ZipEntry.cpp
index e7b52ed..c8eb377 100644
--- a/tools/ziptime/ZipEntry.cpp
+++ b/tools/ziptime/ZipEntry.cpp
@@ -43,19 +43,16 @@
*/
status_t ZipEntry::initAndRewriteFromCDE(FILE* fp)
{
- status_t result;
- long posn;
-
/* read the CDE */
- result = mCDE.rewrite(fp);
+ status_t result = mCDE.rewrite(fp);
if (result != 0) {
LOG("mCDE.rewrite failed\n");
return result;
}
/* using the info in the CDE, go load up the LFH */
- posn = ftell(fp);
- if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {
+ off_t posn = ftello(fp);
+ if (fseeko(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {
LOG("local header seek failed (%" PRIu32 ")\n",
mCDE.mLocalHeaderRelOffset);
return -1;
@@ -67,7 +64,7 @@
return result;
}
- if (fseek(fp, posn, SEEK_SET) != 0)
+ if (fseeko(fp, posn, SEEK_SET) != 0)
return -1;
return 0;
diff --git a/tools/ziptime/ZipFile.cpp b/tools/ziptime/ZipFile.cpp
index 1d111af..3002a65 100644
--- a/tools/ziptime/ZipFile.cpp
+++ b/tools/ziptime/ZipFile.cpp
@@ -40,8 +40,7 @@
/* open the file */
mZipFp = fopen(zipFileName, "r+b");
if (mZipFp == NULL) {
- int err = errno;
- LOG("fopen failed: %d\n", err);
+ LOG("fopen \"%s\" failed: %s\n", zipFileName, strerror(errno));
return -1;
}
@@ -72,52 +71,39 @@
*/
status_t ZipFile::rewriteCentralDir(void)
{
- status_t result = 0;
- uint8_t* buf = NULL;
- off_t fileLength, seekStart;
- long readAmount;
- int i;
-
- fseek(mZipFp, 0, SEEK_END);
- fileLength = ftell(mZipFp);
+ fseeko(mZipFp, 0, SEEK_END);
+ off_t fileLength = ftello(mZipFp);
rewind(mZipFp);
/* too small to be a ZIP archive? */
if (fileLength < EndOfCentralDir::kEOCDLen) {
- LOG("Length is %ld -- too small\n", (long)fileLength);
- result = -1;
- goto bail;
+ LOG("Length is %lld -- too small\n", (long long) fileLength);
+ return -1;
}
- buf = new uint8_t[EndOfCentralDir::kMaxEOCDSearch];
- if (buf == NULL) {
- LOG("Failure allocating %d bytes for EOCD search",
- EndOfCentralDir::kMaxEOCDSearch);
- result = -1;
- goto bail;
- }
-
+ off_t seekStart;
+ size_t readAmount;
if (fileLength > EndOfCentralDir::kMaxEOCDSearch) {
seekStart = fileLength - EndOfCentralDir::kMaxEOCDSearch;
readAmount = EndOfCentralDir::kMaxEOCDSearch;
} else {
seekStart = 0;
- readAmount = (long) fileLength;
+ readAmount = fileLength;
}
- if (fseek(mZipFp, seekStart, SEEK_SET) != 0) {
- LOG("Failure seeking to end of zip at %ld", (long) seekStart);
- result = -1;
- goto bail;
+ if (fseeko(mZipFp, seekStart, SEEK_SET) != 0) {
+ LOG("Failure seeking to end of zip at %lld", (long long) seekStart);
+ return -1;
}
/* read the last part of the file into the buffer */
- if (fread(buf, 1, readAmount, mZipFp) != (size_t) readAmount) {
- LOG("short file? wanted %ld\n", readAmount);
- result = -1;
- goto bail;
+ uint8_t buf[EndOfCentralDir::kMaxEOCDSearch];
+ if (fread(buf, 1, readAmount, mZipFp) != readAmount) {
+ LOG("short file? wanted %zu\n", readAmount);
+ return -1;
}
/* find the end-of-central-dir magic */
+ int i;
for (i = readAmount - 4; i >= 0; i--) {
if (buf[i] == 0x50 &&
ZipEntry::getLongLE(&buf[i]) == EndOfCentralDir::kSignature)
@@ -127,15 +113,14 @@
}
if (i < 0) {
LOG("EOCD not found, not Zip\n");
- result = -1;
- goto bail;
+ return -1;
}
/* extract eocd values */
- result = mEOCD.readBuf(buf + i, readAmount - i);
+ status_t result = mEOCD.readBuf(buf + i, readAmount - i);
if (result != 0) {
- LOG("Failure reading %ld bytes of EOCD values", readAmount - i);
- goto bail;
+ LOG("Failure reading %zu bytes of EOCD values", readAmount - i);
+ return result;
}
/*
@@ -152,49 +137,39 @@
* The only thing we really need right now is the file comment, which
* we're hoping to preserve.
*/
- if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+ if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
LOG("Failure seeking to central dir offset %" PRIu32 "\n",
mEOCD.mCentralDirOffset);
- result = -1;
- goto bail;
+ return -1;
}
/*
* Loop through and read the central dir entries.
*/
- int entry;
- for (entry = 0; entry < mEOCD.mTotalNumEntries; entry++) {
+ for (int entry = 0; entry < mEOCD.mTotalNumEntries; entry++) {
ZipEntry* pEntry = new ZipEntry;
-
result = pEntry->initAndRewriteFromCDE(mZipFp);
+ delete pEntry;
if (result != 0) {
LOG("initFromCDE failed\n");
- delete pEntry;
- goto bail;
+ return -1;
}
-
- delete pEntry;
}
-
/*
* If all went well, we should now be back at the EOCD.
*/
uint8_t checkBuf[4];
if (fread(checkBuf, 1, 4, mZipFp) != 4) {
LOG("EOCD check read failed\n");
- result = -1;
- goto bail;
+ return -1;
}
if (ZipEntry::getLongLE(checkBuf) != EndOfCentralDir::kSignature) {
LOG("EOCD read check failed\n");
- result = -1;
- goto bail;
+ return -1;
}
-bail:
- delete[] buf;
- return result;
+ return 0;
}
/*