blob: 352bfcb4bf50132149e751bc592de1d334638576 [file] [log] [blame]
import argparse
import multiprocessing
import subprocess
import sys
from datetime import datetime
mutex = multiprocessing.Lock()
def build(wheel):
print("{}: building {}".format(datetime.now(), wheel), file=sys.stderr)
process = subprocess.run(
[sys.executable, "-m", "build", "--wheel", "--no-isolation"], cwd=wheel
)
if process.returncode != 0:
# If the build without isolation fails, try to build it again with
# isolation. We need to protect this following logic in two ways:
# 1. Only build one at a time in this process.
# 2. Retry a few times to get around flakiness.
success = False
for _ in range(0, 3):
with mutex:
process = subprocess.run(
[sys.executable, "-m", "build", "--wheel"],
encoding="utf-8",
cwd=wheel,
capture_output=True,
)
if process.returncode != 0:
continue
success = True
break
if not success:
print("STDOUT:", file=sys.stderr)
print(process.stdout, file=sys.stderr)
print("STDERR:", file=sys.stderr)
print(process.stderr, file=sys.stderr)
raise RuntimeError(
"{}: ERROR: failed to build {}".format(datetime.now(), wheel)
)
def main(jobs, wheels):
with multiprocessing.Pool(jobs) as pool:
results = []
for wheel in wheels:
result = pool.apply_async(build, args=(wheel,))
results.append(result)
pool.close()
for result in results:
result.get()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Builds Python wheels.")
parser.add_argument(
"wheels",
metavar="wheel",
type=str,
nargs="+",
help="A path to the extracted wheel directory.",
)
parser.add_argument(
"--jobs",
type=int,
default=8,
help="The number of concurrent build jobs to be executed.",
)
args = parser.parse_args()
exit(main(args.jobs, args.wheels))