Skip to content

Commit

Permalink
Merge pull request #507 from henryiii/feat/windowsfilter
Browse files Browse the repository at this point in the history
feat: Windows filtering and sets
  • Loading branch information
probot-auto-merge[bot] authored Jan 5, 2021
2 parents 6f28d78 + fce7c70 commit 9f610d0
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 43 deletions.
6 changes: 3 additions & 3 deletions cibuildwheel/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from configparser import ConfigParser
from pathlib import Path

from typing import Any, Dict, List, Optional, overload
from typing import Any, Dict, List, Optional, Set, overload

import cibuildwheel
import cibuildwheel.linux
Expand Down Expand Up @@ -304,13 +304,13 @@ def print_preamble(platform: str, build_options: BuildOptions) -> None:


def print_build_identifiers(
platform: str, build_selector: BuildSelector, architectures: List[Architecture]
platform: str, build_selector: BuildSelector, architectures: Set[Architecture]
) -> None:
python_configurations: List[Any] = []
if platform == 'linux':
python_configurations = cibuildwheel.linux.get_python_configurations(build_selector, architectures)
elif platform == 'windows':
python_configurations = cibuildwheel.windows.get_python_configurations(build_selector)
python_configurations = cibuildwheel.windows.get_python_configurations(build_selector, architectures)
elif platform == 'macos':
python_configurations = cibuildwheel.macos.get_python_configurations(build_selector)

Expand Down
10 changes: 6 additions & 4 deletions cibuildwheel/linux.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
import sys
import textwrap
from pathlib import Path, PurePath
from typing import List, NamedTuple
from typing import List, NamedTuple, Set

from .docker_container import DockerContainer
from .logger import log
from .util import (
Architecture, BuildOptions, BuildSelector, NonPlatformWheelError,
get_build_verbosity_extra_flags, prepare_command,
allowed_architectures_check, get_build_verbosity_extra_flags, prepare_command,
)
from .typing import PathOrStr

Expand All @@ -24,7 +24,7 @@ def path(self) -> PurePath:


