blob: 1a27578ea84e86fa97d21d884c52aef04b7940e5 [file] [log] [blame]
#!/usr/bin/env python
#
# 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()