From 2fa27104aa0e97f3c750aa3b04acfc76db5e7123 Mon Sep 17 00:00:00 2001 From: Jack Rosenthal Date: Fri, 8 Jan 2021 12:30:48 -0700 Subject: zephyr: copy zmake to platform/ec This copies zmake into platform/ec/zephyr/zmake, as explained in go/zephyr-fewer-repos. Follow-on CLs will be submitted to: - Update the chromeos-base/zephyr-build-tools ebuild to reference this directory instead of the one in zephyr-chrome. - Remove the copy of zmake in zephyr-chrome. Those interested in the git history of this code prior to it being moved to platform/ec can find it here: https://chromium.googlesource.com/chromiumos/platform/zephyr-chrome/+log/bacea2e3e62c41000e5bdb4ed6433f24386d14bf/util BUG=b:177003034 BRANCH=none TEST=emerge with new path (requires follow-on CL) Signed-off-by: Jack Rosenthal Change-Id: Ia957b3e35ce3b732968ebf8df603ef13298cc6b3 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2618501 Reviewed-by: Yuval Peress --- zephyr/zmake/zmake/util.py | 147 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 zephyr/zmake/zmake/util.py (limited to 'zephyr/zmake/zmake/util.py') diff --git a/zephyr/zmake/zmake/util.py b/zephyr/zmake/zmake/util.py new file mode 100644 index 0000000000..fc81176b6c --- /dev/null +++ b/zephyr/zmake/zmake/util.py @@ -0,0 +1,147 @@ +# Copyright 2020 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Common miscellaneous utility functions for zmake.""" + +import os +import pathlib +import re +import shlex + + +def locate_cros_checkout(): + """Find the path to the ChromiumOS checkout. + + Returns: + The first directory found with a .repo directory in it, + starting by checking the CROS_WORKON_SRCROOT environment + variable, then scanning upwards from the current directory, + and finally from a known set of common paths. + """ + def propose_checkouts(): + yield os.getenv('CROS_WORKON_SRCROOT') + + path = pathlib.Path.cwd() + while path.resolve() != pathlib.Path('/'): + yield path + path = path / '..' + + yield '/mnt/host/source' + yield pathlib.Path.home() / 'trunk' + yield pathlib.Path.home() / 'chromiumos' + + for path in propose_checkouts(): + if not path: + continue + path = pathlib.Path(path) + if (path / '.repo').is_dir(): + return path.resolve() + + raise FileNotFoundError('Unable to locate a ChromiumOS checkout') + + +def locate_zephyr_base(checkout, version): + """Locate the path to the Zephyr RTOS in a ChromiumOS checkout. + + Args: + checkout: The path to the ChromiumOS checkout. + version: The requested zephyr version, as a tuple of integers. + + Returns: + The path to the Zephyr source. + """ + return (checkout / 'src' / 'third_party' / 'zephyr' / 'main' / + 'v{}.{}'.format(*version[:2])) + + +def read_kconfig_file(path): + """Parse a Kconfig file. + + Args: + path: The path to open. + + Returns: + A dictionary of kconfig items to their values. + """ + result = {} + with open(path) as f: + for line in f: + line, _, _ = line.partition('#') + line = line.strip() + if line: + name, _, value = line.partition('=') + result[name.strip()] = value.strip() + return result + + +def write_kconfig_file(path, config, only_if_changed=True): + """Write out a dictionary to Kconfig format. + + Args: + path: The path to write to. + config: The dictionary to write. + only_if_changed: Set to True if the file should not be written + unless it has changed. + """ + if only_if_changed: + if path.exists() and read_kconfig_file(path) == config: + return + with open(path, "w") as f: + for name, value in config.items(): + f.write('{}={}\n'.format(name, value)) + + +def parse_zephyr_version(version_string): + """Parse a human-readable version string (e.g., "v2.4") as a tuple. + + Args: + version_string: The human-readable version string. + + Returns: + A 2-tuple or 3-tuple of integers representing the version. + """ + match = re.fullmatch(r'v?(\d+)[._](\d+)(?:[._](\d+))?', version_string) + if not match: + raise ValueError( + "{} does not look like a Zephyr version.".format(version_string)) + return tuple(int(x) for x in match.groups() if x is not None) + + +def repr_command(argv): + """Represent an argument array as a string. + + Args: + argv: The arguments of the command. + + Returns: + A string which could be pasted into a shell for execution. + """ + return ' '.join(shlex.quote(str(arg)) for arg in argv) + + +def update_symlink(target_path, link_path): + """Create a symlink if it does not exist, or links to a different path. + + Args: + target_path: A Path-like object of the desired symlink path. + link_path: A Path-like object of the symlink. + """ + target = target_path.resolve() + if (not link_path.is_symlink() + or pathlib.Path(os.readlink(link_path)).resolve() != target): + if link_path.exists(): + link_path.unlink() + link_path.symlink_to(target) + + +def log_multi_line(logger, level, message): + """Log a potentially multi-line message to the logger. + + Args: + logger: The Logger object to log to. + level: The logging level to use when logging. + message: The (potentially) multi-line message to log. + """ + for line in message.splitlines(): + if line: + logger.log(level, line) -- cgit v1.2.1