blob: c8f6b6e836bc252fb6ac7ac6a3ea115f932797ac [file] [log] [blame]
#!/usr/bin/env python
#
# Copyright (C) 2017 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 os
import re
from utils.const import Constant
from vts_spec_parser import VtsSpecParser
import build_rule_gen_utils as utils
class BuildRuleGen(object):
"""Build rule generator for test/vts-testcase/hal."""
_ANDROID_BUILD_TOP = os.environ.get('ANDROID_BUILD_TOP')
if not _ANDROID_BUILD_TOP:
print 'Run "lunch" command first.'
sys.exit(1)
_PROJECT_PATH = os.path.join(_ANDROID_BUILD_TOP, 'test', 'vts-testcase',
'hal')
_VTS_BUILD_TEMPLATE = os.path.join(_PROJECT_PATH, 'script', 'build',
'template', 'vts_build_template.bp')
def __init__(self, warning_header, package_root, path_root):
"""BuildRuleGen constructor.
Args:
warning_header: string, warning header for every generated file.
package_root: string, prefix of the hal package.
path_root: string, root path that stores the hal definition.
"""
self._warning_header = warning_header
self._vts_spec_parser = VtsSpecParser(package_root, path_root)
self._package_root = package_root
self._path_root = path_root
def UpdateBuildRule(self, test_config_dir):
"""Updates build rules under the configuration directory.
Args:
test_config_dir: string, directory storing the configurations.
"""
utils.RemoveFilesInDirIf(
os.path.join(self._ANDROID_BUILD_TOP, test_config_dir),
lambda x: self._IsAutoGenerated(x))
hal_list = self._vts_spec_parser.HalNamesAndVersions()
self.UpdateHalDirBuildRule(hal_list, test_config_dir)
def UpdateHalDirBuildRule(self, hal_list, test_config_dir):
"""Updates build rules for vts drivers/profilers.
Updates vts drivers/profilers for each pair of (hal_name, hal_version)
in hal_list.
Args:
hal_list: list of tuple of strings. For example,
[('vibrator', '1.3'), ('sensors', '1.7')]
test_config_dir: string, directory storing the configurations.
"""
for target in hal_list:
hal_name = target[0]
hal_version = target[1]
hal_dir = os.path.join(
self._ANDROID_BUILD_TOP, test_config_dir,
utils.HalNameDir(hal_name), utils.HalVerDir(hal_version))
file_path = os.path.join(hal_dir, 'build', 'Android.bp')
utils.WriteBuildRule(file_path, self._VtsBuildRuleFromTemplate(
self._VTS_BUILD_TEMPLATE, hal_name, hal_version))
def _VtsBuildRuleFromTemplate(self, template_path, hal_name, hal_version):
"""Returns build rules in string form by filling out a template.
Reads template from given path and fills it out.
Args:
template_path: string, path to build rule template file.
hal_name: string, name of the hal, e.g. 'vibrator'.
hal_version: string, version of the hal, e.g '7.4'
Returns:
string, complete build rules in string form
"""
with open(template_path) as template_file:
build_template = str(template_file.read())
return self._FillOutBuildRuleTemplate(hal_name, hal_version,
build_template)
def _FillOutBuildRuleTemplate(self, hal_name, hal_version, template):
"""Returns build rules in string form by filling out given template.
Args:
hal_name: string, name of the hal, e.g. 'vibrator'.
hal_version: string, version of the hal, e.g '7.4'
template: string, build rule template to fill out.
Returns:
string, complete build rule in string form.
"""
package_root_dir = self._package_root.replace(".", "/")
def GeneratedOutput(hal_name, hal_version, extension):
"""Formats list of vts spec names into a string.
Formats list of vts spec name for given hal_name, hal_version
into a string that can be inserted into build template.
Args:
hal_name: string, name of the hal, e.g. 'vibrator'.
hal_version: string, version of the hal, e.g '7.4'
extension: string, extension of files e.g. '.cpp'.
Returns:
string, to be inserted into build template.
"""
result = []
vts_spec_names = self._vts_spec_parser.VtsSpecNames(hal_name,
hal_version)
for vts_spec in vts_spec_names:
result.append('%s/%s/%s/%s%s' %
(package_root_dir, utils.HalNameDir(hal_name),
hal_version, vts_spec, extension))
return ListToBuildString(result, 2)
def ImportedPackages(vts_pkg_type, imported_packages):
"""Formats list of imported packages into a string.
Formats list of imported packages for given hal_name, hal_version
into a string that can be inserted into build template.
Args:
vts_pkg_type: string 'driver' or 'profiler'
imported_packages: list of imported packages
Returns:
string, to be inserted into build template.
"""
result = []
for package in imported_packages:
if re.match(Constant.HAL_PACKAGE_NAME_PATTERN, package):
vts_pkg_name = package + '-vts.' + vts_pkg_type
result.append(vts_pkg_name)
else:
result.append(package)
return ListToBuildString(result, 2)
build_rule = self._warning_header + template
build_rule = build_rule.replace('{HAL_NAME}', hal_name)
build_rule = build_rule.replace('{HAL_NAME_DIR}',
utils.HalNameDir(hal_name))
build_rule = build_rule.replace('{HAL_VERSION}', hal_version)
build_rule = build_rule.replace('{PACKAGE_ROOT}', self._package_root)
build_rule = build_rule.replace('{PACKAGE_ROOT_DIR}', package_root_dir)
build_rule = build_rule.replace(
'{HIDL_GEN_ARGS}',
"-r %s:%s" % (self._package_root, self._path_root))
build_rule = build_rule.replace(
'{GENERATED_VTS_SPECS}',
GeneratedOutput(hal_name, hal_version, ''))
build_rule = build_rule.replace(
'{GENERATED_SOURCES}',
GeneratedOutput(hal_name, hal_version, '.cpp'))
build_rule = build_rule.replace(
'{GENERATED_HEADERS}', GeneratedOutput(hal_name, hal_version, '.h'))
imported_packages = self._vts_spec_parser.ImportedPackagesList(
hal_name, hal_version)
build_rule = build_rule.replace(
'{IMPORTED_DRIVER_PACKAGES}',
ImportedPackages('driver', imported_packages))
build_rule = build_rule.replace(
'{IMPORTED_PROFILER_PACKAGES}',
ImportedPackages('profiler', imported_packages))
this_package = '%s.%s@%s' % (self._package_root, hal_name, hal_version)
imported_packages.append(this_package)
hal_libs = sorted(imported_packages)
build_rule = build_rule.replace(
'{HAL_LIBS}', ListToBuildString(hal_libs, 2))
return build_rule
def _IsAutoGenerated(self, abs_file_path):
"""Checks if file was auto-generated.
Args:
abs_file_path: string, absolute file path.
Returns:
True iff file was auto-generated by BuildRuleGen.
"""
[dir_name, file_name] = os.path.split(abs_file_path)
if file_name != 'Android.bp':
return False
with open(abs_file_path) as myfile:
return self._warning_header in myfile.read()
def ListToBuildString(lst, indent_lvl):
"""Formats a list of item into a string to be inserted into build rule.
Args:
lst: string list, e.g. [a, b, c].
indent_lvl: int, indentation level of the output list.
Returns:
string to be inserted into build rule.
"""
single_indent = ' '
indent = single_indent * indent_lvl
result = ''.join(map(lambda x: '\n%s"%s",' % (indent, x), sorted(lst)))
if result:
result += '\n' + single_indent * (indent_lvl - 1)
return result