我的最终目标是使用 WSL 中的 Pixels 在 Rust 中创建数据可视化。
但是,我无法运行 Pixels 示例,因此我首先要确保 Winit 可以正常运行。 从 GitHub 下载 Winit 存储库并运行
window
示例可以正常工作。
但是,如果我创建一个新项目并将示例代码复制粘贴到其中,那么运行代码将不再打开窗口。
从运行 gdb 开始,代码似乎陷入了
window.request_redraw()
,但我找不到更多其他内容。
我对窗口系统不是很了解,但是通过运行
echo $DISPLAY
和 echo $WAYLAND_DISPLAY
,我分别得到 :0
和 wayland-0
,我相信这表明 WSL 同时安装了 X11 和 Wayland 功能。
我正在使用
Ubuntu 22.04.3 LTS
。运行 cat /proc/version
打印 Linux version 5.15.90.1-microsoft-standard-WSL2 (oe-user@oe-host) (x86_64-msft-linux-gcc (GCC) 9.3.0, GNU ld (GNU Binutils) 2.34.0.20200220) #1 SMP Fri Jan 27 02:56:13 UTC 2023
。
我似乎对 Cargo 如何管理依赖项有一些误解,因为我不知道为什么当我指示 Cargo 下载相同版本的 Winit 源代码时,相同的代码会在 Winit 源代码项目中运行,但不会在我自己的项目中运行。我已经尝试过 Winit v0.29、v0.28 和 v0.27,但同样的问题仍然存在。
重现步骤:
git clone https://github.com/rust-windowing/winit.git
cd winit
cargo run --example window
窗口打开正常...
cd ..
cargo new window
cd window
cargo add winit
cargo add simple_logger
cp ../winit/examples/window.rs src/main.rs
mkdir src/util
cp ../winit/examples/util/fill.rs src/util
cargo run
窗户打不开...
解决了!
TL;DR 示例代码有一个功能标志,我没有在自己的项目中启用。
在毫无结果地调试
window.rs
中的主要示例代码之后,我解决了fill.rs
中的帮助程序代码。有一个函数 fill_window()
有两个签名:
#[cfg(all(feature = "rwh_05", not(any(target_os = "android", target_os = "ios"))))]
pub(super) fn fill_window(window: &Window) {
...
}
#[cfg(not(all(feature = "rwh_05", not(any(target_os = "android", target_os = "ios")))))]
pub(super) fn fill_window(_window: &Window) {
// No-op on mobile platforms.
}
第一个应该在启用
rwh_05
功能且 target_os
不是 android
或 ios
时运行。
否则,第二个应该运行。
我在每个中都放置了一个
println!()
,发现我的window
项目正在编译为第二个(无操作)函数,而源winit
项目正在编译为第一个函数。
因此
target_os == android
、target_os == ios
或 rwh_05
未启用。
我通过向
fill.rs
添加代码来运行一些测试
#[cfg(target_os = "android")]
compile_error!("target_os = android");
#[cfg(target_os = "ios")]
compile_error!("target_os = android");
#[cfg(target_os = "linux")]
compile_error!("target_os = linux");
输出显示
target_os
是 linux
。
error: target_os = linux
--> src/util/fill.rs:16:1
|
16 | compile_error!("target_os = linux");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: could not compile `window` (bin "window") due to previous error
接下来,
#[cfg(feature = "rwh_05")]
compile_error!("rwh_05 feature enabled");
#[cfg(not(feature = "rwh_05"))]
compile_error!("rwh_05 feature is not enabled");
输出显示
rwh_05
未启用⠀
error: rwh_05 feature is not enabled
--> src/util/fill.rs:16:1
|
16 | compile_error!("rwh_05 feature is not enabled");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: could not compile `window` (bin "window") due to previous error
这就是我得到启示的地方。
我错误地将以下内容放入
Cargo.toml
中,认为它会启用 rwh_05
全局,但实际上它只为 winit
板条箱启用该功能,而不是我自己的本地项目。
[dependencies]
winit = { path = "./winit", features = ["rwh_05"] }
添加
[features]
rwh_05 = []
到
Cargo.toml
并使用 cargo run --features rwh_05
运行按预期运行窗口示例: