"Unresolved import" when linking with [lib] in Cargo.toml [duplicate] - rust

I'm trying to create a module in Rust and then use it from a different file. This is my file structure:
matthias#X1:~/projects/bitter-oyster$ tree
.
├── Cargo.lock
├── Cargo.toml
├── Readme.md
├── src
│   ├── liblib.rlib
│   ├── lib.rs
│   ├── main.rs
│   ├── main.rs~
│   └── plot
│   ├── line.rs
│   └── mod.rs
└── target
└── debug
├── bitter_oyster.d
├── build
├── deps
├── examples
├── libbitter_oyster.rlib
└── native
8 directories, 11 files
This is Cargo.toml:
[package]
name = "bitter-oyster"
version = "0.1.0"
authors = ["matthias"]
[dependencies]
This is main.rs:
extern crate plot;
fn main() {
println!("----");
plot::line::test();
}
This is lib.rs:
mod plot;
this is plot/mod.rs
mod line;
and this is plot/line.rs
pub fn test(){
println!("Here line");
}
When I try to compile my program using: cargo run I get:
Compiling bitter-oyster v0.1.0 (file:///home/matthias/projects/bitter-oyster)
/home/matthias/projects/bitter-oyster/src/main.rs:1:1: 1:19 error: can't find crate for `plot` [E0463]
/home/matthias/projects/bitter-oyster/src/main.rs:1 extern crate plot;
How do I compile my program? As far as I can tell from online documentations this should work, but it doesn't.

To add to the given answers, a library compiled as a cdylib (docs) can generate this error when you try to reference it in another project. I solved it by separating the code I wished to reuse in a regular lib project.

If you see this error:
error[E0463]: can't find crate for `PACKAGE`
|
1 | extern crate PACKAGE;
| ^^^^^^^^^^^^^^^^^^^^^ can't find crate
it could be that you haven't added the desired crate to the dependencies list in your Cargo.toml:
[dependencies]
PACKAGE = "1.2.3"
See specifying dependencies in the Cargo docs.

You have the following problems:
you have to use extern crate bitter_oyster; in main.rs, because the produced binary uses your crate, the binary is not a part of it.
Also, call bitter_oyster::plot::line::test(); in main.rs instead of plot::line::test();. plot is a module in the bitter_oyster crate, such as line. You are referring to the test function with its fully qualified name.
Make sure, that every module is exported in the fully qualified name. You can make a module public with the pub keyword, like pub mod plot;
You can find more information about Rust's module system here: https://doc.rust-lang.org/book/crates-and-modules.html
A working copy of your module structure is as follows:
src/main.rs:
extern crate bitter_oyster;
fn main() {
println!("----");
bitter_oyster::plot::line::test();
}
src/lib.rs:
pub mod plot;
src/plot/mod.rs:
pub mod line;
src/plot/line.rs :
pub fn test(){
println!("Here line");
}

I got this issue when I had imported my crate in [dev-dependencies] instead of [dependencies]

This can also happen when you don't enable certain "feature flags" for specific crates. Unfortunately, these feature flags can sometimes be undocumented. When feature flags are missing when required, they show the same error ("Can't find crate")
I was using diesel, and was trying to use BigInteger:
Wrong
diesel = { version = "2.0.3", features = ["postgres", "chrono", "r2d2", "serde_json", "biginteger"] }
Correct:
diesel = { version = "2.0.3", features = ["postgres", "chrono", "r2d2", "serde_json", "numeric"] }

Related

error[E0601]: `main` function not found in crate for utilitary file for a custom binary

I have a custom binary called cli.rs and a file clap.rs with some utilities for clap.rs:
src
bin
cli.rs
clap.rs
where clap.rs just provides me with the clap definitions:
pub fn get_matches() -> ArgMatches {
}
fn main() {}
so I can import them into cli.rs.
However if I take out fn main from clap.rs I get
error[E0601]: `main` function not found in crate `clap`
I don't want clap.rs to have a main function, I just it to simply be a utils file for the binary cli.rs
From the cargo book about package layout:
Cargo uses conventions for file placement to make it easy to dive into a new Cargo package:
.
// ...
├── src/
| | // ...
│ └── bin/
│ ├── named-executable.rs
│ ├── another-executable.rs
│ └── multi-file-executable/
│ ├── main.rs
│ └── some_module.rs
| // ...
[...]
The default executable file is src/main.rs.
Other executables can be placed in src/bin/.
[...]
If a binary, example, bench, or integration test consists of multiple source files, place a main.rs file along with the extra modules within a subdirectory of the src/bin, examples, benches, or tests directory. The name of the executable will be the directory name.
By putting both cli.rs and clap.rs into bin/, you told Cargo that you have two binaries: One named cli, one named clap.
This package layout should work for you:
src
bin
cli
main.rs (that's your cli.rs)
clap.rs
Alternatively, you could also put clap.rs into a lib crate (by putting it inside lib/ and then putting pub mod clap; inside lib.rs). Note however that you then need to reference get_matches() as <your_package_name>::clap::get_matches() so that the compiler knows you are not referencing something from your binary crate, but something from your library crate.

Can't find local crate specified in Cargo.toml even though main.rs exists [duplicate]

My project's path structure is as follows:
demo
├── benches
│   └── crypto_bench.rs
├── src
│   ├── main.rs
│   └── crypto.rs
├── Cargo.lock
└── Cargo.toml
crypto.rs contains a struct Crypto with implementation.
crypto.rs is referred to from main.rs using mod crypto;
How can I use crypto.rs from crypto_bench.rs inside the benches folder?
I have tried all kinds of variations of extern crate, mod, super and use.
All examples I could find online are for library projects with a lib.rs and those "imports" don't work when using a project with a main.rs file.
Here's a literal answer, but don't actually use this!
#![feature(test)]
extern crate test;
#[path = "../src/foo.rs"] // Here
mod foo;
#[bench]
fn bencher(_: &mut test::Bencher) {
println!("{:?}", foo::Thang);
}
In fact, it's very likely that this won't work because your code in foo.rs needs supporting code from other files that won't be included.
Instead of doing this, just create a library. You have the pure definition of a library - a piece of code that wants to be used in two different executables. You don't have to give up having an executable or even create separate directories (see Rust package with both a library and a binary?), but creating reusable code is a key component of making good code.
Your end state would look something like:
demo
├── Cargo.lock
├── Cargo.toml
├── benches
│   └── crypto_bench.rs
├── benchmarks
└── src
├── bin
│   └── main.rs
├── crypto.rs
└── lib.rs
Move the reusable code to a library:
src/lib.rs
pub mod crypto;
src/crypto.rs
pub struct Crypto;
impl Crypto {
pub fn secret() {}
}
Then import your library from the benchmark and the binary:
benches/crypto_bench.rs
#![feature(test)]
extern crate test;
use demo::crypto::Crypto;
use test::Bencher;
#[bench]
fn speedy(b: &mut Bencher) {
b.iter(|| Crypto::secret());
}
src/bin/main.rs
use demo::crypto::Crypto;
fn main() {
Crypto::secret();
eprintln!("Did the secret thing!");
}
You can then run it in different ways:
$ cargo build
Compiling demo v0.1.0 (/private/tmp/example)
Finished dev [unoptimized + debuginfo] target(s) in 0.51s
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/main`
Did the secret thing!
$ cargo +nightly bench
Compiling demo v0.1.0 (/private/tmp/example)
Finished release [optimized] target(s) in 0.70s
Running target/release/deps/my_benchmark-5c9c5716763252a0
running 1 test
test speedy ... bench: 1 ns/iter (+/- 0)
test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured; 0 filtered out
See also:
Rust package with both a library and a binary?
What is an idiomatic way to have shared utility functions for integration tests and benchmarks?
Can I make an object public for integration tests and/or benchmarks only?
Cannot import a module in an integration test

Correct place for private module to be used by multiple executables

Two executables' sources, foo.rs and bar.rs, are located in src/bin.
Private common functionality exists in src/bin/common.rs.
foo.rs and bar.rs include this functionality with:
mod common;
use common::{Bish, Bash, Bosh};
This works, but src/bin/common.rs doesn't feel like the right path for something which isn't going to be built into an executable.
Moving common.rs to src or src/lib stops foo.rs and bar.rs from seeing it.
Where should I put common.rs and how do I then import it?
A common approach to store shared parts at lib.rs and use these in binaries. Its usage, though, is a bit different than simply mod + use. In fact, library is a separate crate, so you need to access it via crate name (defined in Cargo.toml).
Cargo.toml:
[package]
name = "crate-name"
# ... the rest
src/bin/foo.rs:
fn main() {
crate_name::fun();
}
src/lib.rs:
pub fn fun() {}
example
├── Cargo.toml
└── src
├── bin
│   ├── bar.rs
│   └── foo.rs
├── common.rs
└── lib.rs
foo.rs and bar.rs:
#[path = "../common.rs"]
mod common;
use common::{Bish, Bash, Bosh};
also see: How can I use a module from outside the src folder in a binary project, such as for integration tests or benchmarks?

Import a module from my crate in a Criterion benchmark [duplicate]

My project's path structure is as follows:
demo
├── benches
│   └── crypto_bench.rs
├── src
│   ├── main.rs
│   └── crypto.rs
├── Cargo.lock
└── Cargo.toml
crypto.rs contains a struct Crypto with implementation.
crypto.rs is referred to from main.rs using mod crypto;
How can I use crypto.rs from crypto_bench.rs inside the benches folder?
I have tried all kinds of variations of extern crate, mod, super and use.
All examples I could find online are for library projects with a lib.rs and those "imports" don't work when using a project with a main.rs file.
Here's a literal answer, but don't actually use this!
#![feature(test)]
extern crate test;
#[path = "../src/foo.rs"] // Here
mod foo;
#[bench]
fn bencher(_: &mut test::Bencher) {
println!("{:?}", foo::Thang);
}
In fact, it's very likely that this won't work because your code in foo.rs needs supporting code from other files that won't be included.
Instead of doing this, just create a library. You have the pure definition of a library - a piece of code that wants to be used in two different executables. You don't have to give up having an executable or even create separate directories (see Rust package with both a library and a binary?), but creating reusable code is a key component of making good code.
Your end state would look something like:
demo
├── Cargo.lock
├── Cargo.toml
├── benches
│   └── crypto_bench.rs
├── benchmarks
└── src
├── bin
│   └── main.rs
├── crypto.rs
└── lib.rs
Move the reusable code to a library:
src/lib.rs
pub mod crypto;
src/crypto.rs
pub struct Crypto;
impl Crypto {
pub fn secret() {}
}
Then import your library from the benchmark and the binary:
benches/crypto_bench.rs
#![feature(test)]
extern crate test;
use demo::crypto::Crypto;
use test::Bencher;
#[bench]
fn speedy(b: &mut Bencher) {
b.iter(|| Crypto::secret());
}
src/bin/main.rs
use demo::crypto::Crypto;
fn main() {
Crypto::secret();
eprintln!("Did the secret thing!");
}
You can then run it in different ways:
$ cargo build
Compiling demo v0.1.0 (/private/tmp/example)
Finished dev [unoptimized + debuginfo] target(s) in 0.51s
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/main`
Did the secret thing!
$ cargo +nightly bench
Compiling demo v0.1.0 (/private/tmp/example)
Finished release [optimized] target(s) in 0.70s
Running target/release/deps/my_benchmark-5c9c5716763252a0
running 1 test
test speedy ... bench: 1 ns/iter (+/- 0)
test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured; 0 filtered out
See also:
Rust package with both a library and a binary?
What is an idiomatic way to have shared utility functions for integration tests and benchmarks?
Can I make an object public for integration tests and/or benchmarks only?
Cannot import a module in an integration test

Importing non-root module from multiple non-root binaries

I am learning Rust and decided to write a simple client/server program. Both the client and the server will be using a very simple module I've already written. Knowing that this code might grow, I decided to compartmentalize my source for clarity. Right now my current hierarchy looks as follows:
├── Cargo.lock
├── Cargo.toml
├── README.md
├── src
│   ├── client
│   │   └── main.rs
│   ├── common
│   │   ├── communicate.rs
│   │   └── mod.rs
│   ├── lib.rs
│   └── server
│   └── main.rs
Many of the examples I found on Stack Overflow and the net provide great samples for when the main.rs is in the project root directory. Unfortunately I'm trying to do something different as shown above.
communicate.rs contains all of the network code I have written. Eventually I will add other Rust files here and include their public mod statement in mod.rs. Currently common/mod.rs all I have is
pub mod communicate;
Focusing on just the client folder, all I have is main.rs as shown. The file "header" lists
extern crate common;
use std::thread;
use std::time;
use std::net;
use std::mem;
use common::communicate;
pub fn main() {
// ...
}
Besides the fundamental [package] section, all I have in Cargo.toml is
[[bin]]
name = "server"
path = "src/server/main.rs"
[[bin]]
name = "client"
path = "src/client/main.rs"
When I try to build the client binary, the compiler complains that the common crate could not be found.
$ cargo build
Compiling clientserver v0.1.0 (file:///home/soplu/rust/RustClientServer)
client/main.rs:1:1: 1:21 error: can't find crate for `common` [E0463]
client/main.rs:1 extern crate common;
^~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
error: Could not compile `clientserver`.
To learn more, run the command again with --verbose.
I think this is because it is looking for a common crate within the client/ folder. I had this same problem when I tried the mod statement instead of extern crate statement.
use std::thread;
use std::time;
use std::net;
use std::mem;
mod common;
Gave me:
client/main.rs:6:5: 6:11 error: file not found for module `common`
client/main.rs:6 mod common;
^~~~~~
client/main.rs:6:5: 12:11 help: name the file either common.rs or common/mod.rs inside the directory "client"
I also tried (using the extern crate...) adding a lib.rs in the client whose contents are pub mod common; but I still get the same error as the first.
One potential solution I found to model it like this project, but this would require a Cargo.toml in every folder, something which I'd like to avoid.
I feel like I am close but am missing something.
You are not building common as a crate right now. The crates being built are the library clientserver (the default name for the library is the package name) and the binaries client and server.
Normally, extern crate clientserver; should work. However, if you want to name your library differently, you can do so by specifying a different name in a [lib] section in Cargo.toml. In this section, you can also specify a different source path for the library's main source file. In your case, it will probably be better, otherwise you'll end up with a crate named common and all of its contents would be in a module named common, so you'd have to access everything as common::common::foo. For example, by adding this to your Cargo.toml:
[lib]
name = "common"
path = "src/common/lib.rs"
you could combine src/lib.rs and src/common/mod.rs into src/common/lib.rs. Then, extern crate common; should work in your binaries.

Resources