File build.py of Package failed_python-rencode

#!/usr/bin/env python3
"""
Minimal build helper for rencode that sanitizes compiler flags which
are invalid on non-x86 architectures (like riscv64). The upstream
build script sometimes picks up -march=native and x86-specific
options (-msse, -msse2, -mfma, -mfpmath=sse) from the environment
(CFLAGS) or from automatic feature detection. On RISC-V these cause
gcc to fail:

    gcc: error: ‘-march=native’: ISA string must begin with rv32 or rv64
    gcc: error: unrecognized command-line option ‘-msse’

We perform the smallest possible change: filter out the offending
flags from the environment and from extension extra_compile_args
before invoking setuptools to build the extension in-place.
"""

from __future__ import annotations
import os
import platform
import shlex
import sys
from pathlib import Path

# Flags that are known to be invalid on RISC-V / non-x86 targets.
# We treat '-msse*' and similar as prefixes.
_OFFENDING_PREFIXES = (
    "-msse",
    "-mfma",
    "-mfpmath",
)

_OFFENDING_EXACT = (
    "-march=native",
)

def _sanitize_flag_tokens(tokens):
    """Return a new list of tokens with offending flags removed."""
    out = []
    for t in tokens:
        if t in _OFFENDING_EXACT:
            continue
        skip = False
        for p in _OFFENDING_PREFIXES:
            if t.startswith(p):
                skip = True
                break
        if skip:
            continue
        out.append(t)
    return out

def sanitize_env_flags():
    """
    Sanitize CFLAGS and similar environment variables in-place so that
    distutils/setuptools won't pass invalid flags to the compiler.
    """
    # List of env vars that commonly influence compilation.
    for var in ("CFLAGS", "CPPFLAGS", "CXXFLAGS", "LDFLAGS"):
        val = os.environ.get(var)
        if not val:
            continue
        try:
            # split honoring quoted parts
            tokens = shlex.split(val)
        except Exception:
            # Fallback: simple whitespace split
            tokens = val.split()
        new_tokens = _sanitize_flag_tokens(tokens)
        if new_tokens != tokens:
            os.environ[var] = " ".join(new_tokens)

def build():
    # If we are on a RISC-V target (or similar non-x86), aggressively
    # sanitize flags. Also sanitize unconditionally to avoid picking up
    # -msse etc. from the build environment when cross-building.
    machine = platform.machine() or ""
    # sanitize always; it's safe to drop x86-only flags on x86 as they are
    # often redundant when optimization is requested in other ways.
    sanitize_env_flags()

    # Now invoke setuptools to build the extension in-place.
    from setuptools import setup, Extension
    try:
        from Cython.Build import cythonize
        have_cython = True
    except Exception:
        have_cython = False

    src_dir = Path(__file__).parent.resolve() / "rencode"
    pyx = src_dir / "_rencode.pyx"
    c_file = src_dir / "_rencode.c"

    if have_cython and pyx.exists():
        sources = [str(pyx)]
        cythonize_kwargs = dict(language_level=3)
    elif c_file.exists():
        sources = [str(c_file)]
        cythonize_kwargs = None
    else:
        # If neither .pyx nor .c exists, fallback to a very small metadata-only
        # setup so the build system can continue (this is unlikely).
        sources = []
        cythonize_kwargs = None

    ext_modules = []
    if sources:
        ext = Extension(
            "rencode._rencode",
            sources=sources,
            extra_compile_args=[],  # do not add architecture-specific flags here
        )
        if cythonize_kwargs is not None:
            ext_modules = cythonize([ext], **cythonize_kwargs)
        else:
            ext_modules = [ext]

    # Minimal metadata — keep it small to avoid altering packaging behaviour.
    setup(
        name="rencode",
        version="1.0.8",
        description="rencode encoder/decoder (sanitized build)",
        packages=["rencode"],
        ext_modules=ext_modules,
        script_args=["build_ext", "--inplace"],
    )

if __name__ == "__main__":
    build()
openSUSE Build Service is sponsored by