Check if current ld.config.txt files is backward compatible
The ld.config.txt file is a template to be used for current build as well as for the VNDK snapshots for old vendor partitions. To work with the old Android vendor partitions, the ld.config.txt template must be backward compatible. This script checks if the current ld.config.txt template modifies or deletes the vendor directores in every section. If the change is detected, it will report a build error. Bug: 112738739 Bug: 111417344 Test: make ld.config.txt Change-Id: I1211696d6a00a37d531d40c894f1d7e64b210ae5
This commit is contained in:
parent
5e26856b98
commit
15bac6bdaf
|
@ -206,6 +206,7 @@ ifeq ($(_enforce_vndk_at_runtime),true)
|
|||
LOCAL_MODULE_STEM := $(call append_vndk_version,$(LOCAL_MODULE))
|
||||
include $(BUILD_SYSTEM)/base_rules.mk
|
||||
ld_config_template := $(LOCAL_PATH)/etc/ld.config.txt
|
||||
check_backward_compatibility := true
|
||||
vndk_version := $(PLATFORM_VNDK_VERSION)
|
||||
include $(LOCAL_PATH)/update_and_install_ld_config.mk
|
||||
|
||||
|
@ -243,6 +244,7 @@ LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
|
|||
LOCAL_MODULE_STEM := $$(LOCAL_MODULE)
|
||||
include $(BUILD_SYSTEM)/base_rules.mk
|
||||
ld_config_template := $(LOCAL_PATH)/etc/ld.config.txt
|
||||
check_backward_compatibility := true
|
||||
vndk_version := $(1)
|
||||
lib_list_from_prebuilts := true
|
||||
include $(LOCAL_PATH)/update_and_install_ld_config.mk
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (C) 2018 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 glob
|
||||
import os.path
|
||||
import re
|
||||
import sys
|
||||
|
||||
PREBUILTS_VNDK_DIR = "prebuilts/vndk"
|
||||
VENDOR_DIRECTORIES = ('/vendor', '/odm')
|
||||
|
||||
def find_latest_vndk_snapshot_version():
|
||||
"""Returns latest vndk snapshot version in current source tree.
|
||||
It will skip the test if the snapshot directories are not found.
|
||||
|
||||
Returns:
|
||||
latest_version: string
|
||||
"""
|
||||
vndk_dir_list = glob.glob(PREBUILTS_VNDK_DIR + "/v*")
|
||||
if not vndk_dir_list:
|
||||
"""Exit without error because we may have source trees that do not include
|
||||
VNDK snapshot directories in it.
|
||||
"""
|
||||
sys.exit(0)
|
||||
vndk_ver_list = [re.match(r".*/v(\d+)", vndk_dir).group(1)
|
||||
for vndk_dir in vndk_dir_list]
|
||||
latest_version = max(vndk_ver_list)
|
||||
if latest_version == '27':
|
||||
"""Exit without error because VNDK v27 is not using ld.config.txt template
|
||||
"""
|
||||
sys.exit(0)
|
||||
return latest_version
|
||||
|
||||
def get_vendor_configuration(ld_config_file):
|
||||
"""Reads the ld.config.txt file to parse the namespace configurations.
|
||||
It finds the configurations that include vendor directories.
|
||||
|
||||
Args:
|
||||
ld_config_file: string, path (relative to build top) of the ld.config.txt
|
||||
file.
|
||||
Returns:
|
||||
configs: dict{string:[string]}, dictionary of namespace configurations.
|
||||
it has 'section + property' names as keys and the directory list
|
||||
as values.
|
||||
"""
|
||||
try:
|
||||
conf_file = open(ld_config_file)
|
||||
except IOError:
|
||||
print("error: could not read %s" % ld_config_file)
|
||||
sys.exit(1)
|
||||
|
||||
configs = dict()
|
||||
current_section = None
|
||||
|
||||
with conf_file:
|
||||
for line in conf_file:
|
||||
# ignore comments
|
||||
found = line.find('#')
|
||||
if found != -1:
|
||||
line = line[:found]
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
|
||||
if line[0] == '[' and line[-1] == ']':
|
||||
# new section started
|
||||
current_section = line[1:-1]
|
||||
continue
|
||||
|
||||
if current_section == None:
|
||||
continue
|
||||
|
||||
found = line.find('+=')
|
||||
opr_len = 2
|
||||
if found == -1:
|
||||
found = line.find('=')
|
||||
opr_len = 1
|
||||
if found == -1:
|
||||
continue
|
||||
|
||||
namespace = line[:found].strip()
|
||||
if not namespace.endswith(".paths"):
|
||||
# check ".paths" only
|
||||
continue
|
||||
namespace = '[' + current_section + ']' + namespace
|
||||
values = line[found + opr_len:].strip()
|
||||
directories = values.split(':')
|
||||
|
||||
for directory in directories:
|
||||
if any(vendor_dir in directory for vendor_dir in VENDOR_DIRECTORIES):
|
||||
if namespace in configs:
|
||||
configs[namespace].append(directory)
|
||||
else:
|
||||
configs[namespace] = [directory]
|
||||
|
||||
return configs
|
||||
|
||||
def get_snapshot_config(version):
|
||||
"""Finds the ld.config.{version}.txt file from the VNDK snapshot directory.
|
||||
In the vndk prebuilt directory (prebuilts/vndk/v{version}), it searches
|
||||
{arch}/configs/ld.config.{version}.txt file, where {arch} is one of ('arm64',
|
||||
'arm', 'x86_64', 'x86').
|
||||
|
||||
Args:
|
||||
version: string, the VNDK snapshot version to search.
|
||||
Returns:
|
||||
ld_config_file: string, relative path to ld.config.{version}.txt
|
||||
"""
|
||||
arch_list = ('arm64', 'arm', 'x86_64', 'x86')
|
||||
for arch in arch_list:
|
||||
ld_config_file = (PREBUILTS_VNDK_DIR
|
||||
+ "/v{0}/{1}/configs/ld.config.{0}.txt".format(version, arch))
|
||||
if os.path.isfile(ld_config_file):
|
||||
return ld_config_file
|
||||
print("error: cannot find ld.config.{0}.txt file in snapshot v{0}"
|
||||
.format(version))
|
||||
sys.exit(1)
|
||||
|
||||
def check_backward_compatibility(ld_config, vndk_snapshot_version):
|
||||
"""Checks backward compatibility for current ld.config.txt file with the
|
||||
old ld.config.txt file. If any of the vendor directories in the old namespace
|
||||
configurations are missing, the test will fail. It is allowed to have new
|
||||
vendor directories in current ld.config.txt file.
|
||||
|
||||
Args:
|
||||
ld_config: string, relative path to current ld.config.txt file.
|
||||
vndk_snapshot_version: string, the VNDK snapshot version that has an old
|
||||
ld.config.txt file to compare.
|
||||
Returns:
|
||||
result: bool, True if the current configuration is backward compatible.
|
||||
"""
|
||||
current_config = get_vendor_configuration(ld_config)
|
||||
old_config = get_vendor_configuration(
|
||||
get_snapshot_config(vndk_snapshot_version))
|
||||
for namespace in old_config:
|
||||
if namespace not in current_config:
|
||||
print("error: cannot find %s which was provided in ld.config.%s.txt"
|
||||
% (namespace, vndk_snapshot_version))
|
||||
return False
|
||||
for path in old_config[namespace]:
|
||||
if not path in current_config[namespace]:
|
||||
print("error: %s for %s in ld.config.%s.txt are missing in %s"
|
||||
% (path, namespace, vndk_snapshot_version, ld_config))
|
||||
return False
|
||||
return True
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 2:
|
||||
print ("Usage: %s target_ld_config_txt_file_name" % sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
latest_vndk_snapshot_version = find_latest_vndk_snapshot_version()
|
||||
if not check_backward_compatibility(sys.argv[1],
|
||||
latest_vndk_snapshot_version):
|
||||
print("error: %s has backward incompatible changes to old "
|
||||
"vendor partition." % sys.argv[1])
|
||||
sys.exit(1)
|
||||
|
||||
# Current ld.config.txt file is backward compatible
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -18,10 +18,13 @@
|
|||
|
||||
# Read inputs
|
||||
ld_config_template := $(strip $(ld_config_template))
|
||||
check_backward_compatibility := $(strip $(check_backward_compatibility))
|
||||
vndk_version := $(strip $(vndk_version))
|
||||
lib_list_from_prebuilts := $(strip $(lib_list_from_prebuilts))
|
||||
libz_is_llndk := $(strip $(libz_is_llndk))
|
||||
|
||||
compatibility_check_script := \
|
||||
$(LOCAL_PATH)/ld_config_backward_compatibility_check.py
|
||||
intermediates_dir := $(call intermediates-dir-for,ETC,$(LOCAL_MODULE))
|
||||
library_lists_dir := $(intermediates_dir)
|
||||
ifeq ($(lib_list_from_prebuilts),true)
|
||||
|
@ -82,11 +85,19 @@ $(LOCAL_BUILT_MODULE): PRIVATE_VNDK_PRIVATE_LIBRARIES_FILE := $(vndkprivate_libr
|
|||
$(LOCAL_BUILT_MODULE): PRIVATE_SANITIZER_RUNTIME_LIBRARIES := $(sanitizer_runtime_libraries)
|
||||
$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_VERSION_SUFFIX := $(vndk_version_suffix)
|
||||
$(LOCAL_BUILT_MODULE): PRIVATE_INTERMEDIATES_DIR := $(intermediates_dir)
|
||||
$(LOCAL_BUILT_MODULE): PRIVATE_COMP_CHECK_SCRIPT := $(compatibility_check_script)
|
||||
deps := $(llndk_libraries_file) $(vndksp_libraries_file) $(vndkcore_libraries_file) \
|
||||
$(vndkprivate_libraries_file)
|
||||
ifeq ($(check_backward_compatibility),true)
|
||||
deps += $(compatibility_check_script)
|
||||
endif
|
||||
|
||||
$(LOCAL_BUILT_MODULE): $(ld_config_template) $(deps)
|
||||
@echo "Generate: $< -> $@"
|
||||
ifeq ($(check_backward_compatibility),true)
|
||||
@echo "Checking backward compatibility..."
|
||||
$(hide) $(PRIVATE_COMP_CHECK_SCRIPT) $<
|
||||
endif
|
||||
@mkdir -p $(dir $@)
|
||||
$(call private-filter-out-private-libs,$(PRIVATE_LLNDK_LIBRARIES_FILE),$(PRIVATE_INTERMEDIATES_DIR)/llndk_filtered)
|
||||
$(hide) sed -e "s?%LLNDK_LIBRARIES%?$$(cat $(PRIVATE_INTERMEDIATES_DIR)/llndk_filtered)?g" $< >$@
|
||||
|
@ -108,9 +119,11 @@ $(LOCAL_BUILT_MODULE): $(ld_config_template) $(deps)
|
|||
$(hide) rm -f $@.bak
|
||||
|
||||
ld_config_template :=
|
||||
check_backward_compatibility :=
|
||||
vndk_version :=
|
||||
lib_list_from_prebuilts :=
|
||||
libz_is_llndk :=
|
||||
compatibility_check_script :=
|
||||
intermediates_dir :=
|
||||
library_lists_dir :=
|
||||
llndk_libraries_file :=
|
||||
|
|
Loading…
Reference in New Issue