hatch_build.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. from __future__ import annotations
  2. import os
  3. import platform
  4. import stat
  5. from pathlib import Path
  6. from hatchling.builders.hooks.plugin.interface import BuildHookInterface
  7. _PLATFORMS = {
  8. "linux-x64": ("manylinux_2_28_x86_64", "dsh-jsonrpc-agent-pkg-linux-x64"),
  9. "linux-arm64": ("manylinux_2_28_aarch64", "dsh-jsonrpc-agent-pkg-linux-arm64"),
  10. "macos-arm64": ("macosx_11_0_arm64", "dsh-jsonrpc-agent-pkg-macos-arm64"),
  11. }
  12. _SPAWN_HELPER_SUFFIX = "-spawn-helper"
  13. def _spawn_helper_binary_target(header: bytes) -> str | None:
  14. if (
  15. len(header) >= 20
  16. and header[:4] == b"\x7fELF"
  17. and header[4] == 2
  18. and header[5] == 1
  19. ):
  20. machine = int.from_bytes(header[18:20], "little")
  21. if machine == 62:
  22. return "linux-x64"
  23. if machine == 183:
  24. return "linux-arm64"
  25. if len(header) >= 8 and header[:4] == b"\xcf\xfa\xed\xfe":
  26. if int.from_bytes(header[4:8], "little") == 0x0100000C:
  27. return "macos-arm64"
  28. return None
  29. def _validate_spawn_helper(path: Path, expected_target: str) -> None:
  30. with path.open("rb") as helper:
  31. actual_target = _spawn_helper_binary_target(helper.read(20))
  32. if actual_target != expected_target:
  33. raise RuntimeError(
  34. f"runtime spawn helper binary mismatch: expected {expected_target}, "
  35. f"found {actual_target or 'unsupported format or architecture'} at {path}"
  36. )
  37. def _host_platform_tag() -> str:
  38. machine = platform.machine().lower()
  39. arch = "arm64" if machine in {"arm64", "aarch64"} else "x64" if machine in {"x86_64", "amd64"} else machine
  40. system = platform.system().lower()
  41. key = f"macos-{arch}" if system == "darwin" else f"linux-{arch}" if system == "linux" else system
  42. try:
  43. return _PLATFORMS[key][0]
  44. except KeyError as exc:
  45. raise RuntimeError(f"unsupported deepseek-harness-runtime-bin build platform: {key}") from exc
  46. class RuntimeBuildHook(BuildHookInterface):
  47. """Assign the native wheel tag and reject incomplete or mixed-platform payloads."""
  48. def initialize(self, version: str, build_data: dict[str, object]) -> None:
  49. if version == "editable":
  50. return
  51. if self.target_name == "sdist":
  52. raise RuntimeError(
  53. "deepseek-harness-runtime-bin is wheel-only; build and publish platform wheels only."
  54. )
  55. platform_tag = os.environ.get("DSH_RUNTIME_PLATFORM_TAG") or _host_platform_tag()
  56. matches = [(key, value) for key, value in _PLATFORMS.items() if value[0] == platform_tag]
  57. if len(matches) != 1:
  58. supported = ", ".join(value[0] for value in _PLATFORMS.values())
  59. raise RuntimeError(
  60. f"unsupported DSH_RUNTIME_PLATFORM_TAG {platform_tag!r}; expected one of {supported}"
  61. )
  62. expected_target, (_, expected_executable) = matches[0]
  63. runtime_dir = Path(self.root) / "src" / "deepseek_harness_runtime" / "runtime"
  64. runtime_files = sorted(runtime_dir.glob("dsh-jsonrpc-agent-pkg-*") if runtime_dir.is_dir() else [])
  65. executables = [path for path in runtime_files if not path.name.endswith(_SPAWN_HELPER_SUFFIX)]
  66. helpers = [path for path in runtime_files if path.name.endswith(_SPAWN_HELPER_SUFFIX)]
  67. if [path.name for path in executables] != [expected_executable]:
  68. found = ", ".join(path.name for path in executables) or "none"
  69. raise RuntimeError(
  70. f"runtime wheel {platform_tag} must contain only {expected_executable}; found {found}"
  71. )
  72. expected_helper = f"{expected_executable}{_SPAWN_HELPER_SUFFIX}"
  73. if [path.name for path in helpers] != [expected_helper]:
  74. found = ", ".join(path.name for path in helpers) or "none"
  75. raise RuntimeError(
  76. f"runtime wheel {platform_tag} must contain only {expected_helper}; found {found}"
  77. )
  78. for executable in [executables[0], helpers[0]]:
  79. if executable.stat().st_mode & stat.S_IXUSR == 0:
  80. raise RuntimeError(f"runtime executable is not executable: {executable}")
  81. _validate_spawn_helper(helpers[0], expected_target)
  82. build_data["pure_python"] = False
  83. build_data["infer_tag"] = False
  84. build_data["tag"] = f"py3-none-{platform_tag}"