Skip to content

Commit fbf63c5

Browse files
committed
windows: support building with PGO
We had this partially implemented but it wasn't quite working. It probably got bit rotted once we discovered that static builds and PGO didn't work too well due to linking issues downstream. With shared builds, we're consuming DLLs and there shouldn't be linking issues. So it should be safe to use PGO optimized binaries. This commit also contains a minor fixup or two for Windows builds.
1 parent d80ac64 commit fbf63c5

File tree

1 file changed

+50
-19
lines changed

1 file changed

+50
-19
lines changed

cpython-windows/build.py

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import concurrent.futures
88
import datetime
99
import json
10+
import multiprocessing
1011
import os
1112
import pathlib
1213
import re
@@ -802,11 +803,12 @@ def hack_project_files(
802803
# Disable whole program optimization because it interferes with the format
803804
# of object files and makes it so we can't easily consume their symbols.
804805
# TODO this /might/ be OK once we figure out symbol exporting issues.
805-
static_replace_in_file(
806-
pyproject_props,
807-
b"<WholeProgramOptimization>true</WholeProgramOptimization>",
808-
b"<WholeProgramOptimization>false</WholeProgramOptimization>",
809-
)
806+
if static:
807+
static_replace_in_file(
808+
pyproject_props,
809+
b"<WholeProgramOptimization>true</WholeProgramOptimization>",
810+
b"<WholeProgramOptimization>false</WholeProgramOptimization>",
811+
)
810812

811813
# Make libpython a static library.
812814
if static:
@@ -1294,7 +1296,12 @@ def find_additional_dependencies(project: pathlib.Path):
12941296
for obj in process_project("pythoncore", core_dir):
12951297
res["core"]["objs"].append("build/core/%s" % obj)
12961298

1297-
for ext in ("lib", "pdb", "exp"):
1299+
if static:
1300+
exts = ("lib",)
1301+
else:
1302+
exts = ("lib", "pdb", "exp")
1303+
1304+
for ext in exts:
12981305
source = outputs_path / ("python37.%s" % ext)
12991306
dest = core_dir / ("python37.%s" % ext)
13001307
log("copying %s" % source)
@@ -1431,6 +1438,9 @@ def find_additional_dependencies(project: pathlib.Path):
14311438

14321439

14331440
def build_cpython(arch: str, pgo=False, build_mode="static"):
1441+
if pgo and build_mode == "static":
1442+
raise Exception("PGO not supported for static build mode")
1443+
14341444
static = build_mode == "static"
14351445

14361446
msbuild = find_msbuild()
@@ -1529,10 +1539,27 @@ def build_cpython(arch: str, pgo=False, build_mode="static"):
15291539
platform=build_platform,
15301540
)
15311541

1542+
# build-windows.py sets some environment variables which cause the
1543+
# test harness to pick up the wrong `test` module. We unset these
1544+
# so things work as expected.
1545+
env = dict(os.environ)
1546+
paths = [
1547+
p for p in env["PATH"].split(";") if p != str(BUILD / "venv" / "bin")
1548+
]
1549+
env["PATH"] = ";".join(paths)
1550+
del env["PYTHONPATH"]
1551+
15321552
exec_and_log(
1533-
[str(cpython_source_path / "python.bat"), "-m", "test", "--pgo"],
1553+
[
1554+
str(cpython_source_path / "python.bat"),
1555+
"-m",
1556+
"test",
1557+
"--pgo",
1558+
"-j",
1559+
"%d" % (multiprocessing.cpu_count() / 2 - 1),
1560+
],
15341561
str(pcbuild_path),
1535-
os.environ,
1562+
env,
15361563
exit_on_error=False,
15371564
)
15381565

@@ -1675,7 +1702,16 @@ def build_cpython(arch: str, pgo=False, build_mode="static"):
16751702
with (out_dir / "python" / "PYTHON.json").open("w", encoding="utf8") as fh:
16761703
json.dump(python_info, fh, sort_keys=True, indent=4)
16771704

1678-
dest_path = BUILD / ("cpython-windows-%s-%s.tar" % (arch, build_mode))
1705+
basename = "cpython-%s-windows-%s-%s" % (
1706+
DOWNLOADS["cpython-3.7"]["version"],
1707+
arch,
1708+
build_mode,
1709+
)
1710+
if pgo:
1711+
basename += "-pgo"
1712+
basename += ".tar"
1713+
1714+
dest_path = BUILD / basename
16791715

16801716
with dest_path.open("wb") as fh:
16811717
create_tar_from_directory(fh, td / "out")
@@ -1702,6 +1738,9 @@ def main():
17021738
default="static",
17031739
help="How to compile Python",
17041740
)
1741+
parser.add_argument(
1742+
"--pgo", action="store_true", help="Enable profile-guided optimization"
1743+
)
17051744

17061745
args = parser.parse_args()
17071746

@@ -1722,18 +1761,10 @@ def main():
17221761
build_openssl(perl_path, arch)
17231762

17241763
LOG_PREFIX[0] = "cpython"
1725-
tar_path = build_cpython(arch, build_mode=args.build_mode)
1764+
tar_path = build_cpython(arch, build_mode=args.build_mode, pgo=args.pgo)
17261765

17271766
compress_python_archive(
1728-
tar_path,
1729-
DIST,
1730-
"cpython-%s-windows-%s-%s-%s"
1731-
% (
1732-
DOWNLOADS["cpython-3.7"]["version"],
1733-
arch,
1734-
args.build_mode,
1735-
now.strftime("%Y%m%dT%H%M"),
1736-
),
1767+
tar_path, DIST, "%s-%s" % (tar_path.stem, now.strftime("%Y%m%dT%H%M")),
17371768
)
17381769

17391770

0 commit comments

Comments
 (0)