diff --git a/mingw-w64-python-cryptography/PKGBUILD b/mingw-w64-python-cryptography/PKGBUILD index c4c55412bbdad..c74047dda7bcf 100644 --- a/mingw-w64-python-cryptography/PKGBUILD +++ b/mingw-w64-python-cryptography/PKGBUILD @@ -3,7 +3,7 @@ _realname=cryptography pkgbase=mingw-w64-python-${_realname} pkgname=("${MINGW_PACKAGE_PREFIX}-python-${_realname}") -pkgver=48.0.1 +pkgver=49.0.0 pkgrel=1 pkgdesc="A package designed to expose cryptographic recipes and primitives to Python developers (mingw-w64)" arch=('any') @@ -29,19 +29,39 @@ makedepends=("${MINGW_PACKAGE_PREFIX}-python-build" "${MINGW_PACKAGE_PREFIX}-python-maturin" "${MINGW_PACKAGE_PREFIX}-rust" "${MINGW_PACKAGE_PREFIX}-cc" - "${MINGW_PACKAGE_PREFIX}-pkgconf") + "${MINGW_PACKAGE_PREFIX}-pkgconf" + "git") checkdepends=( #"${MINGW_PACKAGE_PREFIX}-python-iso8601" "${MINGW_PACKAGE_PREFIX}-python-pretend" #"${MINGW_PACKAGE_PREFIX}-python-cryptography-vectors" "${MINGW_PACKAGE_PREFIX}-python-hypothesis" "${MINGW_PACKAGE_PREFIX}-python-pytz") -source=("https://pypi.org/packages/source/${_realname::1}/${_realname}/${_realname}-${pkgver}.tar.gz") -sha256sums=('266f4ee051abb2f725b74ef8072b521ce1feacf685a3364fa6a6b45548db791a') +source=("https://pypi.org/packages/source/${_realname::1}/${_realname}/${_realname}-${pkgver}.tar.gz" + "git+https://github.com/PyO3/pyo3#tag=v0.29.0" + "pyo3-fix-python-abi-linking.patch") +sha256sums=('f89660a348f4f78a92366240a61404e337586ef7f5909a2fef59ca88ef505493' + '03411beda834ac76b28742d97fc3136bbbcbb4738598fd21633e78301f916e17' + '0b815dcb69127b60bd8250df5f5f4f57e94458240bd634cd2c5c6a4823d7b75b') + +prepare() { + cd "${_realname}-${pkgver}" + + patch -d ../pyo3 -p1 -i ../pyo3-fix-python-abi-linking.patch + cat >> Cargo.toml < String { + } + + fn default_lib_name_windows(abi: PythonAbi, mingw: bool, debug: bool) -> Result { ++ // mingw formats lib names like unix, and uses a "lib" prefix. We could let the linker ++ // handle "lib" prefix, but that means the `raw-dylib` name is incorrect (where the ++ // "lib" prefix is not automatically added).) ++ if mingw { ++ let mut lib_name = default_lib_name_unix(abi, true, None)?; ++ lib_name.insert_str(0, "lib"); ++ return Ok(lib_name); ++ } ++ + if abi.implementation.is_pypy() { + // PyPy on Windows ships `libpypy3.X-c.dll` (e.g. `libpypy3.11-c.dll`), + // not CPython's `pythonXY.dll`. With raw-dylib linking we need the real +@@ -2341,13 +2341,6 @@ fn default_lib_name_windows(abi: PythonAbi, mingw: bool, debug: bool) -> Result< + lib_name = lib_name.replace("python3", "python3t"); + } + Ok(lib_name) +- } else if mingw { +- ensure!( +- !abi.kind.is_free_threaded(), +- "MinGW free-threaded builds are not currently tested or supported" +- ); +- // https://packages.msys2.org/base/mingw-w64-python +- Ok(format!("python{}.{}", abi.version.major, abi.version.minor)) + } else if abi.kind().is_free_threaded() { + #[expect(deprecated, reason = "using constant internally")] + { +@@ -2371,28 +2364,36 @@ fn default_lib_name_windows(abi: PythonAbi, mingw: bool, debug: bool) -> Result< + } + } + +-fn default_lib_name_unix(abi: PythonAbi, cygwin: bool, ld_version: Option<&str>) -> Result { ++fn default_lib_name_unix( ++ abi: PythonAbi, ++ use_stable_abi_lib: bool, ++ ld_version: Option<&str>, ++) -> Result { + match abi.implementation { + PythonImplementation::CPython => match ld_version { + Some(ld_version) => Ok(format!("python{ld_version}")), +- None => { +- if cygwin && matches!(abi.kind, PythonAbiKind::Stable(StableAbi::Abi3)) { ++ None => match abi.kind { ++ PythonAbiKind::Stable(StableAbi::Abi3) if use_stable_abi_lib => { + Ok("python3".to_string()) +- } else if cygwin && matches!(abi.kind, PythonAbiKind::Stable(StableAbi::Abi3t)) { ++ } ++ PythonAbiKind::Stable(StableAbi::Abi3t) if use_stable_abi_lib => { + Ok("python3t".to_string()) +- } else if abi.kind.is_free_threaded() { +- #[expect(deprecated, reason = "using constant internally")] +- { +- ensure!(abi.version >= PythonVersion::PY313, "Cannot compile extensions for the free-threaded build on Python versions earlier than 3.13, found {}.{}", abi.version.major, abi.version.minor); ++ } ++ _ => { ++ if abi.kind.is_free_threaded() { ++ #[expect(deprecated, reason = "using constant internally")] ++ { ++ ensure!(abi.version >= PythonVersion::PY313, "Cannot compile extensions for the free-threaded build on Python versions earlier than 3.13, found {}.{}", abi.version.major, abi.version.minor); ++ } ++ Ok(format!( ++ "python{}.{}t", ++ abi.version.major, abi.version.minor ++ )) ++ } else { ++ Ok(format!("python{}.{}", abi.version.major, abi.version.minor)) + } +- Ok(format!( +- "python{}.{}t", +- abi.version.major, abi.version.minor +- )) +- } else { +- Ok(format!("python{}.{}", abi.version.major, abi.version.minor)) + } +- } ++ }, + }, + PythonImplementation::PyPy => match ld_version { + Some(ld_version) => Ok(format!("pypy{ld_version}-c")), +--- a/pyo3-build-config/src/lib.rs ++++ b/pyo3-build-config/src/lib.rs +@@ -164,34 +164,6 @@ pub fn print_expected_cfgs() { + for i in impl_::MINIMUM_SUPPORTED_VERSION.minor..=impl_::STABLE_ABI_MAX_MINOR + 1 { + println!("cargo:rustc-check-cfg=cfg(Py_3_{i})"); + } +- +- // pyo3_dll cfg for raw-dylib linking on Windows +- let mut dll_names = vec![ +- "python3".to_string(), +- "python3_d".to_string(), +- "python3t".to_string(), +- "python3t_d".to_string(), +- ]; +- for i in impl_::MINIMUM_SUPPORTED_VERSION.minor..=impl_::STABLE_ABI_MAX_MINOR + 1 { +- dll_names.push(format!("python3{i}")); +- dll_names.push(format!("python3{i}_d")); +- if i >= 13 { +- dll_names.push(format!("python3{i}t")); +- dll_names.push(format!("python3{i}t_d")); +- } +- } +- // PyPy DLL names (libpypy3.X-c.dll) +- for i in +- impl_::MINIMUM_SUPPORTED_VERSION_PYPY.minor..=impl_::MAXIMUM_SUPPORTED_VERSION_PYPY.minor +- { +- dll_names.push(format!("libpypy3.{i}-c")); +- } +- let values = dll_names +- .iter() +- .map(|n| format!("\"{n}\"")) +- .collect::>() +- .join(", "); +- println!("cargo:rustc-check-cfg=cfg(pyo3_dll, values({values}))"); + } + + /// Private exports used in PyO3's build.rs +--- a/pyo3-ffi/build.rs ++++ b/pyo3-ffi/build.rs +@@ -191,15 +191,79 @@ fn ensure_target_pointer_width(interpreter_config: &InterpreterConfig) -> Result + Ok(()) + } + ++/// `raw-dylib` currently does not support arbitrary names ++/// (see https://internals.rust-lang.org/t/support-renames-with-link-name-kind-raw-dylib/24415) ++/// so if the lib name is not one of the known subset, we must fall back to full linking. ++fn lib_name_is_known_for_raw_dylib(lib_name: &str) -> bool { ++ // pyo3_dll cfg for raw-dylib linking on Windows ++ if matches!( ++ lib_name, ++ "python3" | "python3_d" | "python3t" | "python3t_d" ++ ) { ++ return true; ++ } ++ ++ // support raw-dylib linking for all CPython versions supported, plus the next prerelease ++ for i in SUPPORTED_VERSIONS_CPYTHON.min.minor..=SUPPORTED_VERSIONS_CPYTHON.max.minor + 1 { ++ if lib_name == format!("python3{i}") || lib_name == format!("python3{i}_d") { ++ return true; ++ } ++ if i >= 13 && (lib_name == format!("python3{i}t") || lib_name == format!("python3{i}t_d")) { ++ return true; ++ } ++ } ++ // PyPy DLL names (libpypy3.X-c.dll) ++ for i in SUPPORTED_VERSIONS_PYPY.min.minor..=SUPPORTED_VERSIONS_PYPY.max.minor { ++ if lib_name == format!("libpypy3.{i}-c") { ++ return true; ++ } ++ } ++ ++ false ++} ++ ++/// Whether to use raw-dylib linking. ++/// ++/// Currently, this only applies if all of the following are true: ++/// - The target OS is Windows. ++/// - The Python library name is one of the [known subset][lib_name_is_known_for_raw_dylib]. ++/// - The `PYO3_USE_RAW_DYLIB` environment variable is not set, or is set to `1`. ++/// ++/// NB in some cases (e.g. mixed C / Rust builds) it might be necessary to link the full Python ++/// library rather than rely on the symbols which PyO3 defines as raw-dylib, which is why ++/// we have the opt-out env var. ++fn should_use_raw_dylib_linking(lib_name: &str) -> bool { ++ let target_os = cargo_env_var("CARGO_CFG_TARGET_OS").unwrap(); ++ if target_os != "windows" { ++ return false; ++ } ++ ++ match ( ++ lib_name_is_known_for_raw_dylib(lib_name), ++ env_var("PYO3_USE_RAW_DYLIB"), ++ ) { ++ (true, None) => true, ++ (true, Some(os_str)) if os_str == "1" => true, ++ (false, Some(os_str)) if os_str == "1" => { ++ warn!( ++ "PYO3_USE_RAW_DYLIB is set to 1 but the Python library name is not recognized. \ ++ Falling back to full linking." ++ ); ++ false ++ } ++ _ => false, ++ } ++} ++ + fn emit_link_config(build_config: &BuildConfig) -> Result<()> { +- let interpreter_config = &build_config.interpreter_config; + let target_os = cargo_env_var("CARGO_CFG_TARGET_OS").unwrap(); ++ let interpreter_config = &build_config.interpreter_config; + + let lib_name = interpreter_config + .lib_name() + .ok_or("attempted to link to Python shared library but config does not contain lib_name")?; + +- if target_os == "windows" { ++ if should_use_raw_dylib_linking(lib_name) { + // Use raw-dylib linking: emit a cfg so that `extern_libpython!` picks the + // right `#[link(name = "...", kind = "raw-dylib")]` attribute at compile time. + // This eliminates the need for import libraries (.lib files) entirely. +@@ -207,27 +271,36 @@ fn emit_link_config(build_config: &BuildConfig) -> Result<()> { + // Note: raw-dylib is inherently dynamic linking. Static embedding of the + // Python interpreter on Windows is not supported by this path (and is not + // officially supported by CPython on Windows). ++ println!("cargo:rustc-cfg=pyo3_use_raw_dylib"); + println!("cargo:rustc-cfg=pyo3_dll=\"{lib_name}\""); +- } else { +- println!( +- "cargo:rustc-link-lib={link_model}{lib_name}", +- link_model = if interpreter_config.shared() { +- "" +- } else { +- "static=" +- }, +- ); ++ return Ok(()); ++ } + +- if let Some(lib_dir) = interpreter_config.lib_dir() { +- println!("cargo:rustc-link-search=native={lib_dir}"); +- } else if matches!(build_config.source, BuildConfigSource::CrossCompile) { +- warn!( +- "The output binary will link to libpython, \ +- but PYO3_CROSS_LIB_DIR environment variable is not set. \ +- Ensure that the target Python library directory is \ +- in the rustc native library search path." +- ); ++ println!( ++ "cargo:rustc-link-lib={link_model}{alias}{lib_name}", ++ link_model = if interpreter_config.shared() { ++ "" ++ } else { ++ "static=" ++ }, ++ // on windows we emit `#[link(name = "pythonXY")]` attributes ++ // and need this alias here to get the right name for the final link ++ alias = if target_os == "windows" { ++ "pythonXY:" ++ } else { ++ "" + } ++ ); ++ ++ if let Some(lib_dir) = interpreter_config.lib_dir() { ++ println!("cargo:rustc-link-search=native={lib_dir}"); ++ } else if matches!(build_config.source, BuildConfigSource::CrossCompile) { ++ warn!( ++ "The output binary will link to libpython, \ ++ but PYO3_CROSS_LIB_DIR environment variable is not set. \ ++ Ensure that the target Python library directory is \ ++ in the rustc native library search path." ++ ); + } + + Ok(()) +--- a/pyo3-ffi/src/impl_/macros.rs ++++ b/pyo3-ffi/src/impl_/macros.rs +@@ -268,10 +268,12 @@ macro_rules! extern_libpython { + "python313", "python313_d", + "python314", "python314_d", + "python315", "python315_d", ++ "python316", "python316_d", + // free-threaded builds (3.13+) + "python313t", "python313t_d", + "python314t", "python314t_d", + "python315t", "python315t_d", ++ "python316t", "python316t_d", + // PyPy (DLL is libpypy3.X-c.dll, not pythonXY.dll) + "libpypy3.11-c", + ); +@@ -286,11 +288,12 @@ macro_rules! extern_libpython { + // separate cfg_attr arms per architecture. + (@impl $abi:literal { $($body:tt)* } $($dll:literal),* $(,)?) => { + $( +- #[cfg_attr(all(windows, target_arch = "x86", pyo3_dll = $dll), ++ #[cfg_attr(all(windows, pyo3_use_raw_dylib, target_arch = "x86", pyo3_dll = $dll), + link(name = $dll, kind = "raw-dylib", import_name_type = "undecorated"))] +- #[cfg_attr(all(windows, not(target_arch = "x86"), pyo3_dll = $dll), ++ #[cfg_attr(all(windows, pyo3_use_raw_dylib, not(target_arch = "x86"), pyo3_dll = $dll), + link(name = $dll, kind = "raw-dylib"))] + )* ++ #[cfg_attr(all(windows, not(pyo3_use_raw_dylib)), link(name = "pythonXY"))] + extern $abi { + extern_libpython_items! { $($body)* } + } diff --git a/mingw-w64-python-pyopenssl/PKGBUILD b/mingw-w64-python-pyopenssl/PKGBUILD index 1252f6d6c1e9b..08c07c8e5507a 100644 --- a/mingw-w64-python-pyopenssl/PKGBUILD +++ b/mingw-w64-python-pyopenssl/PKGBUILD @@ -3,7 +3,7 @@ _realname=pyopenssl pkgbase=mingw-w64-python-${_realname} pkgname=("${MINGW_PACKAGE_PREFIX}-python-${_realname}") -pkgver=26.2.0 +pkgver=26.3.0 pkgrel=1 pkgdesc="Python wrapper module around the OpenSSL library (mingw-w64)" arch=('any') @@ -26,7 +26,7 @@ makedepends=("${MINGW_PACKAGE_PREFIX}-python-build" "${MINGW_PACKAGE_PREFIX}-python-setuptools") checkdepends=("${MINGW_PACKAGE_PREFIX}-python-pytest") source=("https://pypi.org/packages/source/${_realname::1}/${_realname}/${_realname}-${pkgver}.tar.gz") -sha256sums=('8c6fcecd1183a7fc897548dfe388b0cdb7f37e018200d8409cf33959dbe35387') +sha256sums=('589de7fae1c9ea670d18422ed00fc04da787bbde8e1454aea872aa57b49ad341') build() { cp -r "${_realname}-${pkgver}" "python-build-${MSYSTEM}" && cd "python-build-${MSYSTEM}"