"No backend is available" error with examples
I am trying to build and run an example from piston.rs, here is the code fore reference:
extern crate piston_window;
use piston_window::*;
fn main() {
let mut window: PistonWindow =
WindowSettings::new("Hello Piston!", [640, 480])
.exit_on_esc(true).build().unwrap();
while let Some(e) = window.next() {
window.draw_2d(&e, |c, g| {
clear([1.0; 4], g);
rectangle([1.0, 0.0, 0.0, 1.0], // red
[0.0, 0.0, 100.0, 100.0],
c.transform, g);
});
}
}
but get error:
Running `target/debug/example`
thread 'main' panicked at 'No backend is available', /home/user/.local/share/cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.12.0/src/platform/linux/mod.rs:356:9
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::print
at libstd/sys_common/backtrace.rs:71
at libstd/sys_common/backtrace.rs:59
2: std::panicking::default_hook::{{closure}}
at libstd/panicking.rs:211
3: std::panicking::default_hook
at libstd/panicking.rs:227
4: std::panicking::rust_panic_with_hook
at libstd/panicking.rs:475
5: std::panicking::begin_panic
at /checkout/src/libstd/panicking.rs:409
6: winit::platform::platform::EventsLoop::new
at /home/user/.local/share/cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.12.0/src/platform/linux/mod.rs:356
7: winit::EventsLoop::new
at /home/user/.local/share/cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.12.0/src/lib.rs:195
8: glutin_window::GlutinWindow::new
at /home/user/.local/share/cargo/registry/src/github.com-1ecc6299db9ec823/pistoncore-glutin_window-0.47.0/src/lib.rs:102
9: <glutin_window::GlutinWindow as window::BuildFromWindowSettings>::build_from_window_settings
at /home/user/.local/share/cargo/registry/src/github.com-1ecc6299db9ec823/pistoncore-glutin_window-0.47.0/src/lib.rs:449
10: window::WindowSettings::build
at /home/user/.local/share/cargo/registry/src/github.com-1ecc6299db9ec823/pistoncore-window-0.32.0/src/lib.rs:392
11: <piston_window::PistonWindow<W> as window::BuildFromWindowSettings>::build_from_window_settings
at /home/user/.local/share/cargo/registry/src/github.com-1ecc6299db9ec823/piston_window-0.80.0/src/lib.rs:152
12: window::WindowSettings::build
at /home/user/.local/share/cargo/registry/src/github.com-1ecc6299db9ec823/pistoncore-window-0.32.0/src/lib.rs:392
13: example::main
at src/main.rs:96
14: std::rt::lang_start::{{closure}}
at /checkout/src/libstd/rt.rs:74
15: std::panicking::try::do_call
at libstd/rt.rs:59
at libstd/panicking.rs:310
16: __rust_maybe_catch_panic
at libpanic_unwind/lib.rs:106
17: std::rt::lang_start_internal
at libstd/panicking.rs:289
at libstd/panic.rs:392
at libstd/rt.rs:58
18: std::rt::lang_start
at /checkout/src/libstd/rt.rs:74
19: main
20: __libc_start_main
21: _start
at ../sysdeps/x86_64/start.S:120
I am running NixOS, so problem may be with dynamically loading libraries. Is there a way to find out which libs do I need?
As far as I can understand the problem is in XConnection::new function:
pub fn new(error_handler: XErrorHandler) -> Result<XConnection, XNotSupported> {
// opening the libraries
let xlib = try!(ffi::Xlib::open());
let xcursor = try!(ffi::Xcursor::open());
let xrandr = try!(ffi::Xrandr_2_2_0::open());
let xrandr_1_5 = ffi::Xrandr::open().ok();
let xinput2 = try!(ffi::XInput2::open());
let xlib_xcb = try!(ffi::Xlib_xcb::open());
unsafe { (xlib.XInitThreads)() };
unsafe { (xlib.XSetErrorHandler)(error_handler) };
// calling XOpenDisplay
let display = unsafe {
let display = (xlib.XOpenDisplay)(ptr::null());
if display.is_null() {
return Err(XNotSupported::XOpenDisplayFailed);
}
display
};
Ok(XConnection {
xlib: xlib,
xrandr: xrandr,
xrandr_1_5: xrandr_1_5,
xcursor: xcursor,
xinput2: xinput2,
xlib_xcb: xlib_xcb,
display: display,
latest_error: Mutex::new(None),
})
}
I've tried to explicitly "install" all mentioned libs via nix-shell -p "[x11 gcc] ++ (with xorg; [libXcursor xrandr xinput libxcb])", but got the same error as above.
The source of the issue is glutin. More details available in this closed issue.
I fixed the issue myself by building a simple nix package in the root of the cargo directory:
let
nixpkgs = import <nixpkgs> {};
inherit (nixpkgs) mesa libGL patchelf rustPlatform wayland xorg;
inherit (xorg) libX11 libXcursor libXi libXxf86vm;
in
rustPlatform.buildRustPackage rec {
pname = "spinning-square";
version = "0.1.0";
src = ./.;
cargoSha256 = "...";
buildInputs = [ patchelf ];
fixupPhase = ''
patchelf --set-rpath ${libGL}/lib:${mesa}/lib:${wayland}/lib:${libX11}/lib:${libXi}/lib:${libXcursor}/lib:${libXxf86vm}/lib \
$out/bin/spinning-square
'';
}
The most important part here is the patchelf call where we modify the ELF binaries rpath to contain valid directions to all the listed directories. This should allow it run in both wayland and xorg on NixOS.
This can probably be marked as solved now. If the maintainer wishes to document this somewhere please do. Maybe even just a link to this issue in the readme so people on NixOS don't get stuck and quit trying.
Found this issue after going through the same struggle with backend errors, and I am also on NixOS. For others that find this, the package above is a good solution!
However. somewhere between now and then. glutin now requires libXrandr, but that's just easily extending the patchelf command to include it.
Here's my entire flake if anyone wants it.
{
description = "Basic Rust environment with toolchain and language server";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { nixpkgs, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem
(system:
let
pkgs = nixpkgs.legacyPackages.${system};
inherit (pkgs) mkShell rust mesa libGL patchelf rustPlatform wayland xorg;
inherit (xorg) libX11 libXcursor libXi libXxf86vm libXrandr;
pname = "simple-game";
version = "0.1.0";
nvimrc = ''local servers = { "rust_analyzer" }
local caps = require("cmp_nvim_lsp").default_capabilities(vim.lsp.protocol.make_client_capabilities());
for _, lsp in ipairs(servers) do
require("lspconfig")[lsp].setup {capabilities = caps}
end
vim.cmd("LspStart");'';
in
rec
{
# Executed by `nix build`
packages.default = rustPlatform.buildRustPackage {
inherit pname version;
src = ./.;
cargoLock.lockFile = ./Cargo.lock;
buildInputs = [ patchelf ];
fixupPhase = ''
patchelf --set-rpath ${libGL}/lib:${mesa}/lib:${wayland}/lib:${libX11}/lib:${libXi}/lib:${libXcursor}/lib:${libXxf86vm}/lib:${libXrandr}/lib \
$out/bin/${pname}
'';
};
# Executed by `nix run`
apps.default = flake-utils.lib.mkApp { drv = packages.default; };
# Used by `nix develop`
devShells.default = mkShell {
buildInputs = with pkgs; [
cargo
rustc
clippy
rustfmt
rust-analyzer
pkg-config
];
RUST_SRC_PATH = "${rust.packages.stable.rustPlatform.rustLibSrc}";
shellHook = ''echo '${nvimrc}' > .nvimrc.lua'';
};
}
);
}