dynamic resolutions docs
Some checks failed
Book / test (pull_request) Has been cancelled
Rust / build (pull_request) Has been cancelled

This commit is contained in:
Jaroslaw Konik 2025-05-27 18:58:02 +02:00
parent f404ee91f2
commit e22236f201
4 changed files with 45 additions and 0 deletions

View file

@ -34,6 +34,7 @@ mlua = { version = "0.9.8", features = [
magnus = { version = "0.7.1", optional = true }
rb-sys = { version = "*", default-features = false, features = ["link-ruby", "ruby-static"], optional = true }
crossbeam-channel = "0.5.15"
libc = "0.2.172"
[[example]]
name = "call_function_from_rust_rhai"

View file

@ -38,3 +38,13 @@ bevy_scriptum = { version = "0.8", features = ["ruby"] }
If you need a different version of bevy you need to use a matching bevy_scriptum
version according to the [bevy support matrix](../bevy_support_matrix.md)
Ruby also needs dynamic symbol resolution and since `bevy_scriptum` links Ruby
statically the following `build.rs` file is needed to be present in project
root directory.
```rust
fn main() {
println!("cargo:rustc-link-arg=-rdynamic");
}
```

View file

@ -371,6 +371,10 @@ pub trait Runtime: Resource + Default {
context: &Self::CallContext,
args: Vec<Self::Value>,
) -> Result<Self::Value, ScriptingError>;
fn needs_rdynamic_linking() -> bool {
false
}
}
pub trait FuncArgs<'a, V, R: Runtime> {
@ -433,6 +437,19 @@ impl BuildScriptingRuntime for App {
/// Adds a scripting runtime. Registers required bevy systems that take
/// care of processing and running the scripts.
fn add_scripting<R: Runtime>(&mut self, f: impl Fn(ScriptingRuntimeBuilder<R>)) -> &mut Self {
#[cfg(debug_assertions)]
if R::needs_rdynamic_linking() {
if !is_rdynamic_linking() {
panic!(
"Missing `-rdynamic`: symbol resolution failed.\n\
It is needed by {:?}.\n\
Please add `println!(\"cargo:rustc-link-arg=-rdynamic\");` to your build.rs\n\
or set `RUSTFLAGS=\"-C link-arg=-rdynamic\"`.",
std::any::type_name::<R>()
);
}
}
self.world_mut()
.resource_mut::<MainScheduleOrder>()
.insert_after(Update, R::Schedule::default());
@ -495,6 +512,19 @@ impl<R: Runtime> Default for Callbacks<R> {
}
}
pub extern "C" fn is_rdynamic_linking() -> bool {
unsafe {
// Get a function pointer to itself
let addr = is_rdynamic_linking as *const libc::c_void;
let mut info: libc::Dl_info = std::mem::zeroed();
// Try to resolve symbol info
let result = libc::dladdr(addr, &mut info);
result != 0 && !info.dli_sname.is_null()
}
}
pub mod prelude {
pub use crate::{BuildScriptingRuntime as _, Runtime as _, Script};
}

View file

@ -505,6 +505,10 @@ impl Runtime for RubyRuntime {
Ok(RubyValue::new(result))
})
}
fn needs_rdynamic_linking() -> bool {
true
}
}
pub mod magnus {