Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build mpdecimal on Windows and fix Python 3.13 validation #7

Merged
merged 10 commits into from
Sep 5, 2024
31 changes: 23 additions & 8 deletions cpython-windows/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@
"_lzma": {
"ignore_additional_depends": {"$(OutDir)liblzma$(PyDebugExt).lib"},
},
"_msi": {},
"_msi": {
# Removed in 3.13.
"ignore_missing": True,
},
"_overlapped": {},
"_multiprocessing": {},
"_socket": {},
Expand Down Expand Up @@ -352,13 +355,15 @@ def hack_props(
xz_version = DOWNLOADS["xz"]["version"]
zlib_version = DOWNLOADS["zlib"]["version"]
tcltk_commit = DOWNLOADS["tk-windows-bin"]["git_commit"]
mpdecimal_version = DOWNLOADS["mpdecimal"]["version"]

sqlite_path = td / ("sqlite-autoconf-%s" % sqlite_version)
bzip2_path = td / ("bzip2-%s" % bzip2_version)
libffi_path = td / "libffi"
tcltk_path = td / ("cpython-bin-deps-%s" % tcltk_commit)
xz_path = td / ("xz-%s" % xz_version)
zlib_path = td / ("zlib-%s" % zlib_version)
mpdecimal_path = td / ("mpdecimal-%s" % mpdecimal_version)

openssl_root = td / "openssl" / arch
openssl_libs_path = openssl_root / "lib"
Expand Down Expand Up @@ -398,6 +403,9 @@ def hack_props(
elif b"<zlibDir" in line:
line = b"<zlibDir>%s\\</zlibDir>" % zlib_path

elif b"<mpdecimalDir" in line:
line = b"<mpdecimalDir>%s\\</mpdecimalDir>" % mpdecimal_path

lines.append(line)

with python_props_path.open("wb") as fh:
Expand Down Expand Up @@ -1155,15 +1163,17 @@ def collect_python_build_artifacts(
"_ctypes_test",
"_testbuffer",
"_testcapi",
"_testclinic_limited",
"_testclinic",
"_testconsole",
"_testembed",
"_testimportmultiple",
"_testinternalcapi",
"_testsinglephase",
"_testlimitedcapi",
"_testmultiphase",
"xxlimited",
"_testsinglephase",
"xxlimited_35",
"xxlimited",
}

other_projects = {"pythoncore"}
Expand Down Expand Up @@ -1409,6 +1419,12 @@ def build_cpython(
setuptools_wheel = download_entry("setuptools", BUILD)
pip_wheel = download_entry("pip", BUILD)

# CPython 3.13+ no longer uses a bundled version by default
if meets_python_minimum_version(python_version, "3.13"):
mpdecimal_archive = download_entry("mpdecimal", BUILD)
else:
mpdecimal_archive = None

if arch == "amd64":
build_platform = "x64"
build_directory = "amd64"
Expand All @@ -1426,12 +1442,16 @@ def build_cpython(
for a in (
python_archive,
bzip2_archive,
mpdecimal_archive,
openssl_archive,
sqlite_archive,
tk_bin_archive,
xz_archive,
zlib_archive,
):
if a is None:
continue

log("extracting %s to %s" % (a, td))
fs.append(e.submit(extract_tar_to_directory, a, td))

Expand Down Expand Up @@ -1599,11 +1619,6 @@ def build_cpython(
if not meets_python_minimum_version(python_version, "3.12"):
args.append("--include-distutils")

# CPython 3.13+ no longer uses a bundled libmpdec by default
# TODO(zanieb): We should use the system libmpdec as we do for Unix builds
if meets_python_minimum_version(python_version, "3.13"):
args.append("--with-system-libmpdec=no")

args.extend(["--include-idle", "--include-stable", "--include-tcltk"])

exec_and_log(
Expand Down
24 changes: 17 additions & 7 deletions src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ const PE_ALLOWED_LIBRARIES: &[&str] = &[
"python310.dll",
"python311.dll",
"python312.dll",
"python313.dll",
"sqlite3.dll",
"tcl86t.dll",
"tk86t.dll",
Expand Down Expand Up @@ -679,7 +680,13 @@ const GLOBAL_EXTENSIONS: &[&str] = &[
// We didn't build ctypes_test until 3.9.
// We didn't build some test extensions until 3.9.

const GLOBAL_EXTENSIONS_PYTHON_3_8: &[&str] = &["audioop", "_sha256", "_sha512", "parser"];
const GLOBAL_EXTENSIONS_PYTHON_3_8: &[&str] = &[
"audioop",
"_sha256",
"_sha512",
"parser",
"_xxsubinterpreters",
];

const GLOBAL_EXTENSIONS_PYTHON_3_9: &[&str] = &[
"audioop",
Expand Down Expand Up @@ -727,9 +734,7 @@ const GLOBAL_EXTENSIONS_PYTHON_3_13: &[&str] = &[
"_interpqueues",
"_interpreters",
"_sha2",
"_suggestions",
"_sysconfig",
"_testexternalinspection",
"_tokenize",
"_typing",
"_zoneinfo",
Expand Down Expand Up @@ -759,16 +764,16 @@ const GLOBAL_EXTENSIONS_POSIX: &[&str] = &[
const GLOBAL_EXTENSIONS_LINUX_PRE_3_13: &[&str] = &["spwd"];

const GLOBAL_EXTENSIONS_WINDOWS: &[&str] = &[
"_msi",
"_overlapped",
"_winapi",
"_xxsubinterpreters",
"msvcrt",
"nt",
"winreg",
"winsound",
];

const GLOBAL_EXTENSIONS_WINDOWS_PRE_3_13: &[&str] = &["_msi"];

/// Extension modules not present in Windows static builds.
const GLOBAL_EXTENSIONS_WINDOWS_NO_STATIC: &[&str] = &["_testinternalcapi", "_tkinter"];

Expand Down Expand Up @@ -1494,6 +1499,10 @@ fn validate_extension_modules(
if is_windows {
wanted.extend(GLOBAL_EXTENSIONS_WINDOWS);

if matches!(python_major_minor, "3.8" | "3.9" | "3.10" | "3.11" | "3.12") {
wanted.extend(GLOBAL_EXTENSIONS_WINDOWS_PRE_3_13);
}

if static_crt {
for x in GLOBAL_EXTENSIONS_WINDOWS_NO_STATIC {
wanted.remove(*x);
Expand Down Expand Up @@ -1949,9 +1958,10 @@ fn validate_distribution(
// Static distributions never export symbols.
let wanted = if is_static {
false
// For some strange reason _PyWarnings_Init is exported as part of the ABI.
// For some strange reason _PyWarnings_Init is exported as part of the ABI before
// Python 3.13.
} else if name == "_warnings" {
true
matches!(python_major_minor, "3.8" | "3.9" | "3.10" | "3.11" | "3.12")
// Windows dynamic doesn't export extension module init functions.
} else if triple.contains("-windows-") {
false
Expand Down
Loading