diff --git a/build.rs b/build.rs index 5806697..092952f 100644 --- a/build.rs +++ b/build.rs @@ -1,10 +1,26 @@ +use std::{env, fs, path::Path}; + fn main() { pyo3_build_config::use_pyo3_cfgs(); + let config = pyo3_build_config::get(); if matches!( - pyo3_build_config::get().implementation(), + config.implementation(), pyo3_build_config::PythonImplementation::CPython ) { println!("cargo:rustc-cfg=CPython"); } println!("cargo:rustc-check-cfg=cfg(CPython)"); + + let link = match env::var("CARGO_CFG_TARGET_OS").as_deref() { + Ok("windows") => format!( + r#"#[link(name = "{}", kind = "raw-dylib")]"#, + config.lib_name().unwrap() + ), + _ => String::new(), + }; + let out = Path::new(&env::var("OUT_DIR").unwrap()).join("extern_libpython.rs"); + let src = format!( + "macro_rules! extern_libpython {{ ($($t:tt)*) => {{ {link} extern \"C\" {{ $($t)* }} }} }}" + ); + fs::write(out, src).unwrap(); } diff --git a/src/ffi/sys.rs b/src/ffi/sys.rs index 38b2809..2458609 100644 --- a/src/ffi/sys.rs +++ b/src/ffi/sys.rs @@ -2,6 +2,10 @@ use pyo3::ffi; -extern "C" { +include!(concat!(env!("OUT_DIR"), "/extern_libpython.rs")); + +extern_libpython! { + // x86 Windows import names drop one leading `_`. + #[cfg_attr(all(windows, target_arch = "x86"), link_name = "__PyDict_NewPresized")] pub(crate) fn _PyDict_NewPresized(minused: ffi::Py_ssize_t) -> *mut ffi::PyObject; }