OS X 上的 Rust 和加载器路径 (@rpath, @loader_path)

4

我正在尝试解决Rust中与外部库加载相关的问题。

输入:

我有一个可执行文件rtest和一个动态链接库libcpp2rs.dylib。该库通过FFI链接到可执行文件中:

#[link(name="cpp2rs")]
extern { ... }

这是我的build.rs文件(我传递了一个额外的参数,指定了libcpp2rs.dylib的位置):

pub fn main() {
    println!("cargo:rustc-link-search=native=./cpplib/bin");
}

我的 Cargo.toml 文件:

[package]
name = "rtest"
version = "0.1.0"
authors = ["astavonin"]
build = "build.rs"
rpath = true
[dependencies]
libc = "0.2.10"

我使用 cargo build 命令进行编译。

输出结果:

otool 显示该库将由 RPATH 加载:

> otool -L rtest
rtest:
@rpath/libcpp2rs.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)

但是同时可执行文件中没有LC_LPATH部分:

> otool -l rtest | grep LC_RPATH
>

它导致我的应用程序出现加载错误:

> ./rtest 
dyld: Library not loaded: @rpath/libcpp2rs.dylib
  Referenced from: /Users/astavonin/projects/Tests/rtest/target/debug/./rtest
  Reason: image not found
zsh: trace trap  ./rtest

这个问题可以通过使用install_name_tool来解决,但我更倾向于不在编译过程中引入额外的步骤。
1. 是否可能(以及如何)通过cargo配置/构建脚本将加载类型从@rpath更改为@loader_path? 2. 是否可能将@rpath值传递给cargo

请编辑您的问题,包括 libcpp2rs.dylib 的位置,您如何告知 Rust 它的位置以及您如何构建代码。 - Shepmaster
1个回答

5

经过一些调查,我发现实际问题是libcpp2rs.dylib的ID:

> otool -L cpplib/bin/libcpp2rs.dylib 
cpplib/bin/libcpp2rs.dylib:
    @rpath/libcpp2rs.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)

rustc 使用动态库 ID 作为链接类型的参考,如果你想将一个库的链接类型更改为例如 @loader_path,你需要修复动态库 ID。应该像这样:

@loader_path/libcpp2rs.dylib (compatibility version 0.0.0, current version 0.0.0)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接