下面是一个完整的解决方案...
我创建了一个C库导出一个简单的加法功能。我还创建了一个货物项目来使用这个功能。
/scratch
├── executable
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── build.rs
│ ├── src
│ │ ├── main.rs
└── library
├── awesome_math.c
└── libawesome_math.so
awesome_math.c
#include <stdint.h>
uint8_t from_the_library(uint8_t a, uint8_t b) {
return a + b;
}
库被编译为gcc -g -shared awesome_math.c -o libawesome_math.so
。
src.rs
extern crate libc;
extern {
fn from_the_library(a: libc::uint8_t, b: libc::uint8_t) -> libc::uint8_t;
}
fn main() {
unsafe {
println!("Adding: {}", from_the_library(1, 2));
}
}
build.rs
fn main() {
println!("cargo:rustc-link-lib=dylib=awesome_math");
println!("cargo:rustc-link-search=native=/scratch/library");
}
Cargo.toml
[package]
name = "executable"
version = "0.1.0"
authors = ["An Devloper <[email protected]>"]
build = "build.rs"
[dependencies]
libc = "*"
[profile.dev]
rpath = true
做这一切exhib的它与你经历的同样的问题。 这叫做Minimal, Complete, and Verifiable Example,你应该在提问时提供一个。如果提供了这个答案,这个答案可能在12小时前创建。
进一步调查,我问锈编译器打印出来的连接ARGS它要使用:
cargo rustc -- -Z print-link-args
此打印出来了一堆东西,但两个重要的线是
"-Wl,-rpath,$ORIGIN/../../../../root/.multirust/toolchains/stable-2016-11-08-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib"
"-Wl,-rpath,/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib"
这些是指令链接器将特定值添加到完成的二进制文件的路径。缺少的是对我们链接到的动态库的任何引用。回想起来,这可能是有道理的,因为编译器如何知道我们想将它包含在rpath中?
一个解决办法是另一个指令添加到链接器。有有趣的选项(如$ORIGIN
),但为了简单起见,我们将只使用绝对路径:
cargo rustc -- -C link-args="-Wl,-rpath,/scratch/library/"
产生的二进制打印正确的事情ldd
和运行,而无需设置LD_LIBRARY_PATH
:
$ ldd target/debug/executable | grep awesome
libawesome_math.so => /scratch/library/libawesome_math.so (0x00007fe859085000)
$ ./target/debug/executable
Adding: 3
谈到使得它相对的,我们可以用$ORIGIN
:
cargo rustc -- -C link-args='-Wl,-rpath,$ORIGIN/../../../library/'
要小心为您的shell正确转义$ORIGIN
,并且请记住该路径是相对于可执行文件而不是当前工作目录。
是否将路径添加到'/ etc/ld.so.conf'并运行'ldconfig'不适合你? (或者失败了,设置'LD_LIBRARY_PATH'环境变量?) – BurntSushi5
*是否有办法让Rust查找.so文件* - 这不是关于Rust创建二进制文件后的情况;这取决于操作系统和可执行的加载器。设置'rpath' *是Rust可以控制的东西(更准确地说,Rust指示链接器处理)。 – Shepmaster
*有没有办法让Rust至少插入与它链接的库的绝对路径* - 这就是rpath应该是的。你可以尝试[打印可执行文件的路径](http://stackoverflow.com/a/6348364/155423)?您可能还想尝试“货物清洁”和“货物构建 - 动词”。然后查看链接可执行文件时是否传递了'rpath'选项。 – Shepmaster