Skip to content

Commit 3bd8c26

Browse files
committed
fix: custom cross compiling environment
Signed-off-by: Henry Schreiner <[email protected]>
1 parent f00bc8e commit 3bd8c26

File tree

3 files changed

+93
-4
lines changed

3 files changed

+93
-4
lines changed

src/scikit_build_core/builder/builder.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from ..cmake import CMaker
1616
from ..resources import find_python
1717
from ..settings.skbuild_model import ScikitBuildSettings
18+
from .cross_compile import auto_cross_compile_env
1819
from .generator import set_environment_for_gen
1920
from .sysconfig import get_platform, get_python_include_dir, get_python_library
2021

@@ -194,10 +195,11 @@ def configure(
194195
# Add the pre-defined or passed CMake defines
195196
cmake_defines.update(self.settings.cmake.define)
196197

197-
self.config.configure(
198-
defines=cmake_defines,
199-
cmake_args=[*self.get_cmake_args(), *configure_args],
200-
)
198+
with auto_cross_compile_env(self.config.env):
199+
self.config.configure(
200+
defines=cmake_defines,
201+
cmake_args=[*self.get_cmake_args(), *configure_args],
202+
)
201203

202204
def build(self, build_args: list[str]) -> None:
203205
self.config.build(build_args=build_args, verbose=self.settings.cmake.verbose)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
from __future__ import annotations
2+
3+
import contextlib
4+
import os
5+
import string
6+
import sysconfig
7+
import tempfile
8+
from collections.abc import Generator, MutableMapping
9+
from pathlib import Path
10+
11+
from .._logging import logger
12+
from ..resources import resources
13+
14+
__all__ = ["set_cross_compile_env"]
15+
16+
17+
def __dir__() -> list[str]:
18+
return __all__
19+
20+
21+
@contextlib.contextmanager
22+
def auto_cross_compile_env(
23+
env: MutableMapping[str, str]
24+
) -> Generator[None, None, None]:
25+
if "SETUPTOOLS_EXT_SUFFIX" not in env:
26+
yield
27+
return
28+
29+
with set_cross_compile_env(env["SETUPTOOLS_EXT_SUFFIX"], env):
30+
yield
31+
32+
33+
@contextlib.contextmanager
34+
def set_cross_compile_env(
35+
ext_suffix: str, env: MutableMapping[str, str]
36+
) -> Generator[None, None, None]:
37+
"""
38+
Generate python file and set environment variables to cross-compile Python
39+
extensions. Do not call if _PYTHON_SYSCONFIGDATA_NAME is already set.
40+
"""
41+
42+
if "_PYTHON_SYSCONFIGDATA_NAME" in env:
43+
logger.debug(
44+
"Not setting up cross compiling explicitly due to _PYTHON_SYSCONFIGDATA_NAME already set."
45+
)
46+
yield
47+
return
48+
49+
if getattr(sysconfig, "_get_sysconfigdata_name", ""):
50+
logger.warning(
51+
"Cross-compiling is not supported due to sysconfig._get_sysconfigdata_name missing."
52+
)
53+
yield
54+
return
55+
56+
with tempfile.TemporaryDirectory() as tmpdir:
57+
tmp_dir = Path(tmpdir).resolve()
58+
cross_compile_file = tmp_dir / f"_cross_compile_{ext_suffix}.py"
59+
input_txt = resources.read_text("_cross_compile.py")
60+
output_text = string.Template(input_txt).substitute(
61+
host_name=sysconfig._get_sysconfigdata_name(), # type: ignore[attr-defined]
62+
SOABI=ext_suffix.rsplit(maxsplit=1)[0],
63+
EXT_SUFFIX=ext_suffix,
64+
)
65+
cross_compile_file.write_text(output_text)
66+
current_path = env.get("PYTHONPATH", "")
67+
env["PYTHONPATH"] = (
68+
os.pathsep.join([current_path, str(tmp_dir)])
69+
if current_path
70+
else str(tmp_dir)
71+
)
72+
env["_PYTHON_SYSCONFIGDATA_NAME"] = f"_cross_compile_{ext_suffix}.py"
73+
try:
74+
yield
75+
finally:
76+
del env["_PYTHON_SYSCONFIGDATA_NAME"]
77+
if current_path:
78+
env["PYTHONPATH"] = current_path
79+
else:
80+
del env["PYTHONPATH"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Cross compiling activation template
2+
3+
host_name = "${host_name}"
4+
5+
build_time_vars = __import__("${host_name}").build_time_vars.copy()
6+
build_time_vars["SOABI"] = "${SOABI}"
7+
build_time_vars["EXT_SUFFIX"] = "${EXT_SUFFIX}"

0 commit comments

Comments
 (0)