|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
3 | | -from os import environ, system as system_call |
| 3 | +from os import environ |
4 | 4 | from pathlib import Path |
5 | 5 | from re import match |
6 | 6 | from shutil import which |
7 | | -from sys import executable, platform as sys_platform, version_info |
| 7 | +from sys import executable, platform as sys_platform |
8 | 8 | from sysconfig import get_path |
9 | | -from typing import Any, Dict, List, Literal, Optional |
| 9 | +from typing import Any, List, Literal, Optional |
10 | 10 |
|
11 | 11 | from pydantic import AliasChoices, BaseModel, Field, field_validator, model_validator |
12 | 12 |
|
13 | 13 | __all__ = ( |
14 | | - "HatchCppBuildConfig", |
| 14 | + "BuildType", |
| 15 | + "CompilerToolchain", |
| 16 | + "Language", |
| 17 | + "Binding", |
| 18 | + "Platform", |
| 19 | + "PlatformDefaults", |
15 | 20 | "HatchCppLibrary", |
16 | 21 | "HatchCppPlatform", |
17 | | - "HatchCppBuildPlan", |
18 | 22 | ) |
19 | 23 |
|
| 24 | + |
20 | 25 | BuildType = Literal["debug", "release"] |
21 | 26 | CompilerToolchain = Literal["gcc", "clang", "msvc"] |
22 | 27 | Language = Literal["c", "c++"] |
@@ -231,118 +236,3 @@ def get_link_flags(self, library: HatchCppLibrary, build_type: BuildType = "rele |
231 | 236 | while flags.count(" "): |
232 | 237 | flags = flags.replace(" ", " ") |
233 | 238 | return flags |
234 | | - |
235 | | - |
236 | | -class HatchCppCmakeConfiguration(BaseModel): |
237 | | - root: Path |
238 | | - build: Path = Field(default_factory=lambda: Path("build")) |
239 | | - install: Optional[Path] = Field(default=None) |
240 | | - |
241 | | - cmake_arg_prefix: Optional[str] = Field(default=None) |
242 | | - cmake_args: Dict[str, str] = Field(default_factory=dict) |
243 | | - cmake_env_args: Dict[Platform, Dict[str, str]] = Field(default_factory=dict) |
244 | | - |
245 | | - include_flags: Optional[Dict[str, Any]] = Field(default=None) |
246 | | - |
247 | | - |
248 | | -class HatchCppBuildConfig(BaseModel): |
249 | | - """Build config values for Hatch C++ Builder.""" |
250 | | - |
251 | | - verbose: Optional[bool] = Field(default=False) |
252 | | - name: Optional[str] = Field(default=None) |
253 | | - libraries: List[HatchCppLibrary] = Field(default_factory=list) |
254 | | - cmake: Optional[HatchCppCmakeConfiguration] = Field(default=None) |
255 | | - platform: Optional[HatchCppPlatform] = Field(default_factory=HatchCppPlatform.default) |
256 | | - |
257 | | - @model_validator(mode="wrap") |
258 | | - @classmethod |
259 | | - def validate_model(cls, data, handler): |
260 | | - if "toolchain" in data: |
261 | | - data["platform"] = HatchCppPlatform.platform_for_toolchain(data["toolchain"]) |
262 | | - data.pop("toolchain") |
263 | | - elif "platform" not in data: |
264 | | - data["platform"] = HatchCppPlatform.default() |
265 | | - if "cc" in data: |
266 | | - data["platform"].cc = data["cc"] |
267 | | - data.pop("cc") |
268 | | - if "cxx" in data: |
269 | | - data["platform"].cxx = data["cxx"] |
270 | | - data.pop("cxx") |
271 | | - if "ld" in data: |
272 | | - data["platform"].ld = data["ld"] |
273 | | - data.pop("ld") |
274 | | - model = handler(data) |
275 | | - if model.cmake and model.libraries: |
276 | | - raise ValueError("Must not provide libraries when using cmake toolchain.") |
277 | | - return model |
278 | | - |
279 | | - |
280 | | -class HatchCppBuildPlan(HatchCppBuildConfig): |
281 | | - build_type: BuildType = "release" |
282 | | - commands: List[str] = Field(default_factory=list) |
283 | | - |
284 | | - def generate(self): |
285 | | - self.commands = [] |
286 | | - if self.libraries: |
287 | | - for library in self.libraries: |
288 | | - compile_flags = self.platform.get_compile_flags(library, self.build_type) |
289 | | - link_flags = self.platform.get_link_flags(library, self.build_type) |
290 | | - self.commands.append( |
291 | | - f"{self.platform.cc if library.language == 'c' else self.platform.cxx} {' '.join(library.sources)} {compile_flags} {link_flags}" |
292 | | - ) |
293 | | - elif self.cmake: |
294 | | - # Derive prefix |
295 | | - if self.cmake.cmake_arg_prefix is None: |
296 | | - self.cmake.cmake_arg_prefix = f"{self.name.replace('.', '_').replace('-', '_').upper()}_" |
297 | | - |
298 | | - # Append base command |
299 | | - self.commands.append(f"cmake {Path(self.cmake.root).parent} -DCMAKE_BUILD_TYPE={self.build_type} -B {self.cmake.build}") |
300 | | - |
301 | | - # Setup install path |
302 | | - if self.cmake.install: |
303 | | - self.commands[-1] += f" -DCMAKE_INSTALL_PREFIX={self.cmake.install}" |
304 | | - else: |
305 | | - self.commands[-1] += f" -DCMAKE_INSTALL_PREFIX={Path(self.cmake.root).parent}" |
306 | | - |
307 | | - # TODO: CMAKE_CXX_COMPILER |
308 | | - if self.platform.platform == "win32": |
309 | | - # TODO: prefix? |
310 | | - self.commands[-1] += f' -G "{environ.get("GENERATOR", "Visual Studio 17 2022")}"' |
311 | | - |
312 | | - # Put in CMake flags |
313 | | - args = self.cmake.cmake_args.copy() |
314 | | - for platform, env_args in self.cmake.cmake_env_args.items(): |
315 | | - if platform == self.platform.platform: |
316 | | - for key, value in env_args.items(): |
317 | | - args[key] = value |
318 | | - for key, value in args.items(): |
319 | | - self.commands[-1] += f" -D{self.cmake.cmake_arg_prefix}{key.upper()}={value}" |
320 | | - |
321 | | - # Include customs |
322 | | - if self.cmake.include_flags: |
323 | | - if self.cmake.include_flags.get("python_version", False): |
324 | | - self.commands[-1] += f" -D{self.cmake.cmake_arg_prefix}PYTHON_VERSION={version_info.major}.{version_info.minor}" |
325 | | - if self.cmake.include_flags.get("manylinux", False) and self.platform.platform == "linux": |
326 | | - self.commands[-1] += f" -D{self.cmake.cmake_arg_prefix}MANYLINUX=ON" |
327 | | - |
328 | | - # Include mac deployment target |
329 | | - if self.platform.platform == "darwin": |
330 | | - self.commands[-1] += f" -DCMAKE_OSX_DEPLOYMENT_TARGET={environ.get('OSX_DEPLOYMENT_TARGET', '11')}" |
331 | | - |
332 | | - # Append build command |
333 | | - self.commands.append(f"cmake --build {self.cmake.build} --config {self.build_type}") |
334 | | - |
335 | | - # Append install command |
336 | | - self.commands.append(f"cmake --install {self.cmake.build} --config {self.build_type}") |
337 | | - |
338 | | - return self.commands |
339 | | - |
340 | | - def execute(self): |
341 | | - for command in self.commands: |
342 | | - system_call(command) |
343 | | - return self.commands |
344 | | - |
345 | | - def cleanup(self): |
346 | | - if self.platform.platform == "win32": |
347 | | - for temp_obj in Path(".").glob("*.obj"): |
348 | | - temp_obj.unlink() |
0 commit comments