What is the difference between [dependencies] and [dev-dependencies] in Cargo.toml? - rust

In Rust, what is the difference between the two types of dependencies? It seems that the dev-dependency is conditional/ invoked at a certain time only.
If I include a crate in dev-dependencies, it gives me an error:
$ cargo build
Compiling <> ()
error[E0432]: unresolved import `uuid`
--> / |
28 | use uuid::Uuid;
| ^^^^ use of undeclared crate or module `uuid`
Cargo.toml content (clipped)
[package]
<clipped>
[dependencies]
<clipped>
[dev-dependencies]
uuid = { version = "1.0.0",features = ["serde", "v4"] }
But if I move it to the dependency section, then there is no error.
Closest related post: What is the difference between [dependencies] and [dependencies.dependency-name] in Cargo.toml?

Simple: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#development-dependencies
They are dependencies that only get included / built for examples, tests, and benchmarks.
Most importantly, they will not be included when you run a simple cargo build.

Related

UseDeclaration cannot find struct in the crate root

I start with the cargo new tst. Then in the src/lib.rs I have:
pub struct Config {}
And src/main.rs looks like the following:
use crate::Config;
fn main() {}
This however does not compile:
> cargo run
Compiling tst v0.1.0 (/home/*/rust/book/tst)
error[E0432]: unresolved import `crate::Config`
--> src/main.rs:1:5
|
1 | use crate::Config;
| ^^^^^^^^^^^^^ no `Config` in the root
For more information about this error, try `rustc --explain E0432`.
error: could not compile `tst` due to previous error
But if I replace crate:: with the name of the crate like so:
use tst::Config;
fn main() {}
Then it just work:
> cargo run
Compiling tst v0.1.0 (/home/*/rust/book/tst)
warning: unused import: `tst::Config`
--> src/main.rs:1:5
|
1 | use tst::Config;
| ^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: `tst` (bin "tst") generated 1 warning
Finished dev [unoptimized + debuginfo] target(s) in 0.25s
Running `target/debug/tst`
The output for rustc --explain E0432 has the following quote, which if I understand it correctly means, that I can either use the name of a crate or simply crate:::
In Rust 2018, paths in use statements are relative to the current module
unless they begin with the name of a crate or a literal crate::, in which
case they start from the crate root. As in Rust 2015 code, the self:: and
super:: prefixes refer to the current and parent modules respectively.
Am I doing something wrong in here? Is there a way to use code from lib.rs without hardcoding the name of the crate?
> rustc --version
rustc 1.56.1 (Arch Linux rust 1:1.56.1-3)
> cat Cargo.toml
[package]
name = "tst"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
There is no way to refer to “the library crate in my package”; you must refer to it by its name. The Rust compiler doesn't (currently) know anything about other crates that happen to be in the same Cargo package; it just compiles one crate at a time.
In order for this to change, you would need to write a Rust RFC, which would need to include a description of why it would be valuable to have this feature — probably a stronger argument than “it would be less hardcoded”, since main depending on the library is almost certainly going to use library-specific names anyway, so the name of the library itself is a minor issue (unless, I suppose, you're creating many packages from a common template).

can't find crate when using extern command

I am learning rust, now I tried to use Diesel to do some operation to database. I write the main.rs like this:
#[macro_use]
extern crate reddwarf_music;
fn main(){
}
then compile the project using command cargo build, shows error like this:
~/Documents/GitHub/reddwarf_music on  develop! ⌚ 14:50:50
$ cargo build ‹ruby-2.7.2›
Compiling reddwarf_music v0.1.0 (/Users/dolphin/Documents/GitHub/reddwarf_music)
error[E0463]: can't find crate for `reddwarf_music`
--> src/main.rs:3:1
|
3 | extern crate reddwarf_music;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
error: aborting due to previous error
For more information about this error, try `rustc --explain E0463`.
error: could not compile `reddwarf_music`
To learn more, run the command again with --verbose.
(base)
and this is my Cargo.toml:
[package]
name = "reddwarf_music"
version = "0.1.0"
edition = "2018"
[dependencies]
rocket = { version = "0.5.0-rc.1", features = ["json"] }
rand = "0.8.4"
serde = { version = "1.0.64", features = ["derive"] }
serde_json = "1.0.64"
reqwest = "0.11.4"
# database
diesel = { version = "1.4.4", features = ["postgres"] }
dotenv = "0.15.0"
am I doing the right way? the next step I want to use the mod like this:
use reddwarf_music::schema::posts::dsl::*;
I am follow the docs step by step from here to using diesel. what should I do to make it work as expect? the diesel official docs use it like this way. In my project, it did not work.
As far as I can see, the crate you are trying to compile is called reddwarf_music. extern crate tries to include a crate into the crate you're currently compiling. You're in effect trying to include the crate reddwarf_music into itself in order to use proc_macros from reddwarf_music in reddwarf_music. This is unfortunately not possible.
What the official Diesel documentation does is slightly different. Their library crate is called diesel_demo, but the code run when running cargo run --bin is actually the code inside the folder bin, which is not directly a part of the library crate, and instead part of a separate binary crate. If you instead of the file main.rs in the root, create a file inside a bin folder and run cargo build --bin, I think it should work.
(This has been edited to more directly answer the question)

Compile error when running cargo bench (criterion/serde)

I added following lines to the cargo.toml of my project in order to benchmark my code:
[dev-dependencies]
criterion = "0.3"
[[bench]]
name = "samples"
harness = false
After running cargo bench, I get a lot of errors similar to the following:
Compiling criterion v0.3.4
error[E0603]: module `export` is private
--> C:\Development\Rust\cargo\registry\src\github.com-1ecc6299db9ec823\criterion-0.3.4\src\connection.rs:201:17
|
201 | #[derive(Debug, Deserialize)]
| ^^^^^^^^^^^ private module
|
note: the module `export` is defined here
--> C:\Development\Rust\cargo\registry\src\github.com-1ecc6299db9ec823\serde-1.0.123\src\lib.rs:275:5
|
275 | use self::__private as export;
The error message looks to me that there is a problem between serde and criterion. But I did not find this error message in either project issues, so there may be a hidden reason in my workspace.
Some additional information:
the project is compiled using the nightly toolchain
there is just one explicit dependency (proc macros) in the cargo.toml which transitively references syn, quote and proc-macro2
The serde version and serde_derive version in your dependency graph are mismatched. You need to use cargo update to bring them in sync. The two must have the identical version number always.

Link basic rust program to rlib in a subfolder

This is my first attempt at rust, I am from a c++ background and trying to get going. So I started to create my project in a folder called .../rust/
Note: I used this link to get started with the tools: https://medium.com/#wizofe/cross-compiling-rust-for-arm-e-g-raspberry-pi-using-any-os-11711ebfc52b
I have created the default rust program using: cargo new --bin rust_test. This creates .../rust/rust_test.
I can build using: cargo build or cargo build --target=armv7-unknown-linux-gnueabihf (for my BeagleBB)
So far so good. Now I want to create a library that I can share with other projects. But I will create it inside the rust_test folder as .../rust/rust_test/utils:
Created the library with: cargo new --lib utils
I can build my utils in side the utils dir with: cargo build, this generates a .rlib file.
Now I wanted to get my rust_test project to build it as a dependency, I found I just had to add: utils = { path = "utils" } to my rust_test .toml file.
Now I can build my rust_test executable and my utils lib in the rust_test folder with cargo build
Again, all good so far. The final part of the puzzle for me is to use the function within my utils library. There are two functions in there. One called adder(a,b) - an attempt at a template function, and a basic function called test123(). This is where I have got stuck. I can't seem to formulate the correct syntax to call either of these functions.
Here are my main files:
rust_test
location: .../rust/rust_test/
Cargo.toml
[package]
name = "rust_test"
version = "0.1.0"
authors = ["test#gmail.com <test#gmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
utils = { path = "utils" }
main.rs
mod utils;
fn main() {
println!("Hello, world!");
utils::test123(); // ??? - does not work
}
utils
location: .../rust/rust_test/utils/
Cargo.toml
[package]
name = "utils"
version = "0.1.0"
authors = ["test#gmail.com <test#gmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
lib.rs
#[cfg(test)]
mod tests {
#[test]
fn adder<T>(a: T, b: T) -> T {
return a + b;
}
}
#[cfg(utils)]
mod utils {
#[utils]
fn test123() {
println!("test!");
}
}
The output
~/bbb/development/rust/rust_test$ cargo build
Compiling rust_test v0.1.0 (/home/user/bbb/development/rust_test)
error[E0583]: file not found for module `utils`
--> src/main.rs:1:1
|
1 | mod utils;
| ^^^^^^^^^^
|
= help: to create the module `utils`, create file "src/utils.rs"
error[E0425]: cannot find function `test123` in module `utils`
--> src/main.rs:6:12
|
6 | utils::test123(); // ??? - does not work
| ^^^^^^^ not found in `utils`
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0425, E0583.
For more information about an error, try `rustc --explain E0425`.
error: could not compile `rust_test`.
I have to admit I don't really understand what the #[cfg...] and #[...] lines do. But from what I have read I thought the mod utils; in main.rs tells the rust compiler/linker to look else where for the test123() function.
Maybe I have not even linked the files at all yet - I have only built them?
So the question is what do I need to do now to link my library to my application so I can use the lib function test123()?
update
if I remove mod utils; I get the error:
user#user-VirtualBox:~/bbb/development/rust/rust_test$ cargo build
Compiling rust_test v0.1.0 (/home/user/bbb/development/rust_test)
error[E0425]: cannot find function `test123` in crate `utils`
--> src/main.rs:4:12
|
4 | utils::test123(); // ??? - does not work
| ^^^^^^^ not found in `utils`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0425`.
error: could not compile `rust_test`.
I think that getting rid of mod utils; in main.rs should
solve your problem.
mod utils; in main.rs tells the compiler that
utils is an inner module of your application (but it
does not exist so does not contain the functions you are
looking for), although it is actually a crate (external
to your application).
The module system helps organise the details inside a crate
while a crate is seen as a library.
edit
You should also get rid of #[cfg(utils)] in lib.rs because
it means that the following item exists only if the utils
feature is set in your Cargo.toml file (which is not
the case).
The cfg() directives are intended for conditional compilation.
( https://doc.rust-lang.org/reference/conditional-compilation.html )
And sorry, I forgot, mod utils {} in lib.rs may not be necessary,
or you will need to refer to the function as utils::utils::test123()
from your application.
The first utils refers to the crate, the second utils refers to
an inner module of this crate.

Using a crate in a Cargo project errors with "maybe a missing extern crate"

I started learning Rust today, but I am stuck at this step. I want use the rand crate in my project, so I updated my Cargo.toml as suggested in the tutorial:
[package]
name = "guessing_game"
version = "0.1.0"
authors = ["Novice <novice.coder#gmail.com>"]
[dependencies]
rand = "0.3.14"
Importing it in my code as:
use rand::Rng;
It gives this error:
error[E0432]: unresolved import `rand`
--> src/main.rs:1:5
|
1 | use rand::Rng;
| ^^^^ maybe a missing `extern crate rand;`?
Am I missing something?
I added edition = "2018" as suggested:
Cargo.toml:
[package]
name = "guessing_game"
version = "0.1.0"
authors = ["Novice <novice.coder#gmail.com>"]
edition = "2018"
[dependencies]
rand = "0.3.14"
Cargo build now gives:
$ cargo build --verbose
Fresh libc v0.2.45
Fresh rand v0.4.3
Fresh rand v0.3.22
Compiling guessing_game v0.1.0 (/home/bappaditya/projects/guessing_game)
Running `rustc --edition=2018 --crate-name guessing_game src/main.rs --color always --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=4d1c2d587c45b4
c6 -C extra-filename=-4d1c2d587c45b4c6 --out-dir
/home/bappaditya/projects/guessing_game/target/debug/deps -C
incremental=/home/bappaditya/projects/guessing_game/target
/debug/incremental -L
dependency=/home/bappaditya/projects/guessing_game/target/debug/deps --
extern rand=/home/bappaditya/projects/guessing_game/target/debug/deps/libra
nd-78fc4b142cc921d4.rlib`
error: Edition 2018 is unstable and only available for nightly builds of rustc.
I updated rust using rustup update and then added extern crate rand; to my main.rs. Now it's working as expected.
The program runs but in my vscode problems tab its still showing the error -
error[E0432]: unresolved import `rand`
--> src/main.rs:1:5
|
1 | use rand::Rng;
| ^^^^ maybe a missing `extern crate rand;`?
The quick fix is to add
edition = "2021"
to your Cargo.toml, above the [dependencies] line.
Explanation
There are three major editions of Rust: Rust 2015, 2018, and 2021. Rust 2021 is recommended for new code, but since Rust needs to be backward compatible, you have to opt in to use it.
In Rust 2015, you had to write an extern crate statement before using anything outside of std. That's where the error message comes from. But you don't have to do that in Rust 2018 or 2021 anymore, which is why setting the edition fixes it.
There are many more changes in Rust 2021; if you're interested, you can read about them in the edition guide.

Resources