text: # 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.
  """Registry of known Zephyr modules."""
  
  import pathlib
  import os
  
  import zmake.build_config as build_config
  import zmake.util as util
  
  
  def third_party_module(name, checkout):
      """Common callback in registry for all third_party/zephyr modules.
  
      Args:
          name: The name of the module.
          checkout: The path to the chromiumos source.
  
      Return:
          The path to the module module.
      """
      # TODO(b/180531609): version "v2.5" below is a misnomer, as these
      # modules are actually compatible with all kernel versions.  Drop
      # v2.5 from the manifest checkout path and remove it from here.
      return checkout / 'src' / 'third_party' / 'zephyr' / name / 'v2.5'
  
  
  known_modules = {
      'hal_stm32': third_party_module,
      'cmsis': third_party_module,
      'ec': lambda name, checkout: (checkout / 'src' / 'platform' / 'ec'),
  }
  
  
  def locate_from_checkout(checkout_dir):
      """Find modules from a Chrome OS checkout.
  
      Important: this function should only conditionally be called if a
      checkout exists.  Zmake *can* be used without a Chrome OS source
      tree.  You should call locate_from_directory if outside of a
      Chrome OS source tree.
  
      Args:
          checkout_dir: The path to the chromiumos source.
  
      Returns:
          A dictionary mapping module names to paths.
      """
      result = {}
      for name, locator in known_modules.items():
          result[name] = locator(name, checkout_dir)
      return result
  
  
  def locate_from_directory(directory):
      """Create a modules dictionary from a directory.
  
      This takes a directory, and searches for the known module names
      located in it.
  
      Args:
          directory: the directory to search in.
  
      Returns:
          A dictionary mapping module names to paths.
      """
      result = {}
  
      for name in known_modules:
          modpath = (directory / name).resolve()
          if (modpath / 'zephyr' / 'module.yml').is_file():
              result[name] = modpath
  
      return result
  
  
  def setup_module_symlinks(output_dir, modules):
      """Setup a directory with symlinks to modules.
  
      Args:
          output_dir: The directory to place the symlinks in.
          modules: A dictionary of module names mapping to paths.
  
      Returns:
          The resultant BuildConfig that should be applied to use each
          of these modules.
      """
      if not output_dir.exists():
          output_dir.mkdir(parents=True)
  
      module_links = []
  
      for name, path in modules.items():
          link_path = output_dir.resolve() / name
          util.update_symlink(path, link_path)
          module_links.append(link_path)
  
      if module_links:
          return build_config.BuildConfig(
              cmake_defs={'ZEPHYR_MODULES': ';'.join(map(str, module_links))})
      else:
          return build_config.BuildConfig()
  