Monday, 25 March 2019

dylib cannot load Rust's libstd when compiled in a workspace

I have a project with the following structure:

Cargo.toml
my_script.py
my_lib:
    - Cargo.toml
    - src
my_bin:
    - Cargo.toml
    - src

Where:

  • my_lib is a Rust library with crate-type = ["dylib"]
  • my_bin is a Rust binary application using my_lib
  • my_script.py is a Python3 script that also uses my_lib

The root Cargo.toml contains a basic workspace declaration:

[workspace]
members = [
    "my_lib",
    "my_bin"
]

Everything works properly if I execute cargo build and cargo run -p my_bin. The problem comes with the Python script.

In this script, I load the my_lib lib file using the following code:

from ctypes import cdll
from sys import platform

if platform == 'darwin':
    prefix = 'lib'
    ext = 'dylib'
elif platform == 'win32':
    prefix = ''
    ext = 'dll'
else:
    prefix = 'lib'
    ext = 'so'

# Working path:
# lib_path = './peglrs/target/debug/{}my_lib.{}'.format(prefix, ext)

# Buggy "Library not loaded: @rpath/libstd-d00eaa6834e55536.dylib" path:
lib_path = './target/debug/{}my_lib.{}'.format(prefix, ext)

lib = cdll.LoadLibrary(lib_path)
my_func = lib.my_func
my_func()

If I use the library file from the library directory (./my_lib/target/...), the script has no problem loading the library and executing its functions.

But if I use the library file from the workspace directory (./target/...) I get the following error when trying to load the library:

OSError: dlopen(./target/debug/libpeglrs.dylib, 6): Library not loaded: @rpath/libstd-d00eaa6834e55536.dylib

In the same fashion, trying to execute my_bin directly from the workspace target directory yield the same error (even though cargo run -p my_bin work flawlessly).

Using the software "Dependency Walker", I found that the my_lib library cannot find the Rust libstd library (has the previous error message explain).

Manually exporting the path that contains the Rust toolchain library into the environment PATH fix the issue. This is however far from ideal and not portable. I also don't understand why this issue is only occurring when using the workspace target.

So, why the workspace target cannot find rust's libstd when each project target can, and is there a way to fix this issue that wouldn't require to find the toolchain path and modify an environment variable ?



from dylib cannot load Rust's libstd when compiled in a workspace

No comments:

Post a Comment