pyo3
pyo3 copied to clipboard
Python shared object not found while using pyenv
🐛 Python shared object not found while using pyenv
🌍 Environment
- Your operating system and version: Windows 10 20h2 + WSL2
- Your python version: 3.7.9
- How did you install python (e.g. apt or pyenv)? Did you use a virtualenv?:
env PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install 3.7.9 - Your Rust version (
rustc --version): rustc 1.51.0 (2fd73fabe 2021-03-23) - Your PyO3 version: *0.13.2
- Have you tried using latest PyO3 main (replace
version = "0.x.y"withgit = "https://github.com/PyO3/pyo3")?: yes
💥 Reproducing
main.rs
use pyo3::prelude::*;
use pyo3::types::IntoPyDict;
fn main() -> Result<(), ()> {
Python::with_gil(|py| {
main_(py).map_err(|e| {
// We can't display Python exceptions via std::fmt::Display,
// so print the error here manually.
e.print_and_set_sys_last_vars(py);
})
})
}
fn main_(py: Python) -> PyResult<()> {
let sys = py.import("sys")?;
let version: String = sys.get("version")?.extract()?;
let locals = [("os", py.import("os")?)].into_py_dict(py);
let code = "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'";
let user: String = py.eval(code, None, Some(&locals))?.extract()?;
println!("Hello {}, I'm Python {}", user, version);
Ok(())
}
cargo run
Result
error while loading shared libraries: libpython3.7m.so.1.0: cannot open shared object file: No such file or directory
Workaround
export LD_LIBRARY_PATH=~/.pyenv/versions/3.7.9/lib
Thanks for reporting. It's expected that you will need to set LD_LIBRARY_PATH, however I agree the documentation could make this clearer. I'll try to add something.
I've created this build.rs script to fix the problem for me:
fn main() {
let home = std::env::var("HOME").expect("${HOME} is missing");
println!("cargo:rustc-env=LD_LIBRARY_PATH={home}/.pyenv/versions/3.11.2/lib");
}
I found trying to use a cargo config with a home reference/variable wasn't resolving and I didn't want to hard-code the path.
I used https://github.com/pyenv/pyenv/issues/2647#issuecomment-1511754155, inside .bashrc or .zshrc:
for version in $(pyenv versions --bare)
do
export LD_LIBRARY_PATH="$(pyenv root)/versions/$version/lib:$LD_LIBRARY_PATH"
done
My fix for this in VSCODE is updating settings.json with following entry.
{
"rust-analyzer.runnables.extraEnv": {
"LD_LIBRARY_PATH": "/home/anuvini/mambaforge/lib:$LD_LIBRARY_PATH"
}
}
VSCODE did not respect my bashrc having the export statement.
Is there an explicit way to have it find this, or is setting an env var the current state of the art?
To state the obvious for anyone who hadn't thought of it, simply deactivating your env is one way (if you're just building/running cargo tests)