Skip to content

Commit b95dca5

Browse files
authored
Merge pull request #484 from joerick/macos-universal2
Universal2 wheels on macOS
2 parents 0de4608 + 2def20d commit b95dca5

22 files changed

+554
-99
lines changed

.github/workflows/test.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,18 @@ jobs:
5252
run: |
5353
python bin/sample_build.py
5454
55+
- name: Get some sample wheels
56+
run: |
57+
python -m test.test_projects test.test_0_basic.basic_project sample_proj
58+
cibuildwheel --output-dir wheelhouse sample_proj
59+
env:
60+
CIBW_ARCHS_MACOS: x86_64 universal2 arm64
61+
62+
- uses: actions/upload-artifact@v2
63+
with:
64+
name: sample_wheels
65+
path: wheelhouse
66+
5567
- name: Test cibuildwheel
5668
run: |
5769
python ./bin/run_tests.py

bin/run_tests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@
1717
subprocess.check_call(unit_test_args)
1818

1919
# run the integration tests
20-
subprocess.check_call([sys.executable, '-m', 'pytest', '-x', '--durations', '0', '--timeout=1200', 'test'])
20+
subprocess.check_call([sys.executable, '-m', 'pytest', '-x', '--durations', '0', '--timeout=2400', 'test'])

bin/sample_build.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@
2222
options.project_python_path, project_dir
2323
], check=True)
2424

25-
sys.exit(subprocess.run(['cibuildwheel'], cwd=project_dir).returncode)
25+
sys.exit(subprocess.run([sys.executable, '-m', 'cibuildwheel'], cwd=project_dir).returncode)

cibuildwheel/__main__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ def main() -> None:
137137
if platform == 'linux':
138138
repair_command_default = 'auditwheel repair -w {dest_dir} {wheel}'
139139
elif platform == 'macos':
140-
repair_command_default = 'delocate-listdeps {wheel} && delocate-wheel --require-archs x86_64 -w {dest_dir} {wheel}'
140+
repair_command_default = 'delocate-listdeps {wheel} && delocate-wheel --require-archs {delocate_archs} -w {dest_dir} {wheel}'
141141
elif platform == 'windows':
142142
repair_command_default = ''
143143
else:
@@ -339,7 +339,7 @@ def get_build_identifiers(
339339
elif platform == 'windows':
340340
python_configurations = cibuildwheel.windows.get_python_configurations(build_selector, architectures)
341341
elif platform == 'macos':
342-
python_configurations = cibuildwheel.macos.get_python_configurations(build_selector)
342+
python_configurations = cibuildwheel.macos.get_python_configurations(build_selector, architectures)
343343
else:
344344
assert_never(platform)
345345

cibuildwheel/architecture.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,17 @@ class Architecture(Enum):
1515

1616
# mac/linux archs
1717
x86_64 = 'x86_64'
18+
19+
# linux archs
1820
i686 = 'i686'
1921
aarch64 = 'aarch64'
2022
ppc64le = 'ppc64le'
2123
s390x = 's390x'
2224

25+
# mac archs
26+
universal2 = 'universal2'
27+
arm64 = 'arm64'
28+
2329
# windows archs
2430
x86 = 'x86'
2531
AMD64 = 'AMD64'
@@ -46,19 +52,26 @@ def parse_config(config: str, platform: PlatformName) -> 'Set[Architecture]':
4652
def auto_archs(platform: PlatformName) -> 'Set[Architecture]':
4753
native_architecture = Architecture(platform_module.machine())
4854
result = {native_architecture}
55+
4956
if platform == 'linux' and native_architecture == Architecture.x86_64:
5057
# x86_64 machines can run i686 docker containers
5158
result.add(Architecture.i686)
59+
5260
if platform == 'windows' and native_architecture == Architecture.AMD64:
5361
result.add(Architecture.x86)
62+
63+
if platform == 'macos' and native_architecture == Architecture.arm64:
64+
# arm64 can build and test both archs of a universal2 wheel.
65+
result.add(Architecture.universal2)
66+
5467
return result
5568

5669
@staticmethod
5770
def all_archs(platform: PlatformName) -> 'Set[Architecture]':
5871
if platform == 'linux':
5972
return {Architecture.x86_64, Architecture.i686, Architecture.aarch64, Architecture.ppc64le, Architecture.s390x}
6073
elif platform == 'macos':
61-
return {Architecture.x86_64}
74+
return {Architecture.x86_64, Architecture.arm64, Architecture.universal2}
6275
elif platform == 'windows':
6376
return {Architecture.x86, Architecture.AMD64}
6477
else:

cibuildwheel/linux.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ def build(options: BuildOptions) -> None:
9494

9595
env = docker.get_environment()
9696
env['PATH'] = f'/opt/python/cp38-cp38/bin:{env["PATH"]}'
97+
env['PIP_DISABLE_PIP_VERSION_CHECK'] = '1'
9798
env = options.environment.as_dictionary(env, executor=docker.environment_executor)
9899

99100
before_all_prepared = prepare_command(options.before_all, project=container_project_path, package=container_package_dir)
@@ -228,7 +229,7 @@ def build(options: BuildOptions) -> None:
228229
docker.copy_out(container_output_dir, options.output_dir)
229230
log.step_end()
230231
except subprocess.CalledProcessError as error:
231-
log.error(f'Command {error.cmd} failed with code {error.returncode}. {error.stdout}')
232+
log.step_end_with_error(f'Command {error.cmd} failed with code {error.returncode}. {error.stdout}')
232233
troubleshoot(options.package_dir, error)
233234
sys.exit(1)
234235

cibuildwheel/logger.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
'win32': 'Windows 32bit',
2424
'win_amd64': 'Windows 64bit',
2525
'macosx_x86_64': 'macOS x86_64',
26+
'macosx_universal2': 'macOS Universal 2 - x86_64 and arm64',
27+
'macosx_arm64': 'macOS arm64 - Apple Silicon',
2628
}
2729

2830

@@ -109,15 +111,23 @@ def step_end(self, success: bool = True) -> None:
109111

110112
self.step_start_time = None
111113

112-
def error(self, error: Union[BaseException, str]) -> None:
114+
def step_end_with_error(self, error: Union[BaseException, str]) -> None:
113115
self.step_end(success=False)
114-
print()
116+
self.error(error)
115117

118+
def warning(self, message: str) -> None:
119+
if self.fold_mode == 'github':
120+
print(f'::warning::{message}\n', file=sys.stderr)
121+
else:
122+
c = self.colors
123+
print(f'{c.yellow}Warning{c.end}: {message}\n', file=sys.stderr)
124+
125+
def error(self, error: Union[BaseException, str]) -> None:
116126
if self.fold_mode == 'github':
117-
print(f'::error::{error}')
127+
print(f'::error::{error}\n', file=sys.stderr)
118128
else:
119129
c = self.colors
120-
print(f'{c.bright_red}Error{c.end} {error}')
130+
print(f'{c.bright_red}Error{c.end}: {error}\n', file=sys.stderr)
121131

122132
def _start_fold_group(self, name: str) -> None:
123133
self._end_fold_group()

0 commit comments

Comments
 (0)