|
23 | 23 | call,
|
24 | 24 | detect_ci_provider,
|
25 | 25 | download,
|
| 26 | + find_compatible_abi3_wheel, |
26 | 27 | get_build_verbosity_extra_flags,
|
27 | 28 | get_pip_version,
|
28 | 29 | install_certifi_script,
|
@@ -291,6 +292,8 @@ def build(options: Options, tmp_path: Path) -> None:
|
291 | 292 | )
|
292 | 293 | shell(before_all_prepared, env=env)
|
293 | 294 |
|
| 295 | + built_wheels: List[Path] = [] |
| 296 | + |
294 | 297 | for config in python_configurations:
|
295 | 298 | build_options = options.build_options(config.identifier)
|
296 | 299 | log.build_start(config.identifier)
|
@@ -318,84 +321,94 @@ def build(options: Options, tmp_path: Path) -> None:
|
318 | 321 | build_options.build_frontend,
|
319 | 322 | )
|
320 | 323 |
|
321 |
| - if build_options.before_build: |
322 |
| - log.step("Running before_build...") |
323 |
| - before_build_prepared = prepare_command( |
324 |
| - build_options.before_build, project=".", package=build_options.package_dir |
325 |
| - ) |
326 |
| - shell(before_build_prepared, env=env) |
327 |
| - |
328 |
| - log.step("Building wheel...") |
329 |
| - built_wheel_dir.mkdir() |
330 |
| - |
331 |
| - verbosity_flags = get_build_verbosity_extra_flags(build_options.build_verbosity) |
332 |
| - |
333 |
| - if build_options.build_frontend == "pip": |
334 |
| - # Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org |
335 |
| - # see https://github.com/pypa/cibuildwheel/pull/369 |
336 |
| - call( |
337 |
| - "python", |
338 |
| - "-m", |
339 |
| - "pip", |
340 |
| - "wheel", |
341 |
| - build_options.package_dir.resolve(), |
342 |
| - f"--wheel-dir={built_wheel_dir}", |
343 |
| - "--no-deps", |
344 |
| - *verbosity_flags, |
345 |
| - env=env, |
346 |
| - ) |
347 |
| - elif build_options.build_frontend == "build": |
348 |
| - config_setting = " ".join(verbosity_flags) |
349 |
| - build_env = env.copy() |
350 |
| - if build_options.dependency_constraints: |
351 |
| - constraint_path = build_options.dependency_constraints.get_for_python_version( |
352 |
| - config.version |
353 |
| - ) |
354 |
| - build_env["PIP_CONSTRAINT"] = constraint_path.as_uri() |
355 |
| - build_env["VIRTUALENV_PIP"] = get_pip_version(env) |
356 |
| - call( |
357 |
| - "python", |
358 |
| - "-m", |
359 |
| - "build", |
360 |
| - build_options.package_dir, |
361 |
| - "--wheel", |
362 |
| - f"--outdir={built_wheel_dir}", |
363 |
| - f"--config-setting={config_setting}", |
364 |
| - env=build_env, |
| 324 | + abi3_wheel = find_compatible_abi3_wheel(built_wheels, config.identifier) |
| 325 | + if abi3_wheel: |
| 326 | + log.step_end() |
| 327 | + print( |
| 328 | + f"Found previously built wheel {abi3_wheel.name}, that's compatible with {config.identifier}. Skipping build step..." |
365 | 329 | )
|
| 330 | + repaired_wheel = abi3_wheel |
366 | 331 | else:
|
367 |
| - assert_never(build_options.build_frontend) |
| 332 | + if build_options.before_build: |
| 333 | + log.step("Running before_build...") |
| 334 | + before_build_prepared = prepare_command( |
| 335 | + build_options.before_build, project=".", package=build_options.package_dir |
| 336 | + ) |
| 337 | + shell(before_build_prepared, env=env) |
| 338 | + |
| 339 | + log.step("Building wheel...") |
| 340 | + built_wheel_dir.mkdir() |
| 341 | + |
| 342 | + verbosity_flags = get_build_verbosity_extra_flags(build_options.build_verbosity) |
| 343 | + |
| 344 | + if build_options.build_frontend == "pip": |
| 345 | + # Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org |
| 346 | + # see https://github.com/pypa/cibuildwheel/pull/369 |
| 347 | + call( |
| 348 | + "python", |
| 349 | + "-m", |
| 350 | + "pip", |
| 351 | + "wheel", |
| 352 | + build_options.package_dir.resolve(), |
| 353 | + f"--wheel-dir={built_wheel_dir}", |
| 354 | + "--no-deps", |
| 355 | + *verbosity_flags, |
| 356 | + env=env, |
| 357 | + ) |
| 358 | + elif build_options.build_frontend == "build": |
| 359 | + config_setting = " ".join(verbosity_flags) |
| 360 | + build_env = env.copy() |
| 361 | + if build_options.dependency_constraints: |
| 362 | + constraint_path = ( |
| 363 | + build_options.dependency_constraints.get_for_python_version( |
| 364 | + config.version |
| 365 | + ) |
| 366 | + ) |
| 367 | + build_env["PIP_CONSTRAINT"] = constraint_path.as_uri() |
| 368 | + build_env["VIRTUALENV_PIP"] = get_pip_version(env) |
| 369 | + call( |
| 370 | + "python", |
| 371 | + "-m", |
| 372 | + "build", |
| 373 | + build_options.package_dir, |
| 374 | + "--wheel", |
| 375 | + f"--outdir={built_wheel_dir}", |
| 376 | + f"--config-setting={config_setting}", |
| 377 | + env=build_env, |
| 378 | + ) |
| 379 | + else: |
| 380 | + assert_never(build_options.build_frontend) |
368 | 381 |
|
369 |
| - built_wheel = next(built_wheel_dir.glob("*.whl")) |
| 382 | + built_wheel = next(built_wheel_dir.glob("*.whl")) |
370 | 383 |
|
371 |
| - repaired_wheel_dir.mkdir() |
| 384 | + repaired_wheel_dir.mkdir() |
372 | 385 |
|
373 |
| - if built_wheel.name.endswith("none-any.whl"): |
374 |
| - raise NonPlatformWheelError() |
| 386 | + if built_wheel.name.endswith("none-any.whl"): |
| 387 | + raise NonPlatformWheelError() |
375 | 388 |
|
376 |
| - if build_options.repair_command: |
377 |
| - log.step("Repairing wheel...") |
| 389 | + if build_options.repair_command: |
| 390 | + log.step("Repairing wheel...") |
378 | 391 |
|
379 |
| - if config_is_universal2: |
380 |
| - delocate_archs = "x86_64,arm64" |
381 |
| - elif config_is_arm64: |
382 |
| - delocate_archs = "arm64" |
| 392 | + if config_is_universal2: |
| 393 | + delocate_archs = "x86_64,arm64" |
| 394 | + elif config_is_arm64: |
| 395 | + delocate_archs = "arm64" |
| 396 | + else: |
| 397 | + delocate_archs = "x86_64" |
| 398 | + |
| 399 | + repair_command_prepared = prepare_command( |
| 400 | + build_options.repair_command, |
| 401 | + wheel=built_wheel, |
| 402 | + dest_dir=repaired_wheel_dir, |
| 403 | + delocate_archs=delocate_archs, |
| 404 | + ) |
| 405 | + shell(repair_command_prepared, env=env) |
383 | 406 | else:
|
384 |
| - delocate_archs = "x86_64" |
385 |
| - |
386 |
| - repair_command_prepared = prepare_command( |
387 |
| - build_options.repair_command, |
388 |
| - wheel=built_wheel, |
389 |
| - dest_dir=repaired_wheel_dir, |
390 |
| - delocate_archs=delocate_archs, |
391 |
| - ) |
392 |
| - shell(repair_command_prepared, env=env) |
393 |
| - else: |
394 |
| - shutil.move(str(built_wheel), repaired_wheel_dir) |
| 407 | + shutil.move(str(built_wheel), repaired_wheel_dir) |
395 | 408 |
|
396 |
| - repaired_wheel = next(repaired_wheel_dir.glob("*.whl")) |
| 409 | + repaired_wheel = next(repaired_wheel_dir.glob("*.whl")) |
397 | 410 |
|
398 |
| - log.step_end() |
| 411 | + log.step_end() |
399 | 412 |
|
400 | 413 | if build_options.test_command and build_options.test_selector(config.identifier):
|
401 | 414 | machine_arch = platform.machine()
|
@@ -521,7 +534,9 @@ def build(options: Options, tmp_path: Path) -> None:
|
521 | 534 | )
|
522 | 535 |
|
523 | 536 | # we're all done here; move it to output (overwrite existing)
|
524 |
| - shutil.move(str(repaired_wheel), build_options.output_dir) |
| 537 | + if abi3_wheel is None: |
| 538 | + shutil.move(str(repaired_wheel), build_options.output_dir) |
| 539 | + built_wheels.append(build_options.output_dir / repaired_wheel.name) |
525 | 540 |
|
526 | 541 | # clean up
|
527 | 542 | shutil.rmtree(identifier_tmp_dir)
|
|
0 commit comments