Skip to content

Commit 593419e

Browse files
authored
update cibuildwheels and simplify os detection (#558)
1 parent 7ea29e3 commit 593419e

File tree

3 files changed

+59
-65
lines changed

3 files changed

+59
-65
lines changed

.github/workflows/build-rtc.yml

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,13 @@ jobs:
7979
with:
8080
submodules: true
8181

82-
- uses: actions/setup-python@v4
83-
84-
- name: Install cibuildwheel
85-
if: runner.os != 'macOS'
86-
run: python3 -m pip install cibuildwheel==2.17.0
87-
88-
- name: Install cibuildwheel on macOS
89-
if: runner.os == 'macOS'
90-
run: python3 -m pip install --break-system-packages cibuildwheel==2.17.0
82+
- uses: actions/setup-python@v5
83+
id: setup-python
84+
with:
85+
python-version: "3.11"
9186

9287
- name: Build wheels
93-
run: python3 -m cibuildwheel --output-dir dist
88+
run: pipx run --python '${{ steps.setup-python.outputs.python-path }}' cibuildwheel==3.3.1 --output-dir dist
9489
env:
9590
CIBW_ARCHS: ${{ matrix.archs }}
9691

livekit-rtc/hatch_build.py

Lines changed: 52 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,21 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
"""Custom build hook for platform-specific wheel tagging.
16+
17+
This hook generates py3-none-{platform} wheels because the native FFI libraries
18+
(.so/.dylib/.dll) don't use the Python C API - they're loaded via ctypes at
19+
runtime. This makes them compatible with any Python 3.x version.
20+
21+
Why not use sysconfig.get_platform()?
22+
- On macOS, it returns the Python interpreter's compile-time deployment target,
23+
not the MACOSX_DEPLOYMENT_TARGET from the environment that cibuildwheel sets.
24+
25+
Why not let hatchling infer the tag?
26+
- hatchling doesn't recognize bundled .so/.dylib/.dll as platform-specific
27+
unless we explicitly set pure_python=False and provide the tag.
28+
"""
29+
1530
import os
1631
import platform
1732
import sys
@@ -21,65 +36,57 @@
2136

2237
class CustomBuildHook(BuildHookInterface):
2338
def initialize(self, version, build_data):
24-
"""Force platform-specific wheel with py3-none tag.
25-
26-
The native libraries (.so, .dylib, .dll) are not Python C extensions -
27-
they're standalone FFI libraries loaded at runtime. This means they
28-
don't depend on a specific CPython ABI, so we use py3-none to indicate
29-
compatibility with any Python 3.x version while keeping the platform tag.
30-
"""
3139
build_data["pure_python"] = False
3240
build_data["infer_tag"] = False
41+
build_data["tag"] = f"py3-none-{self._get_platform_tag()}"
3342

43+
def _get_platform_tag(self):
44+
"""Get the wheel platform tag for the current/target platform."""
3445
if sys.platform == "darwin":
35-
plat_tag = self._get_macos_platform_tag()
46+
return self._get_macos_tag()
47+
elif sys.platform == "linux":
48+
# Return linux tag; cibuildwheel's auditwheel converts to manylinux
49+
return f"linux_{platform.machine()}"
50+
elif sys.platform == "win32":
51+
return f"win_{self._normalize_arch(platform.machine())}"
3652
else:
37-
from packaging.tags import sys_tags
53+
return f"{platform.system().lower()}_{platform.machine()}"
3854

39-
tag = next(
40-
t
41-
for t in sys_tags()
42-
if "manylinux" not in t.platform and "musllinux" not in t.platform
43-
)
44-
plat_tag = tag.platform
55+
def _get_macos_tag(self):
56+
"""Build macOS platform tag respecting cross-compilation settings.
4557
46-
build_data["tag"] = f"py3-none-{plat_tag}"
47-
48-
def _get_macos_platform_tag(self):
49-
"""Build macOS platform tag from MACOSX_DEPLOYMENT_TARGET env var."""
50-
deployment_target = os.environ.get("MACOSX_DEPLOYMENT_TARGET")
51-
if not deployment_target:
52-
# Fall back to current macOS version
53-
deployment_target = platform.mac_ver()[0]
54-
# Use only major.minor
55-
parts = deployment_target.split(".")
56-
deployment_target = f"{parts[0]}.{parts[1] if len(parts) > 1 else '0'}"
57-
58-
# Convert version to wheel tag format (e.g., "11.0" -> "11_0")
59-
version_tag = deployment_target.replace(".", "_")
60-
61-
# Get target architecture from ARCHFLAGS (set by cibuildwheel for cross-compilation)
62-
# or fall back to host machine architecture
63-
arch = self._get_macos_target_arch()
58+
cibuildwheel sets MACOSX_DEPLOYMENT_TARGET and ARCHFLAGS when building.
59+
We must use these rather than the host machine's values.
60+
"""
61+
target = os.environ.get("MACOSX_DEPLOYMENT_TARGET")
62+
if not target:
63+
# Fall back to current macOS version (for local dev builds)
64+
target = platform.mac_ver()[0]
65+
parts = target.split(".")
66+
target = f"{parts[0]}.{parts[1] if len(parts) > 1 else '0'}"
6467

68+
version_tag = target.replace(".", "_")
69+
arch = self._get_target_arch()
6570
return f"macosx_{version_tag}_{arch}"
6671

67-
def _get_macos_target_arch(self):
68-
"""Detect target architecture for macOS builds.
72+
def _get_target_arch(self):
73+
"""Detect target architecture, respecting ARCHFLAGS for cross-compilation.
6974
70-
Cibuildwheel sets ARCHFLAGS for cross-compilation (e.g., "-arch x86_64").
71-
Falls back to host machine architecture if not set.
75+
cibuildwheel sets ARCHFLAGS="-arch arm64" or "-arch x86_64" when
76+
cross-compiling on macOS.
7277
"""
7378
archflags = os.environ.get("ARCHFLAGS", "")
7479
if "-arch arm64" in archflags:
7580
return "arm64"
76-
elif "-arch x86_64" in archflags:
81+
if "-arch x86_64" in archflags:
7782
return "x86_64"
83+
return self._normalize_arch(platform.machine())
7884

79-
# Fall back to host architecture
80-
machine = platform.machine()
81-
if machine == "x86_64":
82-
return "x86_64"
83-
elif machine == "arm64":
84-
return "arm64"
85-
return machine
85+
def _normalize_arch(self, arch):
86+
"""Normalize architecture names to wheel tag format."""
87+
return {
88+
"AMD64": "amd64",
89+
"x86_64": "x86_64",
90+
"arm64": "arm64",
91+
"aarch64": "aarch64",
92+
}.get(arch, arch.lower())

livekit-rtc/pyproject.toml

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,9 @@ include = ["/livekit", "/rust-sdks"]
5454

5555
[tool.cibuildwheel]
5656
build = "cp39-*"
57-
skip = "*-musllinux_*" # not supported (libwebrtc is using glibc)
57+
skip = "*-musllinux_*" # not supported (libwebrtc requires glibc)
5858
before-build = "pip install requests && python rust-sdks/download_ffi.py --output livekit/rtc/resources"
59-
60-
manylinux-x86_64-image = "manylinux_2_28"
61-
manylinux-i686-image = "manylinux_2_28"
62-
manylinux-aarch64-image = "manylinux_2_28"
63-
manylinux-ppc64le-image = "manylinux_2_28"
64-
manylinux-s390x-image = "manylinux_2_28"
65-
manylinux-pypy_x86_64-image = "manylinux_2_28"
66-
manylinux-pypy_i686-image = "manylinux_2_28"
67-
manylinux-pypy_aarch64-image = "manylinux_2_28"
59+
# Note: manylinux_2_28 is the default in cibuildwheel 3.x, no explicit config needed
6860

6961
# macOS deployment targets must match the FFI binaries (see rust-sdks/.github/workflows/ffi-builds.yml)
7062
# x86_64 supports macOS 10.15+, arm64 requires macOS 11.0+

0 commit comments

Comments
 (0)