-
-
Notifications
You must be signed in to change notification settings - Fork 333
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
thread 'main' panicked at 'Wayland backend failed' #658
Comments
usually |
xwayland support is enabled in my sway session can it be related to it? $ echo $WAYLAND_DISPLAY
wayland-1
$ echo $DISPLAY
:0 |
well, if you have xwayland anyway - you can just use LinuxBackend::X11 :) still a bug tho! |
tried using all of the backends available to linux and none of them works. it seems pretty hard to find out how and why this happens but it seems to not detect X11 or wayland libraries so i would say it may be related to how wayland/X11 is packaged. this is how wayland library is configured and i dont see any problem so i presume it may be related to the wayland bindings used in miniquad meson \
--prefix=/usr \
-Ddefault_library=both \
-Dtests=false \
-Ddocumentation=false \
-Ddtd_validation=false \
. build it may also be because of musl libc so i recommend testing macroquad in a Void musl environment
logs:
X11Only backend backtrace:
|
i will test this code and see if it is related to it: https://github.com/not-fl3/miniquad/blob/aa38a5bfc01350dd6e6132d44372189f14ba5dd9/src/native/module.rs#L22C35-L22C35 |
yep it seems to be caused by dlopen() by libc crate. i will try doing this with dlopen crate and see the results code: #[derive(Debug)]
enum Error {
DlOpenError,
}
use libc::{dlopen, RTLD_LAZY, RTLD_LOCAL};
use std::{
ffi::{c_void, CString},
ptr::NonNull,
};
fn load(path: &str) -> Result<NonNull<c_void>, Error> {
let path = CString::new(path).unwrap();
let module = unsafe { dlopen(path.as_ptr(), RTLD_LAZY | RTLD_LOCAL) };
if module.is_null() {
Err(Error::DlOpenError)
} else {
Ok(unsafe { NonNull::new_unchecked(module) })
}
}
fn main() {
if let Err(err) = load("/usr/lib/libwayland-egl.so") {
eprintln!("{err:?}");
};
} result: $ cargo run
Compiling tests v0.1.0 (/home/xdream8/files/proj/tests)
Finished dev [unoptimized + debuginfo] target(s) in 0.17s
Running `target/debug/tests`
DlOpenError |
Library::open() from dlopen crate does not work too(as it seems to use dlopen() method from libc crate too). now i am 99.9% sure that this is a problem with libc crate(more likely lack of support for musl libc) |
I do not know enough about musl to comment, but does it support dynamic loading? Quick google give me this, which is a bit suspicious: https://git.musl-libc.org/cgit/musl/tree/src/ldso/dlopen.c |
ok, it was in dlink.c and according to documentation - musl can dlopen just fine. The only thing we should change to make it happen - use musl's dlopen. |
i will try testing this code in a Void musl vm and see if it gives the same error code: use std::{
ffi::{c_void, c_char, CString, CStr},
ptr::NonNull,
};
extern "C" {
fn dlopen(filename: *const c_char, flag: i32) -> *mut c_void;
fn dlerror() -> *mut c_char;
}
fn load(path: &str) -> Result<NonNull<c_void>, String> {
let path = CString::new(path).unwrap();
let module = unsafe { dlopen(path.as_ptr(), 1 | 0) };
if module.is_null() {
let error = unsafe {
let error_ptr = dlerror();
if error_ptr.is_null() {
"Unknown Error"
} else {
CStr::from_ptr(error_ptr).to_str().unwrap()
}
};
Err(error.to_owned())
} else {
Ok(unsafe { NonNull::new_unchecked(module) })
}
}
fn main() {
if let Err(err) = load("/usr/lib/libwayland-egl.so") {
eprintln!("{err}");
};
} log: $ cargo run
Compiling tests v0.1.0 (/home/xdream8/files/proj/tests)
Finished dev [unoptimized + debuginfo] target(s) in 0.20s
Running `target/debug/tests`
Dynamic loading not supported |
Hmm, I found this: https://github.com/helix-editor/helix/pull/4818/files#diff-9a4f3e4537ebb7474452d131b0d969d89a51286f4269aac5ef268e712be17268R5 modifying .cargo/config.toml is not a perfect solution, but does it works? |
quick test to check if their solution works:
|
yep that indeed fixes this. i dont get any error |
wow! |
that would be good |
feel free to open a PR! I don't have a musl-based setup to test it out :( |
Also I believe for the library it should be done through build.rs, not .cargo. But without a musl environment I can't really test it, so can't really tell how exactly it should look like. |
tried this for macroquad: build.rs: fn main() {
let target = std::env::var("TARGET").unwrap();
if target.contains("musl") {
println!("cargo:rustc-link-lib=dylib=m");
println!("cargo:rustc-link-lib=dylib=c");
println!("cargo:rustc-cfg=feature=\"crt-static\"");
println!("cargo:rustc-env=RUSTFLAGS=-crt-static");
}
} in a test project: macroquad = { path="./macroquad" } but when i tried using it in a project i got the 'Wayland backend failed' error again. then i tried doing the same for miniquad too build.rs: use std::env;
fn main() {
let target = env::var("TARGET").unwrap_or_else(|e| panic!("{}", e));
if target.contains("darwin") || target.contains("ios") {
println!("cargo:rustc-link-lib=framework=MetalKit");
} else if target.contains("musl") {
println!("cargo:rustc-link-lib=dylib=m");
println!("cargo:rustc-link-lib=dylib=c");
println!("cargo:rustc-cfg=feature=\"crt-static\"");
println!("cargo:rustc-env=RUSTFLAGS=-crt-static");
}
} modified a line in Cargo.toml for macroquad:
but then again got the same error: $ cargo run
Compiling miniquad v0.4.0-alpha.10 (/home/xdream8/files/proj/game-test/miniquad)
Compiling macroquad v0.4.4 (/home/xdream8/files/proj/game-test/macroquad)
Compiling game-test v0.1.0 (/home/xdream8/files/proj/game-test)
Finished dev [unoptimized + debuginfo] target(s) in 1.93s
Running `target/debug/game-test`
thread 'main' panicked at 'Wayland backend failed', /home/xdream8/files/proj/game-test/miniquad/src/lib.rs:256:54
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace i also removed the dependency for libc for linux part code: #[cfg(any(target_os = "linux", target_os = "android"))]
pub mod linux {
use super::Error;
use std::{
ffi::{c_void, c_char, CString},
ptr::NonNull,
};
extern "C" {
fn dlopen(filename: *const c_char, flag: i32) -> *mut c_void;
fn dlclose(handle: *mut c_void) -> *mut c_void;
fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void;
}
pub struct Module(NonNull<c_void>);
impl Module {
pub fn load(path: &str) -> Result<Self, Error> {
let path = CString::new(path).unwrap();
let module = unsafe { dlopen(path.as_ptr(), 1 | 0) };
if module.is_null() {
Err(Error::DlOpenError)
} else {
Ok(Module(unsafe { NonNull::new_unchecked(module) }))
}
}
pub fn get_symbol<F: Sized>(&self, name: &str) -> Result<F, Error> {
let name = CString::new(name).unwrap();
let symbol = unsafe { dlsym(self.0.as_ptr(), name.as_ptr()) };
if symbol.is_null() {
return Err(Error::DlSymError);
}
Ok(unsafe { std::mem::transmute_copy::<_, F>(&symbol) })
}
}
impl Drop for Module {
fn drop(&mut self) {
unsafe { dlclose(self.0.as_ptr()) };
}
}
} then i tried adding it seems that all crates must be linked dynamically. so the best we can do is add a notice/warning to README and let developers handle this. i am open to any better ideas |
if you want i can create a pr for removing libc dependency for linux and android but it should probably be tested for android first as android uses the same code too |
distro: kiss linux(community maintained, uses a source based package manager and musl libc)
macroquad version: 0.4.4
rust version: 1.72.1(installed using rustup)
code:
backtrace:
The text was updated successfully, but these errors were encountered: