From f68a9f7df9535b4b6dc826ced140ff4546eb81a7 Mon Sep 17 00:00:00 2001 From: mementorc Date: Mon, 14 Sep 2026 17:37:29 -0500 Subject: [PATCH 1/2] Accept macOS triples in the Apple OS version split --- crossenv/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crossenv/__init__.py b/crossenv/__init__.py index b1119f1..6be885c 100644 --- a/crossenv/__init__.py +++ b/crossenv/__init__.py @@ -464,8 +464,12 @@ def run_compiler(arg): ) def _split_apple_os_version(self, value): - # Split the Apple OS version from the OS name prefix. - if value.startswith("ios"): + # Split the Apple OS version from the OS name prefix. On macOS the + # version is the Darwin kernel version, not the macOS version, so it + # is only used to normalize the triple for comparison. + if value.startswith("darwin"): + offset = 6 + elif value.startswith("ios"): offset = 3 elif value.startswith("tvos"): offset = 4 From 38bda56a0cafd1466f52a9df1ac4caff0f3f6d38 Mon Sep 17 00:00:00 2001 From: mementorc Date: Tue, 15 Sep 2026 17:04:11 -0500 Subject: [PATCH 2/2] Split Apple OS version at first digit Covers darwin, macos and other Apple OS names without a fixed list. Add unit tests for the split and triple cleanup. --- crossenv/__init__.py | 18 ++++--------- tests/test_triples.py | 59 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 tests/test_triples.py diff --git a/crossenv/__init__.py b/crossenv/__init__.py index 6be885c..eab8f5f 100644 --- a/crossenv/__init__.py +++ b/crossenv/__init__.py @@ -464,19 +464,11 @@ def run_compiler(arg): ) def _split_apple_os_version(self, value): - # Split the Apple OS version from the OS name prefix. On macOS the - # version is the Darwin kernel version, not the macOS version, so it - # is only used to normalize the triple for comparison. - if value.startswith("darwin"): - offset = 6 - elif value.startswith("ios"): - offset = 3 - elif value.startswith("tvos"): - offset = 4 - elif value.startswith("watchos"): - offset = 7 - else: - raise ValueError("Unknown Apple compiler triple.") + # Split the Apple OS version from the OS name prefix (e.g. ios13.0 -> + # ios, 13.0). No Apple OS name contains a digit, so the version starts + # at the first one. On macOS the version is the Darwin kernel version + # (e.g. darwin23.4.0), not the macOS version. + offset = next((i for i, c in enumerate(value) if c.isdigit()), len(value)) return value[:offset], value[offset:] def _clean_triple(self, triple): diff --git a/tests/test_triples.py b/tests/test_triples.py new file mode 100644 index 0000000..1f8f170 --- /dev/null +++ b/tests/test_triples.py @@ -0,0 +1,59 @@ +################################################# +# Compiler triple parsing (no crossenv required) +################################################# + +import pytest + +from crossenv import CrossEnvBuilder + + +@pytest.fixture +def builder(): + # These helpers only parse strings, so skip __init__ and its environment + # checks. They run on any platform. + return CrossEnvBuilder.__new__(CrossEnvBuilder) + + +def test_split_apple_os_version(builder): + expected = { + "ios13.0": ("ios", "13.0"), + "ios": ("ios", ""), + "tvos17.0": ("tvos", "17.0"), + "tvos": ("tvos", ""), + "watchos10.0": ("watchos", "10.0"), + "watchos": ("watchos", ""), + "darwin23.4.0": ("darwin", "23.4.0"), + "darwin": ("darwin", ""), + # Previously rejected as unknown + "macos14.0": ("macos", "14.0"), + "macosx14.0": ("macosx", "14.0"), + "xros1.0": ("xros", "1.0"), + } + actual = {value: builder._split_apple_os_version(value) for value in expected} + assert actual == expected + + +def test_clean_triple(builder): + expected = { + # Apple: arm64 -> aarch64, OS version removed. The clang -dumpmachine + # and HOST_GNU_TYPE forms must clean to the same value. + "arm64-apple-ios13.0": ["aarch64", "apple", "ios"], + "aarch64-apple-ios": ["aarch64", "apple", "ios"], + "arm64-apple-tvos17.0": ["aarch64", "apple", "tvos"], + "arm64-apple-watchos10.0": ["aarch64", "apple", "watchos"], + "arm64-apple-darwin23.4.0": ["aarch64", "apple", "darwin"], + "aarch64-apple-darwin": ["aarch64", "apple", "darwin"], + "x86_64-apple-darwin23.4.0": ["x86_64", "apple", "darwin"], + # Apple simulator: 4 parts, not compared + "arm64-apple-ios13.0-simulator": None, + # Non-Apple: vendor dropped from 4-part triples + "x86_64-linux-gnu": ["x86_64", "linux", "gnu"], + "x86_64-pc-linux-gnu": ["x86_64", "linux", "gnu"], + "aarch64-unknown-linux-gnu": ["aarch64", "linux", "gnu"], + # Other forms + "x86_64": None, + "aarch64-linux": None, + "a-b-c-d-e": None, + } + actual = {triple: builder._clean_triple(triple) for triple in expected} + assert actual == expected