Skip to content

Conversation

@jameshilliard
Copy link
Contributor

This should function correctly when cross compiling unlike platform.machine.

Description

Uses sysconfig to detect target architecture correctly.


Related Issue(s)

Closes or relates to #1834


Checklist

  • I have referenced relevant issue numbers above
  • I have performed a self-review of my code and it follows
    the style guidelines of this project
  • I have added new or used existing tests that prove my fix
    is effective or that my feature works
  • I have added necessary documentation (if appropriate) and
    updated the changelog
  • I have added an AI assistance disclosure file (required!)
    in this PR

This should function correctly when cross compiling unlike
platform.machine.
@oberstet
Copy link
Contributor

oberstet commented Jan 2, 2026

Review of PR #1835

Thanks for the contribution! Your change to use sysconfig.get_platform() is on the right track, but the fix is incomplete.

The Root Cause

The problem has two parts:

  1. Architecture detection uses platform.machine() which returns the HOST architecture (x86_64), not the TARGET (aarch64)
  2. -march=native is used for "local source builds" but this is invalid for cross-compilation

Your PR fixes part 1, but not part 2.

Why the Current PR is Incomplete

After your change, the code path is:

machine = sysconfig.get_platform().lower().split("-")[-1]  # Now correctly: "aarch64"
# ...
else:
    # Building from source locally: use -march=native for maximum performance
    return base_args + ["-march=native"]  # ❌ Still fails!

In buildroot's cross-compilation:

  • No CI/wheel environment variables are set (CI, CIBUILDWHEEL, etc.)
  • is_building_wheel() returns False
  • Code falls through to else branch → uses -march=native
  • The aarch64 cross-compiler still gets -march=native and fails

The error happens because -march=native tells GCC to query the HOST CPU's capabilities, but the aarch64 cross-compiler doesn't understand x86_64 architecture features.

Complete Fix Needed

The fix needs to also detect cross-compilation and avoid -march=native:

import platform
import sysconfig

def is_cross_compiling():
    """Detect if we're cross-compiling (host != target)."""
    host_machine = platform.machine().lower()
    target_platform = sysconfig.get_platform().lower()
    target_machine = target_platform.split("-")[-1]

    # Normalize architecture names
    host_normalized = _normalize_arch(host_machine)
    target_normalized = _normalize_arch(target_machine)

    return host_normalized != target_normalized

def _normalize_arch(arch):
    """Normalize architecture names for comparison."""
    if arch in ("x86_64", "amd64", "x64"):
        return "x86_64"
    elif arch in ("aarch64", "arm64"):
        return "aarch64"
    return arch

Then in get_compile_args(), add a check before the else branch:

elif is_cross_compiling():
    # Cross-compiling: -march=native is invalid, use safe baseline for target
    arch_flag = _get_safe_march_flag(machine)
    if arch_flag:
        return base_args + [arch_flag]
    else:
        return base_args

else:
    # Native build: -march=native is safe
    return base_args + ["-march=native"]

CI Failure Note

The type check (ty) failure you're seeing is not related to your PR. It's a pre-existing typo in the justfile:

--ignore non-subscriptable \   # WRONG - should be "not-subscriptable"

Would be cool if you could add that as well, because then the PR should run fully green!


Would you like to update your PR with the complete cross-compilation detection, or would you prefer I handle this in a separate PR?

@jameshilliard
Copy link
Contributor Author

jameshilliard commented Jan 2, 2026

There's a rather subtle bug in this code that I've seen in cargo as well, you can't actually reliably detect cross compilation with this approach at all. It fails to cover scenarios like cross compiling on a x86_64 host for a x86_64 target(say with a different userspace and/or cpu variant) which can result in a number of problems: Best option IMO is to avoid -march=native and purely use sysconfig for platform detection.

def is_cross_compiling():
    """Detect if we're cross-compiling (host != target)."""
    host_machine = platform.machine().lower()
    target_platform = sysconfig.get_platform().lower()
    target_machine = target_platform.split("-")[-1]

    # Normalize architecture names
    host_normalized = _normalize_arch(host_machine)
    target_normalized = _normalize_arch(target_machine)

    return host_normalized != target_normalized

The error happens because -march=native tells GCC to query the HOST CPU's capabilities, but the aarch64 cross-compiler doesn't understand x86_64 architecture features.

Yeah, I was testing with AUTOBAHN_ARCH_TARGET=safe in the env to avoid -march=native from being set, I figured that was sort of the expected way of handling non-native builds.

@jameshilliard
Copy link
Contributor Author

Technically buildroot can pass explicit optimization flags kinda like this as well via the env to a python package, this should be fairly reliable but adds a little bit of complexity on the packaging side of things.

@oberstet
Copy link
Contributor

oberstet commented Jan 2, 2026

so in summary:

Complete Fix Needed

The fix should change the default from -march=native to safe baseline:

else:
    # Building from source: use safe baseline by default
    # This ensures cross-compilation works (buildroot, etc.)
    # Users who want -march=native can set AUTOBAHN_ARCH_TARGET=native
    arch_flag = _get_safe_march_flag(machine)
    if arch_flag:
        return base_args + [arch_flag]
    else:
        return base_args

This way:

  • Cross-compilation works out of the box (buildroot, Yocto, etc.)
  • Source distro users (Gentoo, Arch) can opt-in with AUTOBAHN_ARCH_TARGET=native
  • Our published wheels continue using safe baseline (existing behavior via is_building_wheel())

Summary of Required Changes

  1. ✅ Use sysconfig.get_platform() for architecture detection (your current PR)
  2. ❌ Change default from -march=native to safe baseline (missing)

CI Failure Note

The type check (ty) failure you're seeing is not related to your PR. It's a pre-existing typo in the justfile:

--ignore non-subscriptable \   # WRONG - should be "not-subscriptable"

@jameshilliard
Copy link
Contributor Author

  • Source distro users (Gentoo, Arch) can opt-in with AUTOBAHN_ARCH_TARGET=native

Do you prefer opt-in like this for -march=native or opt-out using AUTOBAHN_ARCH_TARGET=safe for cross compilation?

@jameshilliard
Copy link
Contributor Author

Anyways I think the default is probably a separate issue than the machine detection issue here to some degree so maybe leave that for a follow-up PR?

@oberstet
Copy link
Contributor

oberstet commented Jan 2, 2026

Do you prefer opt-in like this for -march=native or opt-out using AUTOBAHN_ARCH_TARGET=safe for cross compilation?

good question;) @mgorny : any opinions? I'd guess Gentoo would want "native" - even though practical difference vs safe options is likely small (if measurable at all). but Gentoo isn't doing cross compile. Buildroot and Yocto do. personally, I mainly care about our own published native binary wheels for Debian ARM64, and for PyPy. and we are using Qemu with PyPA Docker images, not cross-compile, to build those wheels.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants