Problem creating correct Cargo.toml for a leaning_gfx_hal project

I am working through the learning_gfx_hal project and running into what I perceive as namespace issues and how Cargo.toml can help or hinder. Admittedly I trying to bite off a lot at the moment

  1. I am through 2/3 of the Programming Rust by Blandy
  2. I am working on understanding gfx_hal with the learning gfx hal tutorial.
  3. Splitting out the types created in the tutorial into separate code for reuse.

The organization of my code is

Cargo.toml
src/gfx_types    // where I am defining types one per file:
src/gfx_types/hal_state.rs
src/gfx_types/winit_state.rs
src/gfx_type/mod.rs
src/main.rs
examples/build_windows.rs
examples/Cargo.toml

Top level Cargo.toml:

[package]
name = "learning_gfx_hal"
version = "0.1.0"

edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
default = []
metal = ["gfx-backend-metal"]
dx12 = ["gfx-backend-dx12"]

vulkan = ["gfx-backend-vulkan"]

#[workspace]
#members = [
#    "src/gfx_types",
#]


[dependencies]
winit = "0.22.2"
log = "0.4.8"
simple_logger = "1.6.0"
gfx-hal = "0.5.3"
arrayvec = "0.5.1"
bitflags = "1.2.1"
#gfx_types = {path = "src/gfx_types/"}


[dependencies.gfx-backend-vulkan]
version = "0.5.8"
optional =  true

[target.'cfg(target_os =  "macos")'.dependencies.gfx-backend-metal]
version = "0.4.0"
optional = true

[target.'cfg(target_os =  "windows")'.dependencies.gfx-backend-dx12]

src/gfx_types/Cargo.toml

[packlage]
name ="gfx_types"
version =  "0.1.0"
workspace = "../.."
edition = "2018"


[lib]
name = "gfx_types"
path = "mod.rs"

examples/Cargo.toml currently

[packlage]
name ="gfx_types"
version =  "0.1.0"
workspace = "../.."
edition = "2018"

src/gfx_types/mod.rs :

 pub mod winit_state;
pub mod hal_state;

main.rs finds the types in the mod gfx_types just fine but I don't have much luck with the code in examples seeing the gfx_types mod.

main.rs

 mod gfx_types;
fn main() {

     let winit_state = winit_state::WinitState::default();

}

examples/build_windows.rs :

mod gfx_types;
    use winit::event::Event;
    use winit::event::WindowEvent;
    use winit::event_loop::ControlFlow;
fn main() {


    use gfx_types::winit_state;
    let winit_state = winit_state::WinitState::default();

    let running = true;
    while running {
        winit_state.events_loop.run(move |event, _, control_flow| {
            *control_flow = ControlFlow::Poll;
            match event {
            Event::WindowEvent {
                event: WindowEvent::CloseRequested,
                ..
            } => {
                *control_flow =  ControlFlow::Exit
            },
            _ => (),
        }
        })
    }
}

Error mod gfx_types is not found. I have looked a numerous examples including gfx_hal/examples but I am not getting it. Most attempts are errors in the Example/Cargo.toml file.

I understand that the top level Cargo.toml is the root crate bu how do I bind gfx_types to the root crate namespace?
Sorry if my terminology is a little off but I am coming from other comp. languages.

Thanks,
Frank

You would never have a Cargo.toml inside the src/ directory. You would also not use workspaces. You need to split up your crate into a library and binary crate to access stuff from examples, which you can do by having both a lib.rs and a main.rs. Consider the following example:

// Cargo.toml
// no workspaces here
[package]
name = "learning_gfx_hal"
version = "0.1.0"
edition = "2018"

[dependencies]
...

These files make up your library crate:
The library crate is accessible from both the binary and from examples.

// src/lib.rs
pub mod gfx_types;
pub mod my_library_module;
// src/gfx_types/mod.rs
pub mod winit_state;
pub mod hal_state;
// src/gfx_types/winit_state.rs
your content here
// src/gfx_types/hal_state.rs
your content here
// src/my_library_module.rs
// importing from the same crate happens with crate::
use crate::gfx_types::winit_state::MyWinitType;

These files make up your binary crate:
The binary crate is not accessible from examples.

// src/main.rs
// importing from the library crate happens with learning_gfx_hal::
use learning_gfx_hal::gfx_types::winit_state::MyWinitType;

mod my_binary_only_module;
// importing from the same crate happens with crate::
use crate::my_binary_only_module::Stuff;

fn main() {
    ...
}
// src/my_binary_only_module.rs
// this file is not accessible from examples
...

These files make up your example:

// examples/windows_example.rs
use learning_gfx_hal::gfx_types::winit_state::MyWinitType;

