Skip to content

Commit de84624

Browse files
MusicalNinjaDadhenryiiipre-commit-ci[bot]joerick
authored
fix: set VSCMD_ARG_TGT_ARCH based on targeted architecture (#1876)
* set VSCMD_ARG_TGT_ARCH based on targetted architecture * only set VSCMD_ARG_TGT_ARCH if not already set * add unit tests to check setuptools correctly identifies windows arch * only run tests on windows * arm64 fails on azure pipelines (only) * Update windows.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Apply suggestions from code review Co-authored-by: Joe Rickerby <[email protected]> * update test_env_set to validate FatalError is raised on env collision * remove noqa ARG001 (no longer needed) --------- Co-authored-by: Henry Schreiner <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Joe Rickerby <[email protected]>
1 parent cac121a commit de84624

File tree

3 files changed

+105
-0
lines changed

3 files changed

+105
-0
lines changed

cibuildwheel/windows.py

+10
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,16 @@ def setup_setuptools_cross_compile(
152152
# set the platform name
153153
map_plat = {"32": "win32", "64": "win-amd64", "ARM64": "win-arm64"}
154154
plat_name = map_plat[python_configuration.arch]
155+
156+
# Set environment variable so that setuptools._distutils.get_platform()
157+
# identifies the target, not the host
158+
vscmd_arg_tgt_arch = {"32": "x86", "64": "x64", "ARM64": "arm64"}
159+
current_tgt_arch = vscmd_arg_tgt_arch[python_configuration.arch]
160+
if (env.get("VSCMD_ARG_TGT_ARCH") or current_tgt_arch) != current_tgt_arch:
161+
msg = f"VSCMD_ARG_TGT_ARCH must be set to {current_tgt_arch!r}, got {env['VSCMD_ARG_TGT_ARCH']!r}. If you're setting up MSVC yourself (e.g. using vcvarsall.bat or msvc-dev-cmd), make sure to target the right architecture. Alternatively, run cibuildwheel without configuring MSVC, and let the build backend handle it."
162+
raise errors.FatalError(msg)
163+
env["VSCMD_ARG_TGT_ARCH"] = current_tgt_arch
164+
155165
# (This file must be default/locale encoding, so we can't pass 'encoding')
156166
distutils_cfg.write_text(
157167
textwrap.dedent(

pyproject.toml

+3
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ test = [
7575
"pytest-timeout",
7676
"pytest-xdist",
7777
"pytest>=6",
78+
"setuptools",
7879
"tomli_w",
7980
"validate-pyproject",
8081
]
@@ -140,6 +141,8 @@ disallow_untyped_decorators = true
140141
[[tool.mypy.overrides]]
141142
module = [
142143
"setuptools",
144+
"setuptools._distutils", # needed even if only directly import setuptools._distutils.util
145+
"setuptools._distutils.util",
143146
"pytest", # ignored in pre-commit to speed up check
144147
"bashlex",
145148
"bashlex.*",

unit_test/get_platform_test.py

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import contextlib
2+
import sys
3+
from pathlib import Path
4+
from typing import Dict
5+
6+
import pytest
7+
import setuptools._distutils.util
8+
9+
from cibuildwheel.errors import FatalError
10+
from cibuildwheel.util import CIProvider, detect_ci_provider
11+
from cibuildwheel.windows import PythonConfiguration, setup_setuptools_cross_compile
12+
13+
# monkeypatching os.name is too flaky. E.g. It works on my machine, but fails in pipeline
14+
if not sys.platform.startswith("win"):
15+
pytest.skip("Windows-only tests", allow_module_level=True)
16+
17+
18+
@contextlib.contextmanager
19+
def patched_environment(monkeypatch: pytest.MonkeyPatch, environment: Dict[str, str]):
20+
with monkeypatch.context() as mp:
21+
for envvar, val in environment.items():
22+
mp.setenv(name=envvar, value=val)
23+
yield
24+
25+
26+
def test_x86(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
27+
arch = "32"
28+
environment: Dict[str, str] = {}
29+
30+
configuration = PythonConfiguration("irrelevant", arch, "irrelevant", None)
31+
32+
setup_setuptools_cross_compile(tmp_path, configuration, tmp_path, environment)
33+
with patched_environment(monkeypatch, environment):
34+
target_platform = setuptools._distutils.util.get_platform()
35+
36+
assert environment["VSCMD_ARG_TGT_ARCH"] == "x86"
37+
assert target_platform == "win32"
38+
39+
40+
def test_x64(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
41+
arch = "64"
42+
environment: Dict[str, str] = {}
43+
44+
configuration = PythonConfiguration("irrelevant", arch, "irrelevant", None)
45+
46+
setup_setuptools_cross_compile(tmp_path, configuration, tmp_path, environment)
47+
with patched_environment(monkeypatch, environment):
48+
target_platform = setuptools._distutils.util.get_platform()
49+
50+
assert environment["VSCMD_ARG_TGT_ARCH"] == "x64"
51+
assert target_platform == "win-amd64"
52+
53+
54+
@pytest.mark.skipif(
55+
detect_ci_provider() == CIProvider.azure_pipelines, reason="arm64 not recognised on azure"
56+
)
57+
def test_arm(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
58+
arch = "ARM64"
59+
environment: Dict[str, str] = {}
60+
61+
configuration = PythonConfiguration("irrelevant", arch, "irrelevant", None)
62+
63+
setup_setuptools_cross_compile(tmp_path, configuration, tmp_path, environment)
64+
with patched_environment(monkeypatch, environment):
65+
target_platform = setuptools._distutils.util.get_platform()
66+
67+
assert environment["VSCMD_ARG_TGT_ARCH"] == "arm64"
68+
assert target_platform == "win-arm64"
69+
70+
71+
def test_env_set(tmp_path: Path):
72+
arch = "32"
73+
environment = {"VSCMD_ARG_TGT_ARCH": "x64"}
74+
75+
configuration = PythonConfiguration("irrelevant", arch, "irrelevant", None)
76+
77+
with pytest.raises(FatalError, match="VSCMD_ARG_TGT_ARCH"):
78+
setup_setuptools_cross_compile(tmp_path, configuration, tmp_path, environment)
79+
80+
81+
def test_env_blank(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
82+
arch = "32"
83+
environment = {"VSCMD_ARG_TGT_ARCH": ""}
84+
85+
configuration = PythonConfiguration("irrelevant", arch, "irrelevant", None)
86+
87+
setup_setuptools_cross_compile(tmp_path, configuration, tmp_path, environment)
88+
with patched_environment(monkeypatch, environment):
89+
target_platform = setuptools._distutils.util.get_platform()
90+
91+
assert environment["VSCMD_ARG_TGT_ARCH"] == "x86"
92+
assert target_platform == "win32"

0 commit comments

Comments
 (0)