我正在使用 crate
jni = { version = "0.20.0", features = ["invocation"] }
,并尝试设置一个可以运行 JNI 内容的测试。
我的启动代码如下
let jvm_args = InitArgsBuilder::new()
.version(JNIVersion::V8)
.option("-Xcheck:jni")
.build()
.unwrap();
let jvm = JavaVM::new(jvm_args).unwrap();
let _guard = jvm.attach_current_thread().unwrap();
let env = jvm.get_env().unwrap();
JavaClasses::init(&env);
我似乎无法在 Mac 上运行它,因为当 IDE
RustRover
启动二进制文件时,它总是在查找动态链接库时遇到问题,抱怨
Error: could not find libjava.dylib
Failed to GetJREPath()
尝试查找
rpath
名称,似乎没有返回
➜ blaze git:(tests) ✗ otool -l xxxlaze/target/debug/deps/blaze_tests-b310798913eec8e4 | ag -C 5 LC_RPATH
➜ blaze git:(tests) ✗
我确实尝试在 build.rs 中设置它们
println!("cargo:rustc-link-search=native={}", libjvm_path.display());
// println!("cargo:rustc-link-arg=-Wl,-rpath={}", libjvm_path.display());
println!("cargo:rustc-env=LD_LIBRARY_PATH={}", libjvm_path.display());
我发送了类似 JNI crate 的操作,使用
build.rs
构建脚本来定位 jvm 路径,如下所示(与 JNI crate 中的版本完全相同)
fn find_libjvm<S: AsRef<Path>>(path: S) -> Option<PathBuf> {
let walker = walkdir::WalkDir::new(path).follow_links(true);
for entry in walker {
let entry = match entry {
Ok(entry) => entry,
Err(_e) => continue,
};
let file_name = entry.file_name().to_str().unwrap_or("");
if file_name == EXPECTED_JVM_FILENAME {
return entry.path().parent().map(Into::into);
}
}
None
}
然后下面就是关键了,设置
rpath
,用来定位dylib。
println!("cargo:rustc-link-arg=-Wl,-rpath,{}", libjvm_path.display());
这使得测试运行。