I am following the vulkano tutorial to open a window and create a surface with vulkano-win.
Most of the tutorial is dated which I've been able to work around so far, however I have not been able to find a solution.
Currently, I get the following error when I call let window = WindowBuilder::new().build_vk_surface(&events_loop, instance.clone())
error[E0599]: no method named build_vk_surface found for struct winit::window::WindowBuilder in the current scope
I have checked the library and the version of vulkano_win and it seems to properly extend WindowBuilder I will post the dependencies in my Cargo.toml below.
[dependencies]
vulkano = "0.19"
vulkano-shaders = "0.18"
winit = "0.23"
vulkano-win = "0.19"
image = "0.23"
P.S. - There is a legacy instance of this happening on a much older (2 yr ago) version of vulkano_win here. I suspect this has been fixed since I have checked the dependencies for the vulkano_win library and they use the newer and restructured versions of winit there:
https://github.com/vulkano-rs/vulkano/issues/943
I have checked the library and the version of vulkano_win and it seems to properly extend WindowBuilder I will post the dependencies in my Cargo.toml below.
In short, you are correct. The issue is that the VkSurfaceBuild trait, is implemented for winit 0.22's WindowBuilder and not winit 0.23's WindowBuilder.
So to fix your issue, you need to update your Cargo.toml to use winit 0.22 instead of 0.23.
Example:
[dependencies]
vulkano = "0.19"
vulkano-shaders = "0.19"
vulkano-win = "0.19"
winit = "0.22"
Additionally, your confusion might come from browsing the repository.
In the repository both vulkano-win and the examples uses winit 0.23.
However, remember that the current state of the repository is not necessarily the same as what was released in 0.19.
On GitHub you can select tags, and view the commit that was the 0.19 release.
If you then look at vulkano-win and the examples, you'll see that they all use winit 0.22.
If you really want to use winit 0.23. Then you could depend directly on the repository. Like this:
[dependencies]
vulkano = { git = "https://github.com/vulkano-rs/vulkano" }
vulkano-win = { git = "https://github.com/vulkano-rs/vulkano" }
vulkano-shaders = { git = "https://github.com/vulkano-rs/vulkano" }
winit = "0.23"
However, one breaking change to the repository, could potentially ruin your build. So use with caution.
How were able to determine how that trait was implemented over the 0.22 WindowBuilder but not the 0.23 WindowBuilder?
Unsure if there's a fancy way of doing it, but an easy way is to just go to VkSurfaceBuild on docs.rs, then at "Implementations on Foreign Types" if you click on WindowBuilder, then it redirects to winit 0.22.2 docs.
Alternatively, you can also check your Cargo.lock. If you attempt to use winit 0.23, then your Cargo.lock would contain two winit versions:
[[package]]
name = "winit"
version = "0.22.2"
...
[[package]]
name = "winit"
version = "0.23.0"
...
If you then peek at vulkano-win then you can see it uses winit 0.22.2:
[[package]]
name = "vulkano-win"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b9a02addddf5532396d11dbb822f77d87ca17a00c918e4c8a0a125d6c207e2b"
dependencies = [
"cocoa 0.20.2",
"metal",
"objc",
"vulkano",
"winit 0.22.2",
]
If there's no duplicate versions, it would just say "winit" like the others.
Related
How do I enable crate features per-platform in a Cargo.toml configuration? I've tried two methods, neither of which work.
Method 1:
[target.'cfg(windows)'.dependencies.rusqlite]
version = "0.19.0"
features = ["bundled"]
[target.'cfg(unix)'.dependencies.rusqlite] # same behavior with cfg(not(windows))
version = "0.19.0"
Method 2:
[target.'cfg(windows)'.dependencies]
rusqlite = { version = "0.19.0", features = ["bundled"] }
[target.'cfg(unix)'.dependencies]
rusqlite = { version = "0.19.0" }
I'm trying to use the 'bundled' feature only on Windows platforms, but regardless of which way I try to configure cargo it always adds the 'bundled' feature when building on an Ubuntu system.
Is it possible to enable features only on one platform?
Is it possible to enable features only on one platform?
No, it is not possible, due to Cargo issue #1197.
See also:
How can I optionally pass rustc flags depending on a Cargo feature?
This question has a trash repo with minimum reproducible code.
How to reproduce
I have created the project like this:
cargo new foo --bin
cd foo
cargo new bar --bin
Then, I have updated Cargo.toml as below:
[package]
name = "foo"
version = "0.1.0" # notice the version
edition = "2018"
[dependencies]
[workspace]
members = ["bar"]
And then, I have updated bar/Cargo.toml seen as below:
[package]
name = "bar"
version = "0.2.0" # notice the version
edition = "2018"
[dependencies]
foo = { path = ".." }
Notice the versions of both Cargo.toml.
Then, I have created a function in src/lib.rs like this:
pub fn get_version<'a>() -> &'a str {
env!("CARGO_PKG_VERSION")
}
Then, in bar/src/main.rs, I used it as below:
use foo::get_version;
fn main() {
println!("{}", get_version());
}
Then I run cargo run -p bar.
The Problem
I will possibly have multiple workspace members that will use foo::get_version. I expect them to print out their own versions. In this example, foo is 0.1.0 and bar is 0.2.0.
So, I want the main function of bar to print out 0.2.0, yet it prints out 0.1.0, which is expected because env! macro takes environment variable and directly passes it into final binary. When I compile, it compiles foo::get_version, which is inside foo and CARGO_PKG_VERSION is 0.1.0 on compile time.
However, this is not the behavior I desire. I desire it to get the version of the crate that get_version is used and I want to keep it in foo because, again, I'd like to reuse it again and again on possible different workspace members.
Hence the question, how do I get the version of workspace member using a method from the parent member?
Environment
rustc 1.55.0
This cannot possibly work. Functions cannot be generic over their calling contexts.
You can get some info regarding who called the function at run-time by using #[track_caller]. However, that doesn't help that the information you want can only be retrieved in the context of the individual crates at compile-time anyway.
Your only recourse is to use a macro:
macro_rules! get_version {
() => {
env!("CARGO_PKG_VERSION")
}
}
With a macro, code is generated at the call-site, which means that, if called in one of the "child" crates, env!("CARGO_PKG_VERSION") will retrieve the "child" crate's version. You can of course write more code in the macro if the goal of the original function was intended to encompass more logic into the "parent" crate. But that's the only way to get access to crate-specific info like this.
I'm currently trying to learn Rust (for embedded specifically), coming from a background of C for embedded systems and Python.
So far, I've been reading Rust Programming Language and Rust for Embedded, and read a few blog posts on the web.
I want my first project to be a simple "Blinky", where an LED blinks infinitely. I've got an STM32L152CDISCOVERY board with an STM32L152 chip in it (basically same as STM32L151), which is a Cortex M3.
Instead of implementing everything from scratch, I want to leverage existing crates and HALs. I've found two that seem promising: stm32l1 and stm32l1xx-hal. I've tried to read the documentation of each of them and also part of the source code, but I still can't figure out how to use them correctly.
Got a few questions about Rust and about the crates:
I see that stm32l1xx-hal has a dependency on stm32l1. Do I need to add both as a dependency in my Cargo.toml file? Or will that create problems related to ownership?
Is this the correct way to add them? Why is the second one added like that [dependencies.stm32l1]?
[dependencies]
cortex-m-rt = "0.6.10"
cortex-m-semihosting = "0.3.3"
panic-halt = "0.2.0"
stm32l1xx-hal = "0.1.0"
[dependencies.stm32l1]
version = "0.13.0"
features = ["stm32l151", "rt"]
To blink the LD4 (which is connected to PB4 PB6), I've got to enable the GPIOB in the RCC register and then configure the pin to push pull output. By inspecting the documentation of stm32l1xx-hal, I see that there is an RCC struct and a PB4 struct with the method into_push_pull_output. However, I still don't understand how to use these structs: how to import them or how to get an instance of them.
I've seen code examples for stm32l1 but not for stm32l1xx-hal. I know that I can do this:
use stm32l1::{stm32l151};
...
let p = stm32l151::Peripherals::take().unwrap();
p.RCC.ahbenr.modify(|_,w| w.gpiopben().set_bit());
But in the source code of stm32l1xx-hal I see that the RCC part is already done in impl GpioExt for $GPIOX, but I don't know how to get to this "Parts" functionality.
Any help that points me in the right direction is appreciated.
I got some help from a Discord community. The answers were (modified a bit by me):
stm32l1xx-hal already depends on stm32l1 as seen here. There's no need to import it twice. It is enough to add to Cargo.toml:
[dependencies.stm32l1xx-hal]
version = "0.1.0"
default-features = false
features = ["stm32l151", "rt"]
Note that the default-features = false is optional, but without it the compiler was giving me an error.
The syntaxes are equivalent, but as I said above, I only need to add the HAL one. You can add curly braces {} in the first style to add the options, such as:
stm32l1xx-hal = { version = "0.1.0", features = ["stm32l151", "rt"]}
The right code for doing the blinky (which was on PB6, not PB4, sigh) was:
#![no_main]
#![no_std]
use panic_halt as _;
use cortex_m_rt::entry;
use stm32l1xx_hal::delay::Delay;
use stm32l1xx_hal::gpio::GpioExt;
use stm32l1xx_hal::hal::digital::v2::OutputPin;
use stm32l1xx_hal::rcc::{Config, RccExt};
use stm32l1xx_hal::stm32::Peripherals;
use stm32l1xx_hal::stm32::CorePeripherals;
use stm32l1xx_hal::time::MicroSeconds;
#[entry]
fn main() -> ! {
let p = Peripherals::take().unwrap();
let cp = CorePeripherals::take().unwrap();
// Get LED pin PB6
let gpiob = p.GPIOB.split();
let mut led = gpiob.pb6.into_push_pull_output();
// Set up a delay
let rcc = p.RCC.freeze(Config::default());
let mut delay = Delay::new(cp.SYST, rcc.clocks);
loop {
// Turn LED On
led.set_high().unwrap();
delay.delay(MicroSeconds(1_000_000_u32));
// Turn LED Off
led.set_low().unwrap();
delay.delay(MicroSeconds(1_000_000_u32));
}
}
For me, the key was to understand that the split method can be called from the Peripherals because stm32l1xx-hal implemented split for a struct defined in stm32l1. In other words, the HAL crate is not only defining new structs, but also extending functionality for existing structs. I need to wrap my head around trait design patterns.
I try to build the single_mem_node example, but as a standalone example and use the raft-rs crate as a library.
But unfortunately, I get this build error, when building using cargo build
error[E0599]: no method named `is_empty` found for reference `&raft_proto::protos::eraftpb::Snapshot` in the current scope
--> src/main.rs:123:26
|
123 | if !ready.snapshot().is_empty() {
| ^^^^^^^^ method not found in `&raft_proto::protos::eraftpb::Snapshot`
I have declared these dependencies in my Cargo.toml
[dependencies]
protobuf = { version = "2", features = ["with-bytes"] }
raft = "0.6.0-alpha"
slog = "2.5.2"
slog-term = "2.6.0"
slog-async = "2.5.0"
The instructions on how to use the raft-rs crate is:
You can use raft with either rust-protobuf or Prost to encode/decode gRPC messages. We use rust-protobuf by default. To use Prost, build (or depend on) Raft using the prost-codec feature and without default features.
It certainly looks like I miss something around the protobuf... but what? and how do I find out about it?
It looks like the method was added in this commit, after version 0.6.0-alpha was released. GitHub shows the master branch by default, so in the future, try browsing at the commit that corresponds to the version you are using. In this case it is not tagged properly but I think this commit is the published 0.6.0-alpha version. In the example at that commit, the corresponding line is:
if !raft::is_empty_snap(ready.snapshot()) {
Alternatively, since it seems that 0.6.0-alpha was released in July of 2019, if you want the latest changes on master, you could change the dependency in Cargo.toml to read:
raft = { git = "https://github.com/tikv/raft-rs" }
In that case, cargo will fetch the latest commit and store its hash in Cargo.lock, and you can update to a newer commit with cargo update.
I'm trying to use rand::SmallRng. The documentation says
This PRNG is feature-gated: to use, you must enable the crate feature small_rng.
I've been searching and can't figure out how to enable "crate features". The phrase isn't even used anywhere in the Rust docs. This is the best I could come up with:
[features]
default = ["small_rng"]
But I get:
Feature default includes small_rng which is neither a dependency nor another feature
Are the docs wrong, or is there something I'm missing?
Specify the dependencies in Cargo.toml like so:
[dependencies]
rand = { version = "0.7.2", features = ["small_rng"] }
Alternatively:
[dependencies.rand]
version = "0.7.2"
features = ["small_rng"]
Both work.