|
| 1 | +/// Sets up the necessary Cargo directives for linking against the Python library. |
| 2 | +/// |
| 3 | +/// This function should be called from the `build.rs` script of any crate |
| 4 | +/// within the workspace whose compiled artifact (e.g., test executable, binary) |
| 5 | +/// needs to link against the Python C API at compile time and find the |
| 6 | +/// corresponding shared library at runtime. This is typically required for |
| 7 | +/// crates using `pyo3` features like `Python::with_gil` or defining `#[pyfunction]`s |
| 8 | +/// directly in their test or binary code. |
| 9 | +/// |
| 10 | +/// It uses `pyo3-build-config` to detect the active Python installation and |
| 11 | +/// prints the required `cargo:rustc-link-search` and `cargo:rustc-link-lib` |
| 12 | +/// directives to Cargo, enabling the linker to find and link against the |
| 13 | +/// appropriate Python library (e.g., libpythonX.Y.so). |
| 14 | +/// |
| 15 | +/// It also adds an RPATH linker argument on Unix-like systems (`-Wl,-rpath,...`) |
| 16 | +/// to help the resulting executable find the Python shared library at runtime |
| 17 | +/// without needing manual `LD_LIBRARY_PATH` adjustments in typical scenarios. |
| 18 | +pub fn setup_python_linking() { |
| 19 | + // Instruct Cargo to rerun the calling build script if the Python config changes. |
| 20 | + // Using PYO3_CONFIG_FILE is a reliable way to detect changes in the active Python env. |
| 21 | + println!("cargo:rerun-if-changed=build.rs"); |
| 22 | + |
| 23 | + // Set up #[cfg] flags first (useful for conditional compilation) |
| 24 | + pyo3_build_config::use_pyo3_cfgs(); |
| 25 | + |
| 26 | + // Get the Python interpreter configuration directly |
| 27 | + let config = pyo3_build_config::get(); |
| 28 | + |
| 29 | + // Add the library search path if available |
| 30 | + if let Some(lib_dir) = &config.lib_dir { |
| 31 | + println!("cargo:rustc-link-search=native={}", lib_dir); |
| 32 | + |
| 33 | + // Add RPATH linker argument for Unix-like systems (Linux, macOS) |
| 34 | + // This helps the test executable find the Python library at runtime. |
| 35 | + #[cfg(not(windows))] |
| 36 | + println!("cargo:rustc-link-arg=-Wl,-rpath,{}", lib_dir); |
| 37 | + } else { |
| 38 | + println!("cargo:warning=Python library directory not found in config."); |
| 39 | + } |
| 40 | + |
| 41 | + // Add the library link directive if available |
| 42 | + if let Some(lib_name) = &config.lib_name { |
| 43 | + println!("cargo:rustc-link-lib=dylib={}", lib_name); |
| 44 | + } else { |
| 45 | + println!("cargo:warning=Python library name not found in config."); |
| 46 | + } |
| 47 | +} |
0 commit comments