def get_python_configurations(
build_selector: BuildSelector, architectures: List[Architecture]
build_selector: BuildSelector, architectures: Set[Architecture]
) -> List[PythonConfiguration]:
python_configurations = [
PythonConfiguration(version='2.7', identifier='cp27-manylinux_x86_64', path_str='/opt/python/cp27-cp27m'),
Expand Down Expand Up @@ -61,7 +61,7 @@ def get_python_configurations(
PythonConfiguration(version='3.9', identifier='cp39-manylinux_s390x', path_str='/opt/python/cp39-cp39'),
]

# return all configurations whose arch is in our `architectures` list,
# return all configurations whose arch is in our `architectures` set,
# and match the build/skip rules
return [
c for c in python_configurations
Expand All @@ -71,6 +71,8 @@ def get_python_configurations(


def build(options: BuildOptions) -> None:
allowed_architectures_check("linux", options)

try:
subprocess.check_output(['docker', '--version'])
except Exception:
Expand Down
11 changes: 3 additions & 8 deletions cibuildwheel/macos.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
import subprocess
import sys
import tempfile
import textwrap
from pathlib import Path
from typing import Dict, List, NamedTuple, Optional, Sequence

from .environment import ParsedEnvironment
from .logger import log
from .util import (Architecture, BuildOptions, BuildSelector, NonPlatformWheelError,
from .util import (BuildOptions, BuildSelector, NonPlatformWheelError,
download, get_build_verbosity_extra_flags, get_pip_script,
install_certifi_script, prepare_command)
install_certifi_script, prepare_command, allowed_architectures_check)
from .typing import PathOrStr


Expand Down Expand Up @@ -187,11 +186,7 @@ def setup_python(python_configuration: PythonConfiguration,


def build(options: BuildOptions) -> None:
if options.architectures != [Architecture.x86_64]:
raise ValueError(textwrap.dedent(f'''
Invalid archs option {options.architectures}. macOS only supports x86_64 for the moment.
If you want to set emulation architectures on Linux, use CIBW_ARCHS_LINUX instead.
'''))
allowed_architectures_check("macos", options)

temp_dir = Path(tempfile.mkdtemp(prefix='cibuildwheel'))
built_wheel_dir = temp_dir / 'built_wheel'
Expand Down
64 changes: 54 additions & 10 deletions cibuildwheel/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,26 @@
import platform as platform_module
import re
import ssl
import sys
import functools
import textwrap
import urllib.request
from enum import Enum
from fnmatch import fnmatch
from pathlib import Path
from time import sleep
from typing import Dict, List, NamedTuple, Optional
from typing import Dict, List, NamedTuple, Optional, Set

import certifi

from .environment import ParsedEnvironment
from .typing import PathOrStr

if sys.version_info < (3, 8):
from typing_extensions import Literal
else:
from typing import Literal


def prepare_command(command: str, **kwargs: PathOrStr) -> str:
'''
Expand Down Expand Up @@ -124,7 +131,10 @@ def __repr__(self) -> str:
return f'{self.__class__.__name__}{self.base_file_path!r})'


@functools.total_ordering
class Architecture(Enum):
value: str

# mac/linux archs
x86_64 = 'x86_64'
i686 = 'i686'
Expand All @@ -136,33 +146,37 @@ class Architecture(Enum):
x86 = 'x86'
AMD64 = 'AMD64'

# Allow this to be sorted
def __lt__(self, other: "Architecture") -> bool:
return self.value < other.value

@staticmethod
def parse_config(config: str, platform: str) -> 'List[Architecture]':
result = []
def parse_config(config: str, platform: str) -> 'Set[Architecture]':
result = set()
for arch_str in re.split(r'[\s,]+', config):
if arch_str == 'auto':
result += Architecture.auto_archs(platform=platform)
result |= Architecture.auto_archs(platform=platform)
else:
result.append(Architecture(arch_str))
result.add(Architecture(arch_str))
return result

@staticmethod
def auto_archs(platform: str) -> 'List[Architecture]':
def auto_archs(platform: str) -> 'Set[Architecture]':
native_architecture = Architecture(platform_module.machine())
result = [native_architecture]
result = {native_architecture}
if platform == 'linux' and native_architecture == Architecture.x86_64:
# x86_64 machines can run i686 docker containers
result.append(Architecture.i686)
result.add(Architecture.i686)
if platform == 'windows' and native_architecture == Architecture.AMD64:
result.append(Architecture.x86)
result.add(Architecture.x86)
return result


class BuildOptions(NamedTuple):
package_dir: Path
output_dir: Path
build_selector: BuildSelector
architectures: List[Architecture]
architectures: Set[Architecture]
environment: ParsedEnvironment
before_all: str
before_build: Optional[str]
Expand Down Expand Up @@ -229,3 +243,33 @@ def detect_ci_provider() -> Optional[CIProvider]:
return CIProvider.other
else:
return None


PRETTY_NAMES = {'linux': 'Linux', 'macos': 'macOS', 'windows': 'Windows'}

ALLOWED_ARCHITECTURES = {
'linux': {Architecture.x86_64, Architecture.i686, Architecture.aarch64, Architecture.ppc64le, Architecture.s390x},
'macos': {Architecture.x86_64},
'windows': {Architecture.AMD64, Architecture.x86},
}


def allowed_architectures_check(
name: Literal['linux', 'macos', 'windows'],
options: BuildOptions,
) -> None:

allowed_architectures = ALLOWED_ARCHITECTURES[name]

msg = f'{PRETTY_NAMES[name]} only supports {sorted(allowed_architectures)} at the moment.'

if name != 'linux':
msg += ' If you want to set emulation architectures on Linux, use CIBW_ARCHS_LINUX instead.'

if not options.architectures <= allowed_architectures:
msg = f'Invalid archs option {options.architectures}. ' + msg
raise ValueError(msg)

if not options.architectures:
msg = 'Empty archs option set. ' + msg
raise ValueError(msg)
26 changes: 14 additions & 12 deletions cibuildwheel/windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
import subprocess
import sys
import tempfile
import textwrap
from pathlib import Path
from typing import Dict, List, NamedTuple, Optional, Sequence
from typing import Dict, List, NamedTuple, Optional, Sequence, Set
from zipfile import ZipFile

import toml
Expand All @@ -14,7 +13,7 @@
from .logger import log
from .util import (Architecture, BuildOptions, BuildSelector, NonPlatformWheelError,
download, get_build_verbosity_extra_flags, get_pip_script,
prepare_command)
prepare_command, allowed_architectures_check)
from .typing import PathOrStr

IS_RUNNING_ON_AZURE = Path('C:\\hostedtoolcache').exists()
Expand Down Expand Up @@ -48,7 +47,12 @@ class PythonConfiguration(NamedTuple):
url: Optional[str]


def get_python_configurations(build_selector: BuildSelector) -> List[PythonConfiguration]:
def get_python_configurations(build_selector: BuildSelector, architectures: Set[Architecture]) -> List[PythonConfiguration]:
map_arch = {
'32': Architecture.x86,
'64': Architecture.AMD64,
}

python_configurations = [
# CPython
PythonConfiguration(version='2.7.18', arch='32', identifier='cp27-win32', url=None),
Expand All @@ -75,7 +79,10 @@ def get_python_configurations(build_selector: BuildSelector) -> List[PythonConfi
python_configurations = [c for c in python_configurations if not c.version.startswith('2.7')]

# skip builds as required
python_configurations = [c for c in python_configurations if build_selector(c.identifier)]
python_configurations = [
c for c in python_configurations
if build_selector(c.identifier) and map_arch[c.arch] in architectures
]

return python_configurations

Expand Down Expand Up @@ -202,12 +209,7 @@ def pep_518_cp35_workaround(package_dir: Path, env: Dict[str, str]) -> None:


def build(options: BuildOptions) -> None:
if options.architectures != [Architecture.AMD64, Architecture.x86]:
raise ValueError(textwrap.dedent(f'''
Invalid archs option {options.architectures}. Windows only supports 'amd64,x86' for the
moment. If you want to set emulation architectures on Linux, use CIBW_ARCHS_LINUX
instead.
'''))
allowed_architectures_check("windows", options)

temp_dir = Path(tempfile.mkdtemp(prefix='cibuildwheel'))
built_wheel_dir = temp_dir / 'built_wheel'
Expand All @@ -220,7 +222,7 @@ def build(options: BuildOptions) -> None:
before_all_prepared = prepare_command(options.before_all, project='.', package=options.package_dir)
shell(before_all_prepared, env=env)

python_configurations = get_python_configurations(options.build_selector)
python_configurations = get_python_configurations(options.build_selector, options.architectures)

for config in python_configurations:
log.build_start(config.identifier)
Expand Down
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ install_requires =
bashlex!=0.13
toml
certifi
typing_extensions; python_version < '3.8'

[options.package_data]
cibuildwheel = resources/*
Expand Down
12 changes: 6 additions & 6 deletions unit_test/main_tests/main_platform_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ def test_archs_default(platform, intercepted_build_args, monkeypatch):
build_options = intercepted_build_args.args[0]

if platform == 'linux':
assert build_options.architectures == [Architecture.x86_64, Architecture.i686]
assert build_options.architectures == {Architecture.x86_64, Architecture.i686}
else:
assert build_options.architectures == [Architecture.x86_64]
assert build_options.architectures == {Architecture.x86_64}


@pytest.mark.parametrize('use_env_var', [False, True])
Expand All @@ -92,7 +92,7 @@ def test_archs_argument(platform, intercepted_build_args, monkeypatch, use_env_v
main()
build_options = intercepted_build_args.args[0]

assert build_options.architectures == [Architecture.ppc64le]
assert build_options.architectures == {Architecture.ppc64le}


def test_archs_platform_specific(platform, intercepted_build_args, monkeypatch):
Expand All @@ -106,8 +106,8 @@ def test_archs_platform_specific(platform, intercepted_build_args, monkeypatch):
build_options = intercepted_build_args.args[0]

if platform == 'linux':
assert build_options.architectures == [Architecture.ppc64le]
assert build_options.architectures == {Architecture.ppc64le}
elif platform == 'windows':
assert build_options.architectures == [Architecture.x86]
assert build_options.architectures == {Architecture.x86}
elif platform == 'macos':
assert build_options.architectures == [Architecture.x86_64]
assert build_options.architectures == {Architecture.x86_64}

0 comments on commit 9f610d0

Please sign in to comment.