tomaka / redshirt

🧑‍🔬 Operating system
GNU General Public License v3.0
1.42k stars 37 forks source link

Experiment with imgui-rs for the UI #438

Open tomaka opened 4 years ago

tomaka commented 4 years ago

cc #194

Getting any real UI framework to work on redshirt would require either support for hardware acceleration, or a software implementation of OpenGL or WebGPU. Both these solutions are quite inaccessible at the moment.

As a way to get started with a desktop environment, a possibility could be to use imgui-rs.

It should be easy (for a certain definition of "easy") to write a software renderer for imgui. I've also checked, and the C++ code of imgui compiles just fine for wasi provided you pass the Wasi libc with CXXFLAGS_wasm32_wasi="--sysroot=/path/to/wasi-libc/sysroot" cargo b --target=wasm32-wasi

tomaka commented 4 years ago

Imgui turned out to be more complicated to compile than I thought.

The following works:

CXX_wasm32_wasi=/path/to/wasi-sdk-10.0/bin/clang++ CXXFLAGS_wasm32_wasi="--sysroot=/path/to/wasi-sdk-10.0/share/wasi-sysroot" CARGO_TARGET_WASM32_WASI_LINKER=/path/to/wasi-sdk-10.0/bin/lld CXXSTDLIB_wasm32_wasi=c++ RUSTFLAGS="-Clink-arg=-L/path/to/wasi-sdk-10.0/share/wasi-sysroot/lib/wasm32-wasi" cargo run --target=wasm32-wasi

(off-topic: it is quite frustrating to not be able to put these C++ flags in some configuration file and instead having to pass them every single time)

Unfortunately I'm getting linking errors about function signature mismatches between the Rust bindings and the actual implementations. It seems that Rust thinks that ImVec2 must be passed by pointer, while the C++ code wants to pass the two fields individually.

tomaka commented 4 years ago

It seems that the bindings in the imgui crate are wrong-ish.

When I do the following:

diff --git a/imgui-sys-bindgen/src/lib.rs b/imgui-sys-bindgen/src/lib.rs
index 7f74258..4033e72 100644
--- a/imgui-sys-bindgen/src/lib.rs
+++ b/imgui-sys-bindgen/src/lib.rs
@@ -89,6 +89,8 @@ pub fn generate_bindings<P: AsRef<Path>>(cimgui_path: &P) -> Result<Bindings, Er
         .raw_line("#![allow(non_camel_case_types)]")
         .raw_line("#![allow(non_snake_case)]")
         .raw_line("#![allow(clippy::all)]")
+        .clang_arg("--target=wasm32-wasi")
+        .clang_arg("--sysroot=/home/pierre/Projets/wasi-sdk-10.0/share/wasi-sysroot")
         .header_contents("cimgui.h", &header)
         .rust_target(RustTarget::Stable_1_36)
         .default_enum_style(EnumVariation::Consts)

Then the sizes of all structs are different. Also some structs are missing (?!?!) and all the exports are missing from the bindings too.

Issues with C/C++ compilers are tiring.

tomaka commented 4 years ago

cc https://github.com/rust-lang/rust-bindgen/issues/751

The following diff leads to bindings being generated:

diff --git a/imgui-sys-bindgen/src/lib.rs b/imgui-sys-bindgen/src/lib.rs
index 7f74258..68e727f 100644
--- a/imgui-sys-bindgen/src/lib.rs
+++ b/imgui-sys-bindgen/src/lib.rs
@@ -89,6 +89,9 @@ pub fn generate_bindings<P: AsRef<Path>>(cimgui_path: &P) -> Result<Bindings, Er
         .raw_line("#![allow(non_camel_case_types)]")
         .raw_line("#![allow(non_snake_case)]")
         .raw_line("#![allow(clippy::all)]")
+        .clang_arg("--target=wasm32-wasi")
+        .clang_arg("--sysroot=/home/pierre/Projets/wasi-sdk-10.0/share/wasi-sysroot")
+        .clang_arg("-fvisibility=default")
         .header_contents("cimgui.h", &header)
         .rust_target(RustTarget::Stable_1_36)
         .default_enum_style(EnumVariation::Consts)

Unfortunately I'm still getting linking errors.

tomaka commented 4 years ago

The linking errors were caused by https://github.com/rust-lang/rust/issues/71871 Bypassed the issue in my fork: https://github.com/tomaka/imgui-rs/tree/wasi

Compiles with:

AR_wasm32_wasi=/home/pierre/Projets/wasi-sdk-10.0/bin/ar CXX_wasm32_wasi=/home/pierre/Projets/wasi-sdk-10.0/bin/clang++ CXXFLAGS_wasm32_wasi="--sysroot=/home/pierre/Projets/wasi-sdk-10.0/share/wasi-sysroot" CARGO_TARGET_WASM32_WASI_LINKER=/home/pierre/Projets/wasi-sdk-10.0/bin/lld CXXSTDLIB_wasm32_wasi=c++ CARGO_TARGET_WASM32_WASI_RUSTFLAGS="-Clink-arg=-L/home/pierre/Projets/wasi-sdk-10.0/share/wasi-sysroot/lib/wasm32-wasi" cargo run --target=wasm32-wasi

tomaka commented 4 years ago

Need to pass -fno-threadsafe-statics in the C++ flags as well, otherwise I get linking errors when trying to actually invoke an imgui function.