diff --git a/src/scikit_build_core/builder/builder.py b/src/scikit_build_core/builder/builder.py index 87594dd89..836cae073 100644 --- a/src/scikit_build_core/builder/builder.py +++ b/src/scikit_build_core/builder/builder.py @@ -10,7 +10,11 @@ from packaging.version import Version from .. import __version__ -from ..builder.sysconfig import get_python_include_dir, get_python_library +from ..builder.sysconfig import ( + get_cmake_platform, + get_python_include_dir, + get_python_library, +) from ..cmake import CMaker from ..errors import NinjaNotFoundError from ..program_search import best_program, get_make_programs, get_ninja_programs @@ -82,11 +86,12 @@ def configure( if fp_backport and self.config.cmake.version < Version(fp_backport): self.config.module_dirs.append(Path(find_python.__file__).parent.resolve()) - if sys.platform.startswith("win32"): - # TODO: support cross-compilation - is_64bit = sys.maxsize > 2**32 - if not is_64bit: - cmake_args += ["-A", "Win32"] + if sys.platform.startswith("win32") and "Visual Studio" in self.config.env.get( + "CMAKE_GENERATOR", "Visual Studio" + ): + self.config.env.setdefault( + "CMAKE_GENERATOR_PLATFORM", get_cmake_platform(self.config.env) + ) elif self.config.env.get( "CMAKE_GENERATOR", "Ninja" ) == "Ninja" and not self.config.env.get("CMAKE_MAKE_PROGRAM", ""): diff --git a/src/scikit_build_core/builder/sysconfig.py b/src/scikit_build_core/builder/sysconfig.py index efb3ed62c..998777526 100644 --- a/src/scikit_build_core/builder/sysconfig.py +++ b/src/scikit_build_core/builder/sysconfig.py @@ -1,12 +1,29 @@ from __future__ import annotations import os +import sys import sysconfig +from collections.abc import Mapping from pathlib import Path from .._logging import logger -__all__ = ["get_python_include_dir", "get_python_library"] +__all__ = ["get_python_include_dir", "get_python_library", "get_cmake_platform"] + + +TARGET_TO_PLAT = { + "x86": "win32", + "x64": "win-amd64", + "arm": "win-arm32", + "arm64": "win-arm64", +} + +PLAT_TO_CMAKE = { + "win32": "Win32", + "win-amd64": "x64", + "win-arm32": "ARM", + "win-arm64": "ARM64", +} def __dir__() -> list[str]: @@ -55,3 +72,38 @@ def get_python_library() -> Path | None: def get_python_include_dir() -> Path: return Path(sysconfig.get_path("include")) + + +def get_host_platform() -> str: + """ + Return a string that identifies the current platform. This mimics + setuptools get_host_platform (without 3.8 aix compat). + """ + + if sys.version_info < (3, 8): + if os.name == "nt": + if "(arm)" in sys.version.lower(): + return "win-arm32" + if "(arm64)" in sys.version.lower(): + return "win-arm64" + + return sysconfig.get_platform() + + +def get_platform(env: Mapping[str, str] | None = None) -> str: + """ + Return the Python platform name for a platform, respecting VSCMD_ARG_TGT_ARCH. + """ + if env is None: + env = os.environ + if os.name == "nt" and "VSCMD_ARG_TGT_ARCH" in env: + return TARGET_TO_PLAT.get(env["VSCMD_ARG_TGT_ARCH"]) or get_host_platform() + return get_host_platform() + + +def get_cmake_platform(env: Mapping[str, str] | None) -> str: + """ + Return the CMake platform name for a platform, respecting VSCMD_ARG_TGT_ARCH. + """ + plat = get_platform(env) + return PLAT_TO_CMAKE.get(plat, plat) diff --git a/src/scikit_build_core/setuptools/extension.py b/src/scikit_build_core/setuptools/extension.py index a3ad362c5..b134054db 100644 --- a/src/scikit_build_core/setuptools/extension.py +++ b/src/scikit_build_core/setuptools/extension.py @@ -24,15 +24,6 @@ def __dir__() -> list[str]: return __all__ -# Convert distutils Windows platform specifiers to CMake -A arguments -PLAT_TO_CMAKE = { - "win32": "Win32", - "win-amd64": "x64", - "win-arm32": "ARM", - "win-arm64": "ARM64", -} - - # A CMakeExtension needs a sourcedir instead of a file list. # The name must be the _single_ output extension from the CMake build. # The sourcedir is relative to the setup.py directory, where the CMakeLists.txt lives