1""" 2Copyright 2024 Google LLC 3SPDX-License-Identifier: MIT 4""" 5 6from enum import Enum 7 8 9class LibraryType(Enum): 10 Library = 0 # Default undefined library value 11 LibraryShared = 1 12 LibraryStatic = 2 13 14 15class IncludeDirectories: 16 def __init__(self): 17 self.name: str = '' 18 self.dirs: list[str] = [] 19 self.visibility: list[str] = [] 20 21 22class StaticLibrary(IncludeDirectories): 23 """ 24 Represents the cc_library_static / cc_library module in build files 25 """ 26 27 def __init__(self): 28 """ 29 Attributes here favor a Soong attribute naming scheme 30 """ 31 super().__init__() 32 self.srcs: list[str] = [] 33 self.library_type: LibraryType = ( 34 LibraryType.Library 35 ) # Can be cc_library_static or cc_library_shared 36 # In Bazel, these headers are one merged list. 37 self.generated_headers: list[str] = [] 38 self.generated_sources: list[str] = [] 39 # In Bazel, these c options are copts 40 self.copts: list[str] = [] 41 self.cstd: str = '' 42 self.cpp_std: str = '' 43 self.conlyflags: list[str] = [] 44 self.cppflags: list[str] = [] 45 46 self.deps: list[str] = [] 47 self.target_compatible_with: list[str] = [] 48 49 self.local_include_dirs: list[str] = [] 50 self.static_libs: list[str] = [] 51 self.whole_static_libs: list[str] = [] 52 self.shared_libs: list[str] = [] 53 self.header_libs: list[str] = [] 54 55 @property 56 def hdrs(self): 57 return self.generated_headers + self.generated_sources 58 59 def __str__(self): 60 return f'@StaticLibrary: name: {self.name}, LibraryType: {self.library_type}' 61 62 63class CustomTarget: 64 """ 65 Denoted as genrule in both build files 66 """ 67 68 def __init__(self): 69 self.name: str = '' 70 self.srcs: list[str] = [] 71 self.out: list[str] = [] # 'outs' in bazel 72 self.tools: list[str] = [] 73 self.export_include_dirs: list[str] = [] 74 self.cmd: str = '' 75 76 def __str__(self): 77 return ( 78 f'name: {self.name}\n' 79 f'srcs: {self.srcs}\n' 80 f'out: {self.out}\n' 81 f'tools: {self.tools}\n' 82 f'export_include_dirs: {self.export_include_dirs}\n' 83 f'cmd: {self.cmd}' 84 ) 85 86 87class PythonCustomTarget(CustomTarget): 88 def __init__(self): 89 super().__init__() 90 self.main: str = '' 91 self.libs: list[str] = [] 92 self.imports: list[str] = [] 93 self.version = {} 94 95 def __str__(self): 96 return ( 97 f'name: {self.name}\n' 98 f'main: {self.main}\n' 99 f'srcs: {self.srcs}\n' 100 f'libs: {self.libs}' 101 ) 102 103 104class ProjectConfig: 105 """ 106 Class that represents a singular project_config within aosp.toml/fuchsia.toml 107 in python objects. There are multiple project_config within each .toml 108 file 109 """ 110 def __init__(self): 111 self._build: str = '' # Global across all configs 112 self._name: str = '' # name of this config 113 self._inherits_from = '' 114 # project_config.host_machine 115 self._cpu_family: str = '' 116 self._cpu: str = '' 117 self._host_machine: str = '' 118 self._build_machine: str = '' 119 # project_config.meson_options 120 self._meson_options: dict[str, int | str] = {} 121 # project_config.header_not_supported 122 self._headers_not_supported: list[str] = [] 123 # project_config.symbol_not_supported 124 self._symbols_not_supported: list[str] = [] 125 # project_config.function_not_supported 126 self._functions_not_supported: list[str] = [] 127 # project_config.link_not_supported 128 self._links_not_supported: list[str] = [] 129 # project_config.ext_dependencies 130 self._ext_dependencies: dict[str, list[dict[str, str | int]]] = {} 131 # Example structure for ext_dependencies 132 # { 133 # zlib = [ 134 # { 135 # 'target_name': '@zlib//:zlib', 136 # 'target_type': 2 137 # }, 138 # ... 139 # ] 140 141 @staticmethod 142 def create_project_config(build, **kwargs): 143 project_config = ProjectConfig() 144 project_config._build = build # Global across all configs 145 project_config._name = kwargs.get('name') # name of this config 146 project_config._inherits_from = kwargs.get('inherits_from') 147 project_config._cpu_family = kwargs.get('host_machine').get('cpu_family') 148 project_config._cpu = kwargs.get('host_machine').get('cpu') 149 project_config._host_machine = kwargs.get('host_machine').get('host_machine') 150 project_config._build_machine = kwargs.get('host_machine').get('build_machine') 151 project_config._meson_options = kwargs.get('meson_options') 152 project_config._headers_not_supported = kwargs.get('header_not_supported').get( 153 'headers' 154 ) 155 project_config._symbols_not_supported = kwargs.get('symbol_not_supported').get( 156 'symbols' 157 ) 158 project_config._functions_not_supported = kwargs.get( 159 'function_not_supported' 160 ).get('functions') 161 project_config._links_not_supported = kwargs.get('link_not_supported').get( 162 'links' 163 ) 164 project_config._ext_dependencies = kwargs.get('ext_dependencies') 165 return project_config 166 167 def extend(self, proj_config): 168 """ 169 Appends to the current instance of ProjectConfig with another 170 This also overrides attributes like self._name to the given param 171 :param proj_config: ProjectConfig 172 :return: ProjectConfig 173 """ 174 self._build = proj_config.build 175 self._name = proj_config.name 176 self._inherits_from = proj_config.inherits_from 177 self._cpu_family = proj_config.cpu_family 178 self._cpu = proj_config.cpu 179 self._host_machine = proj_config.host_machine 180 self._build_machine = proj_config.build_machine 181 182 self._meson_options.update(proj_config.meson_options) 183 self._headers_not_supported.extend(proj_config.headers_not_supported) 184 self._symbols_not_supported.extend(proj_config.symbols_not_supported) 185 self._functions_not_supported.extend(proj_config.functions_not_supported) 186 self._links_not_supported.extend(proj_config.links_not_supported) 187 self._ext_dependencies.update(proj_config.ext_dependencies) 188 return self 189 190 def deepcopy(self): 191 proj = ProjectConfig() 192 proj._build = self._build 193 proj._name = self._name 194 proj._inherits_from = self._inherits_from 195 proj._cpu_family = self._cpu_family 196 proj._cpu = self._cpu 197 proj._host_machine = self._host_machine 198 proj._build_machine = self._build_machine 199 200 proj._meson_options.update(self._meson_options) 201 proj._headers_not_supported.extend(self._headers_not_supported) 202 proj._symbols_not_supported.extend(self._symbols_not_supported) 203 proj._functions_not_supported.extend(self._functions_not_supported) 204 proj._links_not_supported.extend(self._links_not_supported) 205 proj._ext_dependencies.update(self._ext_dependencies) 206 return proj 207 208 @property 209 def build(self): 210 return self._build 211 212 @property 213 def name(self): 214 return self._name 215 216 @property 217 def inherits_from(self): 218 return self._inherits_from 219 220 @property 221 def cpu(self): 222 return self._cpu 223 224 @property 225 def cpu_family(self): 226 return self._cpu_family 227 228 @property 229 def host_machine(self): 230 return self._host_machine 231 232 @property 233 def build_machine(self): 234 return self._build_machine 235 236 @property 237 def meson_options(self): 238 return self._meson_options 239 240 @property 241 def headers_not_supported(self): 242 return self._headers_not_supported 243 244 @property 245 def symbols_not_supported(self): 246 return self._symbols_not_supported 247 248 @property 249 def functions_not_supported(self): 250 return self._functions_not_supported 251 252 @property 253 def links_not_supported(self): 254 return self._links_not_supported 255 256 @property 257 def ext_dependencies(self): 258 return self._ext_dependencies 259 260 def __str__(self): 261 return f""" 262 @ProjectConfig: {self._name} 263 inherits_from: {self._inherits_from} 264 build: {self._build} 265 cpu_family: {self._cpu_family} 266 cpu: {self._cpu} 267 host_machine: {self._host_machine} 268 build_machine: {self._build_machine} 269 meson_options: {self._meson_options} 270 headers_not_supported: {self._headers_not_supported} 271 symbols_not_supported: {self._symbols_not_supported} 272 functions_not_supported: {self._functions_not_supported} 273 links_not_supported: {self._links_not_supported} 274 ext_dependencies: {self._ext_dependencies} 275 """ 276 277 278class MesonProjectState: 279 """ 280 Represents a singular build config 281 """ 282 283 def __init__(self): 284 self.static_libraries: list[StaticLibrary] = [] 285 self.custom_targets: list[CustomTarget] = [] 286 self.custom_py_targets: list[PythonCustomTarget] = [] 287 self.include_dirs: list[IncludeDirectories] = [] 288 289 def __str__(self): 290 return ( 291 f'static libraries len: {len(self.static_libraries)}\n' 292 f'custom targets len: {len(self.custom_targets)}\n' 293 f'custom py targets len: {len(self.custom_py_targets)}\n' 294 f'include dirs len: {len(self.include_dirs)}\n' 295 ) 296