Add APEX data to checkvintf for compatibility check.

As part of extending libvintf to support VINTF data inside of APEXes:
  Create apex-info-list.xml as part of build to pass into checkvintf.
  Include the /apex data to dirmap

  Extend check_target_files_vintf.py to include APEX data:
    Unzip APEX from partions
    Extract APEX data
    Create apex-info-list.xml

Bug: 239055387
Bug: 242314000
Test: m
Test: m dist
Change-Id: I4b4e159051bacb46dc43b83e006ca0f0eb58d772
This commit is contained in:
Rob Seymour
2022-07-28 21:56:28 +00:00
parent 2a9b910bf4
commit 3f1c9577e8
3 changed files with 126 additions and 1 deletions

View File

@@ -4557,6 +4557,26 @@ ifeq (,$(TARGET_BUILD_UNBUNDLED))
intermediates := $(call intermediates-dir-for,PACKAGING,check_vintf_all)
check_vintf_all_deps :=
APEX_OUT := $(PRODUCT_OUT)/apex
# -----------------------------------------------------------------
# Create apex-info-file.xsd
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_INFO_FILE): $(HOST_OUT_EXECUTABLES)/dump_apex_info $(apex_vintf_files)
@echo "Creating apex-info-file in $(PRODUCT_OUT) "
$< --root_dir $(PRODUCT_OUT) --out_file $@
apex_vintf_files :=
# 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.
check_vintf_common_srcs_patterns := \
@@ -4567,6 +4587,7 @@ check_vintf_common_srcs_patterns := \
$(TARGET_OUT_SYSTEM_EXT)/etc/vintf/% \
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 :=
@@ -4746,10 +4767,12 @@ check_vintf_compatible_args += \
--dirmap /odm:$(TARGET_OUT_ODM) \
--dirmap /product:$(TARGET_OUT_PRODUCT) \
--dirmap /system_ext:$(TARGET_OUT_SYSTEM_EXT) \
--dirmap /apex:$(APEX_OUT) \
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)

View File

@@ -98,6 +98,8 @@ python_defaults {
],
required: [
"checkvintf",
"deapexer",
"dump_apex_info",
],
}

View File

@@ -22,6 +22,7 @@ Usage: check_target_files_vintf target_files
target_files can be a ZIP file or an extracted target files directory.
"""
import json
import logging
import subprocess
import sys
@@ -123,7 +124,12 @@ def CheckVintfFromExtractedTargetFiles(input_tmp, info_dict=None):
logger.warning('PRODUCT_ENFORCE_VINTF_MANIFEST is not set, skipping checks')
return True
dirmap = GetDirmap(input_tmp)
apex_root, apex_info_file = PrepareApexDirectory(input_tmp)
dirmap['/apex'] = apex_root
args_for_skus = GetArgsForSkus(info_dict)
shipping_api_level_args = GetArgsForShippingApiLevel(info_dict)
kernel_args = GetArgsForKernel(input_tmp)
@@ -132,6 +138,8 @@ def CheckVintfFromExtractedTargetFiles(input_tmp, info_dict=None):
'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)]
common_command += kernel_args
@@ -185,6 +193,98 @@ def GetVintfFileList():
paths = sum((PathToPatterns(path) for path in paths if path), [])
return paths
def GetVintfApexUnzipPatterns():
""" Build unzip pattern for APEXes. """
patterns = []
for target_files_rel_paths in DIR_SEARCH_PATHS.values():
for target_files_rel_path in target_files_rel_paths:
patterns.append(os.path.join(target_files_rel_path,"apex/*"))
return patterns
def PrepareApexDirectory(inp):
""" Prepare the APEX data.
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.
Create the following structure under the input inp directory:
APEX/apex # Extracted APEXes
APEX/system/apex/ # System APEXes
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
"""
def ExtractApexes(path, outp):
# Extract all APEXes found in input path.
debugfs_path = 'debugfs'
deapexer = 'deapexer'
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')
if os.path.isfile(deapexer_path):
deapexer = deapexer_path
logger.info('Extracting APEXs in %s', path)
for f in os.listdir(path):
logger.info(' adding APEX %s', os.path.basename(f))
apex = os.path.join(path, f)
cmd = [deapexer,
'--debugfs_path', debugfs_path,
'info',
apex]
info = json.loads(common.RunAndCheckOutput(cmd))
cmd = [deapexer,
'--debugfs_path', debugfs_path,
'extract',
apex,
os.path.join(outp, info['name'])]
common.RunAndCheckOutput(cmd)
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
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():
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)
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]
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
def CheckVintfFromTargetFiles(inp, info_dict=None):
"""
@@ -198,7 +298,7 @@ def CheckVintfFromTargetFiles(inp, info_dict=None):
True if VINTF check is skipped or compatible, False if incompatible. Raise
a RuntimeError if any error occurs.
"""
input_tmp = common.UnzipTemp(inp, GetVintfFileList() + UNZIP_PATTERN)
input_tmp = common.UnzipTemp(inp, GetVintfFileList() + GetVintfApexUnzipPatterns() + UNZIP_PATTERN)
return CheckVintfFromExtractedTargetFiles(input_tmp, info_dict)