""" Copyright 2024 Google LLC SPDX-License-Identifier: MIT """ from enum import Enum class LibraryType(Enum): Library = 0 # Default undefined library value LibraryShared = 1 LibraryStatic = 2 class IncludeDirectories: def __init__(self): self.name: str = '' self.dirs: list[str] = [] self.visibility: list[str] = [] class StaticLibrary(IncludeDirectories): """ Represents the cc_library_static / cc_library module in build files """ def __init__(self): """ Attributes here favor a Soong attribute naming scheme """ super().__init__() self.srcs: list[str] = [] self.library_type: LibraryType = ( LibraryType.Library ) # Can be cc_library_static or cc_library_shared # In Bazel, these headers are one merged list. self.generated_headers: list[str] = [] self.generated_sources: list[str] = [] # In Bazel, these c options are copts self.copts: list[str] = [] self.cstd: str = '' self.cpp_std: str = '' self.conlyflags: list[str] = [] self.cppflags: list[str] = [] self.deps: list[str] = [] self.target_compatible_with: list[str] = [] self.local_include_dirs: list[str] = [] self.static_libs: list[str] = [] self.whole_static_libs: list[str] = [] self.shared_libs: list[str] = [] self.header_libs: list[str] = [] @property def hdrs(self): return self.generated_headers + self.generated_sources def __str__(self): return f'@StaticLibrary: name: {self.name}, LibraryType: {self.library_type}' class CustomTarget: """ Denoted as genrule in both build files """ def __init__(self): self.name: str = '' self.srcs: list[str] = [] self.out: list[str] = [] # 'outs' in bazel self.tools: list[str] = [] self.export_include_dirs: list[str] = [] self.cmd: str = '' def __str__(self): return ( f'name: {self.name}\n' f'srcs: {self.srcs}\n' f'out: {self.out}\n' f'tools: {self.tools}\n' f'export_include_dirs: {self.export_include_dirs}\n' f'cmd: {self.cmd}' ) class PythonCustomTarget(CustomTarget): def __init__(self): super().__init__() self.main: str = '' self.libs: list[str] = [] self.imports: list[str] = [] self.version = {} def __str__(self): return ( f'name: {self.name}\n' f'main: {self.main}\n' f'srcs: {self.srcs}\n' f'libs: {self.libs}' ) class ProjectConfig: """ Class that represents a singular project_config within aosp.toml/fuchsia.toml in python objects. There are multiple project_config within each .toml file """ def __init__(self): self._build: str = '' # Global across all configs self._name: str = '' # name of this config self._inherits_from = '' # project_config.host_machine self._cpu_family: str = '' self._cpu: str = '' self._host_machine: str = '' self._build_machine: str = '' # project_config.meson_options self._meson_options: dict[str, int | str] = {} # project_config.header_not_supported self._headers_not_supported: list[str] = [] # project_config.symbol_not_supported self._symbols_not_supported: list[str] = [] # project_config.function_not_supported self._functions_not_supported: list[str] = [] # project_config.link_not_supported self._links_not_supported: list[str] = [] # project_config.ext_dependencies self._ext_dependencies: dict[str, list[dict[str, str | int]]] = {} # Example structure for ext_dependencies # { # zlib = [ # { # 'target_name': '@zlib//:zlib', # 'target_type': 2 # }, # ... # ] @staticmethod def create_project_config(build, **kwargs): project_config = ProjectConfig() project_config._build = build # Global across all configs project_config._name = kwargs.get('name') # name of this config project_config._inherits_from = kwargs.get('inherits_from') project_config._cpu_family = kwargs.get('host_machine').get('cpu_family') project_config._cpu = kwargs.get('host_machine').get('cpu') project_config._host_machine = kwargs.get('host_machine').get('host_machine') project_config._build_machine = kwargs.get('host_machine').get('build_machine') project_config._meson_options = kwargs.get('meson_options') project_config._headers_not_supported = kwargs.get('header_not_supported').get( 'headers' ) project_config._symbols_not_supported = kwargs.get('symbol_not_supported').get( 'symbols' ) project_config._functions_not_supported = kwargs.get( 'function_not_supported' ).get('functions') project_config._links_not_supported = kwargs.get('link_not_supported').get( 'links' ) project_config._ext_dependencies = kwargs.get('ext_dependencies') return project_config def extend(self, proj_config): """ Appends to the current instance of ProjectConfig with another This also overrides attributes like self._name to the given param :param proj_config: ProjectConfig :return: ProjectConfig """ self._build = proj_config.build self._name = proj_config.name self._inherits_from = proj_config.inherits_from self._cpu_family = proj_config.cpu_family self._cpu = proj_config.cpu self._host_machine = proj_config.host_machine self._build_machine = proj_config.build_machine self._meson_options.update(proj_config.meson_options) self._headers_not_supported.extend(proj_config.headers_not_supported) self._symbols_not_supported.extend(proj_config.symbols_not_supported) self._functions_not_supported.extend(proj_config.functions_not_supported) self._links_not_supported.extend(proj_config.links_not_supported) self._ext_dependencies.update(proj_config.ext_dependencies) return self def deepcopy(self): proj = ProjectConfig() proj._build = self._build proj._name = self._name proj._inherits_from = self._inherits_from proj._cpu_family = self._cpu_family proj._cpu = self._cpu proj._host_machine = self._host_machine proj._build_machine = self._build_machine proj._meson_options.update(self._meson_options) proj._headers_not_supported.extend(self._headers_not_supported) proj._symbols_not_supported.extend(self._symbols_not_supported) proj._functions_not_supported.extend(self._functions_not_supported) proj._links_not_supported.extend(self._links_not_supported) proj._ext_dependencies.update(self._ext_dependencies) return proj @property def build(self): return self._build @property def name(self): return self._name @property def inherits_from(self): return self._inherits_from @property def cpu(self): return self._cpu @property def cpu_family(self): return self._cpu_family @property def host_machine(self): return self._host_machine @property def build_machine(self): return self._build_machine @property def meson_options(self): return self._meson_options @property def headers_not_supported(self): return self._headers_not_supported @property def symbols_not_supported(self): return self._symbols_not_supported @property def functions_not_supported(self): return self._functions_not_supported @property def links_not_supported(self): return self._links_not_supported @property def ext_dependencies(self): return self._ext_dependencies def __str__(self): return f""" @ProjectConfig: {self._name} inherits_from: {self._inherits_from} build: {self._build} cpu_family: {self._cpu_family} cpu: {self._cpu} host_machine: {self._host_machine} build_machine: {self._build_machine} meson_options: {self._meson_options} headers_not_supported: {self._headers_not_supported} symbols_not_supported: {self._symbols_not_supported} functions_not_supported: {self._functions_not_supported} links_not_supported: {self._links_not_supported} ext_dependencies: {self._ext_dependencies} """ class MesonProjectState: """ Represents a singular build config """ def __init__(self): self.static_libraries: list[StaticLibrary] = [] self.custom_targets: list[CustomTarget] = [] self.custom_py_targets: list[PythonCustomTarget] = [] self.include_dirs: list[IncludeDirectories] = [] def __str__(self): return ( f'static libraries len: {len(self.static_libraries)}\n' f'custom targets len: {len(self.custom_targets)}\n' f'custom py targets len: {len(self.custom_py_targets)}\n' f'include dirs len: {len(self.include_dirs)}\n' )