# # Copyright (C) 2008 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. #
# --------------------------------------------------------------- # Generic functions # TODO: Move these to definitions.make once we're able to include # definitions.make before config.make.
########################################################### ## Return non-empty if $(1) is a C identifier; i.e., if it ## matches /^[a-zA-Z_][a-zA-Z0-9_]*$/. We do this by first ## making sure that it isn't empty and doesn't start with ## a digit, then by removing each valid character. If the ## final result is empty, then it was a valid C identifier. ## ## $(1): word to check ###########################################################
_ici_digits := 0123456789
_ici_alphaunderscore := \
a b c d e f g h i j k l m n o p q r s t u v w x y z \
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ define is-c-identifier
$(strip \
$(if $(1), \
$(if $(filter $(addsuffix %,$(_ici_digits)),$(1)), \
, \
$(eval w := $(1)) \
$(foreach c,$(_ici_digits) $(_ici_alphaunderscore), \
$(eval w := $(subst $(c),,$(w))) \
) \
$(if $(w),,TRUE) \
$(eval w :=) \
) \
) \
) endef
# TODO: push this into the combo files; unfortunately, we don't even # know HOST_OS at this point.
trysed := $(shell echo a | sed -E -e 's/a/b/'2>/dev/null) ifeq ($(trysed),b)
SED_EXTENDED := sed -E else
trysed := $(shell echo c | sed -r -e 's/c/d/'2>/dev/null) ifeq ($(trysed),d)
SED_EXTENDED := sed -r else
$(error Unknown sed version) endif endif
########################################################### ## List all of the files in a subdirectory in a format ## suitable for PRODUCT_COPY_FILES and ## PRODUCT_SDK_ADDON_COPY_FILES ## ## $(1): Glob to match file name ## $(2): Source directory ## $(3): Target base directory ###########################################################
define find-copy-subdir-files
$(shell find $(2) -name "$(1)" -type f | $(SED_EXTENDED) "s:($(2)/?(.*)):\\1\\:$(3)/\\2:"| sed "s://:/:g" | sort) endef
# # Convert file file to the PRODUCT_COPY_FILES/PRODUCT_SDK_ADDON_COPY_FILES # format: for each file F return $(F):$(PREFIX)/$(notdir $(F)) # $(1): files list # $(2): prefix
# # Convert the list of file names to the list of PRODUCT_COPY_FILES items # $(1): from pattern # $(2): to pattern # $(3): file names # E.g., calling product-copy-files-by-pattern with # (from/%, to/%, a b) # returns # from/a:to/a from/b:to/b define product-copy-files-by-pattern
$(join $(patsubst %,$(1),$(3)),$(patsubst %,:$(2),$(3))) endef
# Return empty unless the board is in the list define is-board-platform-in-list2
$(filter $(1),$(TARGET_BOARD_PLATFORM)) endef
# Return empty unless the board is QCOM define is-vendor-board-qcom
$(if $(strip $(TARGET_BOARD_PLATFORM) $(QCOM_BOARD_PLATFORMS)),$(filter $(TARGET_BOARD_PLATFORM),$(QCOM_BOARD_PLATFORMS)),\
$(error both TARGET_BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) and QCOM_BOARD_PLATFORMS=$(QCOM_BOARD_PLATFORMS))) endef
# --------------------------------------------------------------- # Check for obsolete PRODUCT- and APP- goals ifeq ($(CALLED_FROM_SETUP),true)
product_goals := $(strip $(filter PRODUCT-%,$(MAKECMDGOALS)))
ifdef product_goals
$(error The PRODUCT-* goal is no longer supported. Use `TARGET_PRODUCT=<product> m droid` instead) endif
unbundled_goals := $(strip $(filter APP-%,$(MAKECMDGOALS)))
ifdef unbundled_goals
$(error The APP-* goal is no longer supported. Use `TARGET_BUILD_APPS="<app>" m droid` instead) endif# unbundled_goals endif
# Default to building dalvikvm on hosts that support it... ifeq ($(HOST_OS),linux) # ... or if the if the option is already set ifeq ($(WITH_HOST_DALVIK),)
WITH_HOST_DALVIK := true endif endif
# --------------------------------------------------------------- # Include the product definitions. # We need to do this to translate TARGET_PRODUCT into its # underlying TARGET_DEVICE before we start defining any rules. # include $(BUILD_SYSTEM)/node_fns.mk include $(BUILD_SYSTEM)/product.mk
# Read all product definitions. # # Products are defined in AndroidProducts.mk files:
android_products_makefiles := $(file <$(OUT_DIR)/.module_paths/AndroidProducts.mk.list) \
$(SRC_TARGET_DIR)/product/AndroidProducts.mk
# An AndroidProduct.mk file sets the following variables: # PRODUCT_MAKEFILES specifies product makefiles. Each item in this list # is either a <product>:path/to/file.mk, or just path/to/<product.mk> # COMMON_LUNCH_CHOICES specifies <product>-<variant> values to be shown # in the `lunch` menu # STARLARK_OPT_IN_PRODUCTS specifies products to use Starlark-based # product configuration by default
# Builds a list of first/second elements of each pair: # $(call _first,a:A b:B,:) returns 'a b' # $(call _second,a-A b-B,-) returns 'A B'
_first=$(filter-out $(2)%,$(subst $(2),$(space)$(2),$(1)))
_second=$(filter-out %$(2),$(subst $(2),$(2)$(space),$(1)))
# Returns <product>:<path> pair from a PRODUCT_MAKEFILE item. # If an item is <product>:path/to/file.mk, return it as is, # otherwise assume that an item is path/to/<product>.mk and # return <product>:path/to/<product>.mk
_product-spec=$(strip $(if $(findstring :,$(1)),$(1),$(basename $(notdir $(1))):$(1)))
# Reads given AndroidProduct.mk file and sets the following variables: # ap_product_paths -- the list of <product>:<path> pairs # ap_common_lunch_choices -- the list of <product>-<build variant> items # ap_products_using_starlark_config -- the list of products using starlark config # In addition, validates COMMON_LUNCH_CHOICES and STARLARK_OPT_IN_PRODUCTS values define _read-ap-file
$(eval PRODUCT_MAKEFILES :=) \
$(eval COMMON_LUNCH_CHOICES :=) \
$(eval STARLARK_OPT_IN_PRODUCTS := ) \
$(eval ap_product_paths :=) \
$(eval LOCAL_DIR := $(patsubst %/,%,$(dir $(f)))) \
$(evalinclude $(f)) \
$(foreach p, $(PRODUCT_MAKEFILES),$(eval ap_product_paths += $(call _product-spec,$(p)))) \
$(eval ap_common_lunch_choices := $(COMMON_LUNCH_CHOICES)) \
$(eval ap_products_using_starlark_config := $(STARLARK_OPT_IN_PRODUCTS)) \
$(eval _products := $(call _first,$(ap_product_paths),:)) \
$(eval _bad := $(filter-out $(_products),$(call _first,$(ap_common_lunch_choices),-))) \
$(if $(_bad),$(error COMMON_LUNCH_CHOICES contains products(s) not defined in this file: $(_bad))) \
$(eval _bad := $(filter-out %-eng %-userdebug %-user,$(ap_common_lunch_choices))) \
$(if $(_bad),$(error invalid variant in COMMON_LUNCH_CHOICES: $(_bad)))
$(eval _bad := $(filter-out $(_products),$(ap_products_using_starlark_config))) \
$(if $(_bad),$(error STARLARK_OPT_IN_PRODUCTS contains product(s) not defined in this file: $(_bad))) endef
# Check that there are no duplicate product names
$(foreach p,$(all_named_products), \
$(if $(filter 1,$(words $(filter $(p):%,$(product_paths)))),, \
$(error Product name must be unique, "$(p)" used by $(call _second,$(filter $(p):%,$(product_paths)),:))))
include $(OUT_DIR)/rbc/rbc_product_config_results.mk endif
# This step was already handled in the RBC product configuration. ifeq ($(RBC_PRODUCT_CONFIG)$(SKIP_ARTIFACT_PATH_REQUIREMENT_PRODUCTS_CHECK),) # Import all the products that have made artifact path requirements, so that we can verify # the artifacts they produce. They might be intermediate makefiles instead of real products.
$(foreach makefile,$(ARTIFACT_PATH_REQUIREMENT_PRODUCTS),\
$(if $(filter-out $(makefile),$(PRODUCTS)),$(eval $(callimport-products,$(makefile))))\
) endif
INTERNAL_PRODUCT := $(current_product_makefile) # Strip and assign the PRODUCT_ variables.
$(call strip-product-vars)
# AOSP and Google products currently share the same `apex_contributions` in next. # This causes issues when building <aosp_product>-next-userdebug in main. # Create a temporary allowlist to ignore the google apexes listed in `contents` of apex_contributions of `next` # *for aosp products*. # TODO(b/308187268): Remove this denylist mechanism # Use PRODUCT_PACKAGES to determine if this is an aosp product. aosp products do not use google signed apexes.
ignore_apex_contributions := ifeq (,$(filter com.google.android.conscrypt% com.google.android.go.conscrypt% com.google.android.extservices% com.google.android.go.extservices%,$(PRODUCT_PACKAGES)))
ignore_apex_contributions := true endif ifeq (true,$(PRODUCT_MODULE_BUILD_FROM_SOURCE))
ignore_apex_contributions := true endif ifneq ($(EMMA_INSTRUMENT)$(EMMA_INSTRUMENT_STATIC)$(EMMA_INSTRUMENT_FRAMEWORK)$(CLANG_COVERAGE)$(NATIVE_COVERAGE_PATHS),) # Coverage builds for TARGET_RELEASE=foo should always build from source, # even if TARGET_RELEASE=foo uses prebuilt mainline modules. # This is necessary because the checked-in prebuilts were generated with # instrumentation turned off.
ignore_apex_contributions := true endif
# Allow overriding PLATFORM_BASE_OS when PRODUCT_BASE_OS is defined
ifdef PRODUCT_BASE_OS
PLATFORM_BASE_OS := $(PRODUCT_BASE_OS) else
PLATFORM_BASE_OS := $(PLATFORM_BASE_OS_ENV_INPUT) endif
.KATI_READONLY := PLATFORM_BASE_OS
# TODO: also keep track of things like "port", "land" in product files.
# Figure out which resoure configuration options to use for this # product. # If CUSTOM_LOCALES contains any locales not already included # in PRODUCT_LOCALES, add them to PRODUCT_LOCALES.
extra_locales := $(filter-out $(PRODUCT_LOCALES),$(CUSTOM_LOCALES)) ifneq (,$(extra_locales)) ifneq ($(CALLED_FROM_SETUP),true) # Don't spam stdout, because envsetup.sh may be scraping values from it.
$(info Adding CUSTOM_LOCALES [$(extra_locales)] to PRODUCT_LOCALES [$(PRODUCT_LOCALES)]) endif
PRODUCT_LOCALES += $(extra_locales)
extra_locales := endif
# Add PRODUCT_LOCALES to PRODUCT_AAPT_CONFIG
PRODUCT_AAPT_CONFIG := $(PRODUCT_LOCALES) $(PRODUCT_AAPT_CONFIG)
# Keep a copy of the space-separated config
PRODUCT_AAPT_CONFIG_SP := $(PRODUCT_AAPT_CONFIG)
PRODUCT_AAPT_CONFIG := $(subst $(space),$(comma),$(PRODUCT_AAPT_CONFIG))
########################################################### ## Add 'platform:' prefix to jars not in <apex>:<module> format. ## ## This makes sure that a jar corresponds to ConfigureJarList format of <apex> and <module> pairs ## where needed. ## ## $(1): a list of jars either in <module> or <apex>:<module> format ###########################################################
# b/191127295: force core-icu4j onto boot image. It comes from a non-updatable APEX jar, but has # historically been part of the boot image; even though APEX jars are not meant to be part of the # boot image. # TODO(b/191686720): remove PRODUCT_APEX_BOOT_JARS to avoid a special handling of core-icu4j # in make rules.
PRODUCT_APEX_BOOT_JARS := $(filter-out com.android.i18n:core-icu4j,$(PRODUCT_APEX_BOOT_JARS)) # All APEX jars come after /system and /system_ext jars, so adding core-icu4j at the end of the list
PRODUCT_BOOT_JARS += com.android.i18n:core-icu4j
# The extra system server jars must be appended at the end after common system server jars.
PRODUCT_SYSTEM_SERVER_JARS += $(PRODUCT_SYSTEM_SERVER_JARS_EXTRA)
# Sort APEX boot and system server jars. We use deterministic alphabetical order # when constructing BOOTCLASSPATH and SYSTEMSERVERCLASSPATH definition on device # after an update. Enforce it in the build system as well to avoid recompiling # everything after an update due a change in the order.
PRODUCT_APEX_BOOT_JARS := $(sort $(PRODUCT_APEX_BOOT_JARS))
PRODUCT_APEX_SYSTEM_SERVER_JARS := $(sort $(PRODUCT_APEX_SYSTEM_SERVER_JARS))
ifdef PRODUCT_DEFAULT_DEV_CERTIFICATE ifneq (1,$(words $(PRODUCT_DEFAULT_DEV_CERTIFICATE)))
$(error PRODUCT_DEFAULT_DEV_CERTIFICATE='$(PRODUCT_DEFAULT_DEV_CERTIFICATE)', \
only 1 certificate is allowed.) endif endif
$(foreach apexpair,$(PRODUCT_APEX_BOOT_JARS), \
$(foreach platformpair,$(PRODUCT_BOOT_JARS), \
$(eval apexjar := $(call word-colon,2,$(apexpair))) \
$(eval platformjar := $(call word-colon,2,$(platformpair))) \
$(if $(filter $(apexjar), $(platformjar)), \
$(error A jar in PRODUCT_APEX_BOOT_JARS must not be in PRODUCT_BOOT_JARS, but $(apexjar) is))))
# Resolve and setup per-module dex-preopt configs.
DEXPREOPT_DISABLED_MODULES := # If a module has multiple setups, the first takes precedence.
_pdpmc_modules :=
$(foreach c,$(PRODUCT_DEX_PREOPT_MODULE_CONFIGS),\
$(eval m := $(firstword $(subst =,$(space),$(c))))\
$(if $(filter $(_pdpmc_modules),$(m)),,\
$(eval _pdpmc_modules += $(m))\
$(eval cf := $(patsubst $(m)=%,%,$(c)))\
$(eval cf := $(subst $(_PDPMC_SP_PLACE_HOLDER),$(space),$(cf)))\
$(if $(filter disable,$(cf)),\
$(eval DEXPREOPT_DISABLED_MODULES += $(m)),\
$(eval DEXPREOPT.$(TARGET_PRODUCT).$(m).CONFIG := $(cf)))))
_pdpmc_modules :=
# Resolve and setup per-module sanitizer configs. # If a module has multiple setups, the first takes precedence.
_psmc_modules :=
$(foreach c,$(PRODUCT_SANITIZER_MODULE_CONFIGS),\
$(eval m := $(firstword $(subst =,$(space),$(c))))\
$(if $(filter $(_psmc_modules),$(m)),,\
$(eval _psmc_modules += $(m))\
$(eval cf := $(patsubst $(m)=%,%,$(c)))\
$(eval cf := $(subst $(_PSMC_SP_PLACE_HOLDER),$(space),$(cf)))\
$(eval SANITIZER.$(TARGET_PRODUCT).$(m).CONFIG := $(cf))))
_psmc_modules :=
# Reset ADB keys. If RELEASE_BUILD_USE_VARIANT_FLAGS is set look for # the value of a dedicated flag. Otherwise check if build variant is # non-debuggable. ifneq (,$(RELEASE_BUILD_USE_VARIANT_FLAGS)) ifneq (,$(RELEASE_BUILD_PURGE_PRODUCT_ADB_KEYS))
PRODUCT_ADB_KEYS := endif elseifeq (,$(filter eng userdebug,$(TARGET_BUILD_VARIANT)))
PRODUCT_ADB_KEYS := endif
ifneq ($(filter-out 01,$(words $(PRODUCT_ADB_KEYS))),)
$(error Only one file may be in PRODUCT_ADB_KEYS: $(PRODUCT_ADB_KEYS)) endif
# Show a warning wall of text if non-compliance-GSI products set this option.
ifdef PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT ifeq (,$(filter gsi_arm gsi_arm64 gsi_x86 gsi_x86_64 gsi_car_arm64 gsi_car_x86_64 gsi_tv_arm gsi_tv_arm64 clockwork_gsi_google_arm,$(PRODUCT_NAME)))
$(warning PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT is set but \
PRODUCT_NAME ($(PRODUCT_NAME)) doesn't look like a GSI for compliance \
testing. This is a special configuration for compliance GSI, so domake \
sure you understand the security implications before setting this \
option. If you don't know what this option does, then you probably \
shouldn't set this.) endif endif
# All requirements of PRODUCT_USE_DYNAMIC_PARTITIONS falls back to # PRODUCT_USE_DYNAMIC_PARTITIONS if not defined.
ifndef PRODUCT_USE_DYNAMIC_PARTITION_SIZE
PRODUCT_USE_DYNAMIC_PARTITION_SIZE := $(PRODUCT_USE_DYNAMIC_PARTITIONS) endif
# If build command defines OVERRIDE_PRODUCT_EXTRA_VNDK_VERSIONS, # override PRODUCT_EXTRA_VNDK_VERSIONS with it.
ifdef OVERRIDE_PRODUCT_EXTRA_VNDK_VERSIONS
PRODUCT_EXTRA_VNDK_VERSIONS := $(OVERRIDE_PRODUCT_EXTRA_VNDK_VERSIONS) endif
########################################### # PRODUCT_COMPRESSED_APEX: Use compressed apexes in pre-installed partitions. # # Note: this doesn't mean that all pre-installed apexes will be compressed. # Whether an apex is compressed or not is controlled at apex Soong module # via compresible property. # # APEX compression can be forcibly enabled (resp. disabled) by # setting OVERRIDE_PRODUCT_COMPRESSED_APEX to true (resp. false), e.g. by # setting the OVERRIDE_PRODUCT_COMPRESSED_APEX environment variable.
_default_compressed_apex := true # To mount APEXes before /data partition is mounted, there should be no compressed # apexes. ifeq (true,$(RELEASE_APEX_MOUNT_BEFORE_DATA))
_default_compressed_apex := false endif
ifdef OVERRIDE_PRODUCT_COMPRESSED_APEX
PRODUCT_COMPRESSED_APEX := $(OVERRIDE_PRODUCT_COMPRESSED_APEX) elseifeq (,$(PRODUCT_COMPRESSED_APEX))
PRODUCT_COMPRESSED_APEX := $(_default_compressed_apex) endif ifeq (,$(filter true false,$(PRODUCT_COMPRESSED_APEX)))
$(error PRODUCT_COMPRESSED_APEX should be either true or false) endif
PRODUCT_SYSTEM_PROPERTIES += apexd.config.compressed_apex=$(PRODUCT_COMPRESSED_APEX) # This is a system property but cannot be defined in the system makefile because # the PRODUCT_COMPRESSED_APEX is not available. Add it to the allowed list.
PRODUCT_ARTIFACT_PATH_REQUIREMENT_SYSPROP_ALLOWED_LIST += apexd.config.compressed_apex
########################################### # Set the default payload type for APEXes #
_default_payload_fs_type := ext4 ifeq (true,$(RELEASE_APEX_USE_EROFS_PREINSTALLED))
_default_payload_fs_type := erofs endif
# Default APEX payload type can be forcibly set with # OVERRIDE_PRODUCT_DEFAULT_APEX_PAYLOAD_TYPE.
ifdef OVERRIDE_PRODUCT_DEFAULT_APEX_PAYLOAD_TYPE
PRODUCT_DEFAULT_APEX_PAYLOAD_TYPE := $(OVERRIDE_PRODUCT_DEFAULT_APEX_PAYLOAD_TYPE) elseifeq ($(PRODUCT_DEFAULT_APEX_PAYLOAD_TYPE),)
PRODUCT_DEFAULT_APEX_PAYLOAD_TYPE := $(_default_payload_fs_type) endif
_default_payload_fs_type :=
ifeq ($(filter ext4 erofs,$(PRODUCT_DEFAULT_APEX_PAYLOAD_TYPE)),)
$(error PRODUCT_DEFAULT_APEX_PAYLOAD_TYPE should be either erofs or ext4,\
not $(PRODUCT_DEFAULT_APEX_PAYLOAD_TYPE).) endif
# If build command defines OVERRIDE_PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE, # override PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE with it unless it is # defined as `false`. If the value is `false` clear # PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE # OVERRIDE_PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE can be used for # testing only.
ifdef OVERRIDE_PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE ifeq (false,$(OVERRIDE_PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE))
PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := else
PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := $(OVERRIDE_PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE) endif elseifeq ($(PRODUCT_SHIPPING_API_LEVEL),) # No shipping level defined. Enforce the product interface by default.
PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true elseifeq ($(call math_gt,$(PRODUCT_SHIPPING_API_LEVEL),29),true) # Enforce product interface if PRODUCT_SHIPPING_API_LEVEL is greater than 29.
PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true endif
# From Android V, Define PRODUCT_PRODUCT_VNDK_VERSION as current by default. # This is required to make all devices have product variants.
ifndef PRODUCT_PRODUCT_VNDK_VERSION
PRODUCT_PRODUCT_VNDK_VERSION := current endif
ifdef PRODUCT_ENFORCE_RRO_EXEMPTED_TARGETS
$(error PRODUCT_ENFORCE_RRO_EXEMPTED_TARGETS is deprecated, consider using RRO for \
$(PRODUCT_ENFORCE_RRO_EXEMPTED_TARGETS)) endif
# This table maps sdk version 35 to vendor api level 202404 and assumes yearly # release for the same month. If 10000 API level or more is used, which usually # represents 'current' or 'future' API levels, several zeros are added to # preserve ordering. Specifically API level 10,000 is converted to 10,000,000 # which importantly is greater than 202404 = 202,404. This convention will break # in 100,000 CE, which is the closest multiple of 10 that doesn't break earlier # than 10,000 as an API level breaks. define sdk-to-vendor-api-level
$(if $(call math_lt_or_eq,$(1),34),$(1),$(if $(call math_lt,$(1),10000),20$(call int_subtract,$(1),11)04,$(1)000)) endef
ifneq ($(call sdk-to-vendor-api-level,34),34)
$(error sdk-to-vendor-api-level is broken for pre-Trunk-Stable SDKs) endif ifneq ($(call sdk-to-vendor-api-level,35),202404)
$(error sdk-to-vendor-api-level is broken for post-Trunk-Stable SDKs) endif ifneq ($(call sdk-to-vendor-api-level,10000),10000000)
$(error sdk-to-vendor-api-level is broken for current $(call sdk-to-vendor-api-level,10000)) endif
# VSR API level is the vendor api level of the product shipping API level.
VSR_VENDOR_API_LEVEL := $(call sdk-to-vendor-api-level,$(PLATFORM_SDK_VERSION))
ifdef PRODUCT_SHIPPING_API_LEVEL
VSR_VENDOR_API_LEVEL := $(call sdk-to-vendor-api-level,$(PRODUCT_SHIPPING_API_LEVEL)) endif
ifdef BOARD_SHIPPING_API_LEVEL # Vendors with GRF must define BOARD_SHIPPING_API_LEVEL for the vendor API level. # In this case, the VSR API level is the minimum of the PRODUCT_SHIPPING_API_LEVEL # and RELEASE_BOARD_API_LEVEL
board_api_level := $(RELEASE_BOARD_API_LEVEL)
ifdef BOARD_API_LEVEL_PROP_OVERRIDE # This must be used only for testing purpose. Product must not be released # with the modified api level value.
board_api_level := $(BOARD_API_LEVEL_PROP_OVERRIDE) endif
VSR_VENDOR_API_LEVEL := $(call math_min,$(VSR_VENDOR_API_LEVEL),$(board_api_level))
board_api_level := endif
.KATI_READONLY := VSR_VENDOR_API_LEVEL
# Macro to use below. $(1) is the name of the partition define product-build-image-config ifneq ($$(filter-out true false,$$(PRODUCT_BUILD_$(1)_IMAGE)),)
$$(error Invalid PRODUCT_BUILD_$(1)_IMAGE: $$(PRODUCT_BUILD_$(1)_IMAGE) -- true false and empty are supported) endif endef
# Copy and check the value of each PRODUCT_BUILD_*_IMAGE variable
$(foreach image, \
PVMFW \
SYSTEM \
SYSTEM_OTHER \
VENDOR \
PRODUCT \
SYSTEM_EXT \
ODM \
VENDOR_DLKM \
ODM_DLKM \
SYSTEM_DLKM \
CACHE \
RAMDISK \
USERDATA \
BOOT \
RECOVERY, \
$(eval $(call product-build-image-config,$(image))))
product-build-image-config :=
ifdef PRODUCT_SOONG_ONLY ifneq ($(PRODUCT_SOONG_ONLY),true) ifneq ($(PRODUCT_SOONG_ONLY),false)
$(error PRODUCT_SOONG_ONLY can only be true, false or unset) endif endif endif
ifdef PRODUCT_SOONG_INCREMENTAL_ANALYSIS ifneq ($(PRODUCT_SOONG_INCREMENTAL_ANALYSIS),true) ifneq ($(PRODUCT_SOONG_INCREMENTAL_ANALYSIS),false)
$(error PRODUCT_SOONG_INCREMENTAL_ANALYSIS can only be true, false or unset) endif endif endif
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.