use winit::event::Event;
use winit::event::WindowEvent;
use winit::event_loop::ControlFlow;

fn main() {
    ...
}

Any files accessible by following mod statements starting from lib.rs are part of the library crate. Files accessible by following mod statements starting from main.rs are only accessible in the binary crate.

You should never make a file accessible via mod statements from both main.rs and lib.rs. Instead, put the mod statement in the library crate and import it in the binary crate with a use statement.

Consider reading this: Clear explanation of Rust’s module system.

// the file system
learning_gfx_hal/
├── Cargo.toml
├─┬ examples/
│ └── windows_example.rs
└─┬ src/
  ├── main.rs
  ├── my_binary_only_module.rs
  ├── lib.rs
  ├── my_library_module.rs
  └─┬ gfx_types/
    ├── mod.rs
    ├── winit_state.rs
    └── hal_state.rs
// the module layout
learning_gfx_hal
├── my_library_module
└─┬ gfx_types
  ├── winit_state
  └── hal_state
binary
└── my_binary_only_module
windows_example
└─ (no children)

In this case, both binary and windows_example have a dependency on the learning_gfx_hal crate, but none on eachother.

Alice,
Thanks for the help. I had already read "Clear explanation of Rust's module system" and at first was using it as a working example. Along with it and your explanations I am still having problems binding the Project crate name to the namespace so it if visible in src/main.rs and in examples

use learning_gfx_hal::gfx_types::winit_state::MyWinitType;

Gives me "missing crate learning_gfx_hal

use crate::gfx_types::winit_state

give an error about gfx_types is missing.

I think there is something missing in the top level Cargo.toml I listed at the top. I did try uncommenting gfx_types as a dependcy but that errors with an error about getting gfx_types as a dependcy

Top level binding in namespaces in a project is still a bit a problem in my mind.
Any more ideas?

Thanks,
Frank

What’s your full Cargo.toml look like now? Also make sure you only have the one top level Cargo.toml in the directory tree. And can you show the full output from the run that’s generating the error including the command being run?

Hi,

I only have the top level Cargo.toml

[package]
name = "learning_gfx_hal"
version = "0.1.0"
authors = ["FrankieD <frank.deming@gmail.com>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
default = []
metal = ["gfx-backend-metal"]
dx12 = ["gfx-backend-dx12"]
vulkan = ["gfx-backend-vulkan"]

#[workspace]
#members = [
    #"src/gfx_types",
#]


[dependencies]
winit = "0.22.2"
log = "0.4.8"
simple_logger = "1.6.0"
gfx-hal = "0.5.3"
arrayvec = "0.5.1"
bitflags = "1.2.1"


[dependencies.gfx-backend-vulkan]
version = "0.5.8"
optional =  true

[target.'cfg(target_os =  "macos")'.dependencies.gfx-backend-metal]
version = "0.4.0"
optional = true

[target.'cfg(target_os =  "windows")'.dependencies.gfx-backend-dx12]
version = "0.1.3"
optional = true

Error after running rustc error[E0433]: failed to resolve: maybe a missing crate learning_gfx_hal?

 --> src/main.rs:2:9
  |
2 |     use learning_gfx_hal::gfx_types::winit_state;
  |         ^^^^^^^^^^^^^^^^ maybe a missing crate `learning_gfx_hal`?

Inside of vscode when I build with features "vulkan" gives an error of can't find crate for learning_gfx_hal.

Thanks,

Frank

Frank

Create a file src/lib.rs with this in it

pub mod gfx_types;

See if that works. If so I can explain more what’s going on.

Hi Drew,

I already had that created from the start.

I have now figured out what was fouling up the effort. Naive off me.

src/gfx_types/mod.rs contained

pub mod winit_state;
pub mod hal_state;

as it should. When I commented out the second line everything worked as expected. I thought that learning_gfx_hal::gfx_types/winit_state would get resolved because it got built. hal_state I am still porting to more recent dependency crates. As I am working it fails and therefor all of gfx_types fails to be completed so that gfx_types::winit_state can't be resolved either.

Sigh. I have not been programming for a number of years so new languages and build tools are a bit of mystery. I was among other things a consulting build engineer 20 years ago. Now retired and interested in engineering again.

What I plan with all of what I am working on:

  1. work through the learning_gfx_hal tutorial.
  2. Update the code as the original one does not build because of problems with dependent crates
  3. With the original authors permission update the tutorials.

It has been an interesting first experience over the last 4-5 months.

Thanks
Frank

Glad to hear you’ve sorted out this issue. Working through out of date tutorials while simultaneously learning a new language is definitely tricky. Hopefully it goes a bit smoother going forward.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.