Skip to content

Commit c5e974c

Browse files
committed
unix: support building multiple Python versions in parallel
`build-main.py` now passes in space delimited Python versions to build, which the Makefile can happily translate to appropriate make targets for us. We added support for `--python all` to allow building all supported Python versions.
1 parent 881e4c1 commit c5e974c

File tree

2 files changed

+45
-24
lines changed

2 files changed

+45
-24
lines changed

cpython-unix/Makefile

+4-4
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ ifndef PYBUILD_PYTHON_SOURCE
2424
$(error PYBUILD_PYTHON_SOURCE not defined)
2525
endif
2626

27-
ifndef PYBUILD_PYTHON_VERSION
28-
$(error PYBUILD_PYTHON_VERSION not defined)
27+
ifndef PYBUILD_PYTHON_VERSIONS
28+
$(error PYBUILD_PYTHON_VERSIONS not defined)
2929
endif
3030

31-
PYTHON_MAJOR_VERSION := $(subst $(SPACE),.,$(wordlist 1,2,$(subst .,$(SPACE),$(PYBUILD_PYTHON_VERSION))))
31+
BUILD_MAJOR_VERSIONS := $(foreach version,$(PYBUILD_PYTHON_VERSIONS),$(subst $(SPACE),.,$(wordlist 1,2,$(subst .,$(SPACE),$(version)))))
3232

3333
TARGET_TRIPLE := $(PYBUILD_TARGET_TRIPLE)
3434
HOST_PLATFORM := $(PYBUILD_HOST_PLATFORM)
@@ -70,7 +70,7 @@ PYTHON_DEP_DEPENDS := \
7070
$(TOOLCHAIN_DEPENDS) \
7171
$(NULL)
7272

73-
default: $(OUTDIR)/cpython-$(CPYTHON_$(PYTHON_MAJOR_VERSION)_VERSION)-$(PACKAGE_SUFFIX).tar
73+
default: $(foreach version,$(BUILD_MAJOR_VERSIONS),$(OUTDIR)/cpython-$(CPYTHON_$(version)_VERSION)-$(PACKAGE_SUFFIX).tar)
7474

7575
ifndef PYBUILD_NO_DOCKER
7676
$(OUTDIR)/image-%.tar: $(OUTDIR)/%.Dockerfile

cpython-unix/build-main.py

+41-20
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ def main():
6363
parser.add_argument(
6464
"--python",
6565
choices={
66+
"all",
6667
"cpython-3.9",
6768
"cpython-3.10",
6869
"cpython-3.11",
@@ -117,13 +118,23 @@ def main():
117118

118119
supported_pythons = {"cpython-%s" % p for p in settings["pythons_supported"]}
119120

120-
if args.python not in supported_pythons:
121+
if args.python != "all" and args.python not in supported_pythons:
121122
print(
122123
"%s only supports following Pythons: %s"
123124
% (target_triple, ", ".join(supported_pythons))
124125
)
125126
return 1
126127

128+
if args.python == "all":
129+
if args.python_source:
130+
print("--python-source is not compatible with --python all")
131+
return 1
132+
133+
# This can be removed once 3.13 is the minimum version.
134+
if "freethreaded" in args.options:
135+
print("freedthreaded builds not compatible with --python all")
136+
return 1
137+
127138
python_source = (
128139
(str(pathlib.Path(args.python_source).resolve()))
129140
if args.python_source
@@ -145,41 +156,40 @@ def main():
145156
if args.no_docker:
146157
env["PYBUILD_NO_DOCKER"] = "1"
147158

148-
if not args.python_source:
149-
entry = DOWNLOADS[args.python]
150-
env["PYBUILD_PYTHON_VERSION"] = cpython_version = entry["version"]
159+
if args.python == "all":
160+
cpython_versions = [
161+
DOWNLOADS["cpython-%s" % p]["version"]
162+
for p in settings["pythons_supported"]
163+
]
164+
165+
elif not args.python_source:
166+
cpython_versions = [DOWNLOADS[args.python]["version"]]
151167
else:
152168
# TODO consider parsing version from source checkout. Or defining version
153169
# from CLI argument.
154170
if "PYBUILD_PYTHON_VERSION" not in env:
155171
print("PYBUILD_PYTHON_VERSION must be set when using `--python-source`")
156172
return 1
157-
cpython_version = env["PYBUILD_PYTHON_VERSION"]
173+
cpython_versions = [env["PYBUILD_PYTHON_VERSION"]]
174+
175+
env["PYBUILD_PYTHON_VERSIONS"] = " ".join(cpython_versions)
158176

159-
python_majmin = ".".join(cpython_version.split(".")[0:2])
177+
python_majmins = [".".join(v.split(".")[0:2]) for v in cpython_versions]
160178

161179
if "PYBUILD_RELEASE_TAG" in os.environ:
162180
release_tag = os.environ["PYBUILD_RELEASE_TAG"]
163181
else:
164182
release_tag = release_tag_from_git()
165183

166-
# Guard against accidental misuse of the free-threaded flag with older versions
167-
if "freethreaded" in args.options and python_majmin not in ("3.13",):
184+
# Guard against accidental misuse of the free-threaded flag with older versions.
185+
if "freethreaded" in args.options and any(
186+
v not in ("3.13",) for v in python_majmins
187+
):
168188
print(
169-
"Invalid build option: 'freethreaded' is only compatible with CPython 3.13+ (got %s)"
170-
% cpython_version
189+
"Invalid build option: 'freethreaded' is only compatible with CPython 3.13+"
171190
)
172191
return 1
173192

174-
archive_components = [
175-
"cpython-%s" % cpython_version,
176-
target_triple,
177-
args.options,
178-
]
179-
180-
build_basename = "-".join(archive_components) + ".tar"
181-
dist_basename = "-".join(archive_components + [release_tag])
182-
183193
# We run make with static parallelism no greater than the machine's CPU count
184194
# because we can get some speedup from parallel operations. But we also don't
185195
# share a make job server with each build. So if we didn't limit the
@@ -195,7 +205,18 @@ def main():
195205
DIST.mkdir(exist_ok=True)
196206

197207
if args.make_target == "default":
198-
compress_python_archive(BUILD / build_basename, DIST, dist_basename)
208+
# TODO this could be made parallel.
209+
for version in cpython_versions:
210+
archive_components = [
211+
"cpython-%s" % version,
212+
target_triple,
213+
args.options,
214+
]
215+
216+
build_basename = "-".join(archive_components) + ".tar"
217+
dist_basename = "-".join(archive_components + [release_tag])
218+
219+
compress_python_archive(BUILD / build_basename, DIST, dist_basename)
199220

200221

201222
if __name__ == "__main__":

0 commit comments

Comments
 (0)