Error E0432 when generating multiple binaries

Error[E0432]: unresolved imports `crate::messages::msgvolumeextras::ExtraParameters`, `crate::messages::msgvolumeextras::LLTextureParams`
  --> src/messages/msgconvertfull.rs:19:40
   |
19 | use crate::messages::msgvolumeextras::{ExtraParameters, LLTextureParams};
   |                                        ^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^ no `LLTextureParams` in `messages::msgvolumeextras`
   |                                        |
   |        

I'm getting errors like the above after I reorganized a program by adding an additional binary in the cargo.toml file, one that uses many files from the root crate. What has me puzzled is that most "use" imports work. Only a few fail.

Here's the beginning of the cargo.toml file:

#   
#   Viewer for Second Life and Open Simulator
#
[package]
name = "sltestviewer"
version = "0.1.0"
authors = ["John-Nagle <nagle@sitetruth.com>"]
edition = "2018"
build="build/main.rs"

#   UDP replayer - replays UDP captures and outputs a huge JSON file
#   which can be displayed by another program
[[bin]]
name = "replayer"
test = false
bench = false

#   Mapmaker - makes map tiles and impostors of regions.
[[bin]]
name = "mapmaker"
test = false
bench = false
version = "0.0.1"

Before reorganization, there was one target, "sltestviewer". Now, that's a stub, and there are targets "replayer" (now the main program being generated) and a stub "mapmaker".

The first item not found is ExtraParameters, which is defined in msgvolumextras.rs:

#[derive(Default, Clone, PartialEq, Debug)]
pub struct ExtraParameters {
    pub params: HashMap<ExtraParameterCode, ExtraParameter>, 
} 

Note that the compiler found the file, but not the pub struct within the file. That's what's puzzling.

(Edit)
The main program is now

pub mod assets;
pub mod common;
pub mod messages;
pub mod viewer;
fn main() {
    println!("Hello from future main program");
}

and there are "pub mod" statements in the appropriate "mod.rs" files to make things visible. This all worked when the main program was at the root of the crate. So it's some kind of visibility issue.

If you have code that will be used by multiple binaries, you should create a library (src/lib.rs), and put all the common code into the library.

For example, if all of those modules live in the library, your library crate would look like this:

// src/lib.rs:
pub mod assets;
pub mod common;
pub mod messages;
pub mod viewer;

Within any of these library modules (including their submodules), you can refer to other library modules with the crate:: prefix, since they are all within the same crate. For example:

// src/common.rs
use crate::messages::msgvolumeextras::ExtraParameters;

But within your binary crates (including their submodules), you will access them through your library. By default, the library name is the same as the package name (sltestviewer). For example:

// src/bin/replayer.rs
use sltestviewer::messages::msgvolumeextras::ExtraParameters;

If you still have errors like “no LLTextureParams in messages::msgvolumeextras,” it would be useful to know which crate the messages module is part of (i.e., is it defined in lib.rs or main.rs or one of your other binary crates), and also where and how LLTextureParams is defined.

1 Like

That's an alternative organization, but it comes with its own set of constraints. Calling out of the library gets complicated.

This doesn't address the question asked. The program has many cross-module "use" statements, but only some of them fail, and it's not clear why some fail when other similar ones don't.

It's all repeatable; tried "cargo clean" and a rebuild.

Is this file located at src/messages/msgvolumeextras.rs?

Do you have pub mod msgvolumeextras; in src/messages/mod.rs (or src/messages.rs) and nowhere else?

It might be useful to see exactly where and how each of the modules in this path is declared. It would also be useful to know which of your crates rustc is compiling when the error above is generated.

Yes.

Yes, in src/messages/mod.rs there is

pub mod msgvolumextras;

and I just did a grep -r to make sure there are no other occurences of "mod msgvolumeextra".

There's only one crate, and one cargo.toml file, here.

Each of your binaries is a separate crate (i.e., it is a separate compilation unit), as is your library if you have one. Which binary (or library) contains the messages module?

Each module should live in exactly one crate. Otherwise, you'll end up compiling the same code multiple times but with different paths, and you may end up with mysterious errors.

1 Like

Which binary (or library) contains the messages module?

"sltestviewer" has almost everything. The other binaries import things from there.

You can't import things from one binary into another binary. Within a binary, you can only use code that is either defined within the same binary, or in a library. (This is why a library is necessary if you want to actually share code between binaries rather than duplicating it.)

You can import into other binaries from the root crate. Otherwise, "examples" would never work.

"examples" can only load code from the library crate (src/lib.rs). They cannot load code from any binaries, including the "main" binary (src/main.rs).

To see for yourself, try it in this repo:

git clone https://github.com/mbrubeck/foo
cd foo
cargo build --examples

To reuse code in multiple binaries, put in a library.

OK. Did it as a library. That's better. I wanted one project with multiple binaries, not multiple projects, and it's working that way now.

Thanks.

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.