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.system_include_dirs: list[str] = [] 51 self.static_libs: list[str] = [] 52 self.whole_static_libs: list[str] = [] 53 self.shared_libs: list[str] = [] 54 self.header_libs: list[str] = [] 55 56 @property 57 def hdrs(self): 58 return self.generated_headers + self.generated_sources 59 60 def __str__(self): 61 return f'@StaticLibrary: name: {self.name}, LibraryType: {self.library_type}' 62 63 64class CustomTarget: 65 """ 66 Denoted as genrule in both build files 67 """ 68 69 def __init__(self): 70 self.name: str = '' 71 self.srcs: list[str] = [] 72 self.out: list[str] = [] # 'outs' in bazel 73 self.tools: list[str] = [] 74 self.export_include_dirs: list[str] = [] 75 self.cmd: str = '' 76 77 def __str__(self): 78 return ( 79 f'name: {self.name}\n' 80 f'srcs: {self.srcs}\n' 81 f'out: {self.out}\n' 82 f'tools: {self.tools}\n' 83 f'export_include_dirs: {self.export_include_dirs}\n' 84 f'cmd: {self.cmd}' 85 ) 86 87 88class PythonCustomTarget(CustomTarget): 89 def __init__(self): 90 super().__init__() 91 self.main: str = '' 92 self.libs: list[str] = [] 93 self.imports: list[str] = [] 94 self.version = {} 95 96 def __str__(self): 97 return ( 98 f'name: {self.name}\n' 99 f'main: {self.main}\n' 100 f'srcs: {self.srcs}\n' 101 f'libs: {self.libs}' 102 ) 103 104 105class ProjectConfig: 106 """ 107 Class that represents a singular project_config within aosp.toml/fuchsia.toml 108 in python objects. There are multiple project_config within each .toml 109 file 110 """ 111 def __init__(self): 112 self._build: str = '' # Global across all configs 113 self._name: str = '' # name of this config 114 self._inherits_from = '' 115 # project_config.host_machine 116 self._cpu_family: str = '' 117 self._cpu: str = '' 118 self._host_machine: str = '' 119 self._build_machine: str = '' 120 # project_config.meson_options 121 self._meson_options: dict[str, int | str] = {} 122 # project_config.header_not_supported 123 self._headers_not_supported: list[str] = [] 124 # project_config.symbol_not_supported 125 self._symbols_not_supported: list[str] = [] 126 # project_config.function_not_supported 127 self._functions_not_supported: list[str] = [] 128 # project_config.link_not_supported 129 self._links_not_supported: list[str] = [] 130 # project_config.ext_dependencies 131 self._ext_dependencies: dict[str, list[dict[str, str | int]]] = {} 132 # Example structure for ext_dependencies 133 # { 134 # zlib = [ 135 # { 136 # 'target_name': '@zlib//:zlib', 137 # 'target_type': 2 138 # }, 139 # ... 140 # ] 141 142 @staticmethod 143 def create_project_config(build, **kwargs): 144 project_config = ProjectConfig() 145 project_config._build = build # Global across all configs 146 project_config._name = kwargs.get('name') # name of this config 147 project_config._inherits_from = kwargs.get('inherits_from') 148 project_config._cpu_family = kwargs.get('host_machine').get('cpu_family') 149 project_config._cpu = kwargs.get('host_machine').get('cpu') 150 project_config._host_machine = kwargs.get('host_machine').get('host_machine') 151 project_config._build_machine = kwargs.get('host_machine').get('build_machine') 152 project_config._meson_options = kwargs.get('meson_options') 153 project_config._headers_not_supported = kwargs.get('header_not_supported').get( 154 'headers' 155 ) 156 project_config._symbols_not_supported = kwargs.get('symbol_not_supported').get( 157 'symbols' 158 ) 159 project_config._functions_not_supported = kwargs.get( 160 'function_not_supported' 161 ).get('functions') 162 project_config._links_not_supported = kwargs.get('link_not_supported').get( 163 'links' 164 ) 165 project_config._ext_dependencies = kwargs.get('ext_dependencies') 166 return project_config 167 168 def extend(self, proj_config): 169 """ 170 Appends to the current instance of ProjectConfig with another 171 This also overrides attributes like self._name to the given param 172 :param proj_config: ProjectConfig 173 :return: ProjectConfig 174 """ 175 self._build = proj_config.build 176 self._name = proj_config.name 177 self._inherits_from = proj_config.inherits_from 178 self._cpu_family = proj_config.cpu_family 179 self._cpu = proj_config.cpu 180 self._host_machine = proj_config.host_machine 181 self._build_machine = proj_config.build_machine 182 183 self._meson_options.update(proj_config.meson_options) 184 self._headers_not_supported.extend(proj_config.headers_not_supported) 185 self._symbols_not_supported.extend(proj_config.symbols_not_supported) 186 self._functions_not_supported.extend(proj_config.functions_not_supported) 187 self._links_not_supported.extend(proj_config.links_not_supported) 188 self._ext_dependencies.update(proj_config.ext_dependencies) 189 return self 190 191 def deepcopy(self): 192 proj = ProjectConfig() 193 proj._build = self._build 194 proj._name = self._name 195 proj._inherits_from = self._inherits_from 196 proj._cpu_family = self._cpu_family 197 proj._cpu = self._cpu 198 proj._host_machine = self._host_machine 199 proj._build_machine = self._build_machine 200 201 proj._meson_options.update(self._meson_options) 202 proj._headers_not_supported.extend(self._headers_not_supported) 203 proj._symbols_not_supported.extend(self._symbols_not_supported) 204 proj._functions_not_supported.extend(self._functions_not_supported) 205 proj._links_not_supported.extend(self._links_not_supported) 206 proj._ext_dependencies.update(self._ext_dependencies) 207 return proj 208 209 @property 210 def build(self): 211 return self._build 212 213 @property 214 def name(self): 215 return self._name 216 217 @property 218 def inherits_from(self): 219 return self._inherits_from 220 221 @property 222 def cpu(self): 223 return self._cpu 224 225 @property 226 def cpu_family(self): 227 return self._cpu_family 228 229 @property 230 def host_machine(self): 231 return self._host_machine 232 233 @property 234 def build_machine(self): 235 return self._build_machine 236 237 @property 238 def meson_options(self): 239 return self._meson_options 240 241 @property 242 def headers_not_supported(self): 243 return self._headers_not_supported 244 245 @property 246 def symbols_not_supported(self): 247 return self._symbols_not_supported 248 249 @property 250 def functions_not_supported(self): 251 return self._functions_not_supported 252 253 @property 254 def links_not_supported(self): 255 return self._links_not_supported 256 257 @property 258 def ext_dependencies(self): 259 return self._ext_dependencies 260 261 def __str__(self): 262 return f""" 263 @ProjectConfig: {self._name} 264 inherits_from: {self._inherits_from} 265 build: {self._build} 266 cpu_family: {self._cpu_family} 267 cpu: {self._cpu} 268 host_machine: {self._host_machine} 269 build_machine: {self._build_machine} 270 meson_options: {self._meson_options} 271 headers_not_supported: {self._headers_not_supported} 272 symbols_not_supported: {self._symbols_not_supported} 273 functions_not_supported: {self._functions_not_supported} 274 links_not_supported: {self._links_not_supported} 275 ext_dependencies: {self._ext_dependencies} 276 """ 277 278 279class MesonProjectState: 280 """ 281 Represents a singular build config 282 """ 283 284 def __init__(self): 285 self.static_libraries: list[StaticLibrary] = [] 286 self.custom_targets: list[CustomTarget] = [] 287 self.custom_py_targets: list[PythonCustomTarget] = [] 288 self.include_dirs: list[IncludeDirectories] = [] 289 290 def __str__(self): 291 return ( 292 f'static libraries len: {len(self.static_libraries)}\n' 293 f'custom targets len: {len(self.custom_targets)}\n' 294 f'custom py targets len: {len(self.custom_py_targets)}\n' 295 f'include dirs len: {len(self.include_dirs)}\n' 296 ) 297