ha(packaging): musllinux-wheel для HA OS и статический C++-рантайм

- _corebuild.musl_platform_tag(): на musl (Alpine/HA OS) bdist_wheel
  выпускает py3-none-musllinux_X_Y_<arch> вместо linux_<arch> — иначе pip
  ставит glibc-сборку и dlopen падает на ld-linux-x86-64.so.2
- shared-библиотека линкуется со -static-libstdc++ -static-libgcc (gcc):
  NEEDED только libm/libc (проверено readelf), меньше зависимостей у HA OS
- Gitea Actions: job build-musllinux (container python:3.12-alpine) собирает
  и публикует musl-wheel; build-glibc — как раньше; общий
  scripts/publish-gitea-pypi.sh с пропуском уже загруженных файлов
- тесты musl_platform_tag; RELEASE_HA §1.1-1.4 (выбор wheel, переустановка
  на HA OS, ручная сборка musllinux без container:); README troubleshooting
This commit is contained in:
2026-09-29 16:20:21 +03:00
parent 49d5533cd1
commit f9d917c66d
8 changed files with 270 additions and 58 deletions
+25
View File
@@ -8,6 +8,8 @@ from __future__ import annotations
import argparse
import os
import platform
import re
import shutil
import subprocess
import sys
@@ -22,6 +24,29 @@ LIB_GLOBS = (
)
def musl_platform_tag() -> str | None:
"""musllinux-тег, если сборка идёт на musl (Alpine/HA OS), иначе None.
wheel-тег `linux_<arch>` на musl вводит pip в заблуждение: он ставит
glibc-сборку на Alpine, и dlopen падает на отсутствующем
ld-linux-<arch>.so.2. На musl отдаём корректный `musllinux_X_Y_<arch>`.
"""
machine = platform.machine()
try:
result = subprocess.run(
["ldd", "--version"], capture_output=True, text=True, timeout=10
)
except (OSError, subprocess.SubprocessError):
return None
text = (result.stdout or "") + (result.stderr or "")
if "musl" not in text.lower():
return None
match = re.search(r"(\d+)\.(\d+)", text)
major, minor = (match.group(1), match.group(2)) if match else ("1", "2")
arch = {"amd64": "x86_64", "arm64": "aarch64"}.get(machine, machine)
return f"musllinux_{major}_{minor}_{arch}"
def source_root() -> Path | None:
"""Корень монорепо (CMakeLists.txt + include/fgl-aircon)."""
env = os.environ.get("FGLAIR_SOURCE_ROOT")