can't find crate when using extern command - rust

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)

Related

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

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.

Unable to use rust crates

I'm new to rust. I'm following a getting started tutorial that imports the crate random-number but when running the code I'm getting the error can't find crate for 'random_number'. What am I doing wrong?
~/Cargo.toml:
[package]
name = "test"
version = "0.0.1"
edition = "2021"
[dependencies]
random-number = "0.1.8"
~/src/main.rs:
extern crate random_number;
use random_number::random;
fn main() {
let num: i8 = random!(..);
println!("{}", num);
}
rustc is not meant to be used directly. It is the compiler that can compile a .rs file, but it doesn't have any dependency manager attached to it. So if you decide to use rustc directly, you need to manage your dependencies manually.
cargo is the official tool to compile Rust projects. It internally uses rustc, but additionally manages the project's dependencies that are specified in Cargo.toml.
cargo build --release && ./target/release/<project_name>
or the short form:
cargo run --release

Why do I get "can't find crate" that is listed as a dependency in Cargo.toml when I compile with rustc?

My Cargo.toml includes this:
[dependencies]
chrono = "0.4"
And my code includes this:
extern crate chrono;
use chrono::{Duration, DateTime, Utc};
yet when I run my code, I get this error:
error[E0463]: can't find crate for `chrono`
--> src/lib.rs:1:1
|
1 | extern crate chrono;
| ^^^^^^^^^^^^^^^^^^^^ can't find crate
I am working on an Exercism exercise, so the way I am building/running the program is rustc src/lib.rs to test my solution. Is the problem because I'm not running rustc src/main.rs?
When you're directly running rustc, all that compiler knows is the command line arguments. It doesn't know anything about Cargo.toml, in particular, and so it doesn't know where to look for chrono library.
To use dependency management, you have to compile your project with Cargo - just use cargo build/cargo run/cargo test, and everything should be fine. See the Book for details.
If, however, you want (for some reason) use rustc directly, I'd advise to check first cargo anyway, by using cargo build --verbose. It will show all the commands that are invoked, allowing you to inspect the possible arguments to be defined manually.

How to import a crate dependency when the library name is different from the package name?

I have a crate that is imported straight off of GitHub, as per Cargo's documentation:
[dependencies]
libfoo = { git = "ssh://git#github.com/me/libfoo", branch = "dev" }
[lib]
path = "src/rust/lib.rs"
name = "myprj"
crate-type = ["cdylib"]
Running cargo build works fine here, Cargo fetches libfoo and builds it in the ~/.cargo directory. When I try to use (import) it in lib.rs:
extern crate libfoo; //also tried foo
Cargo chokes:
error[E0463]: can't find crate for `libfoo`
--> src/rust/lib.rs:1:1
|
1 | extern crate libfoo;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
Interestingly, IntelliJ's Rust plugin does find the crate when I click on it in lib.rs – it navigates to the downloaded source in ~/.cargo...
In the dependency libfoo, the lib section of the Cargo.toml file is specified as:
[package]
name = "libfoo"
[lib]
name = "foo"
crate-type = ["cdylib"]
I have tried all permutations of libfoo and foo to see if Cargo is getting confused between the lib name and the package/directory name.
It also fails if I specify a local path to the dependency. (Cargo compiles the dependency but then claims not to find it when it is declared/imported in lib.rs.)
[dependencies]
libfoo = { path = "/Users/me/dev/libfoo" }
If I include a crate from git or the file system that has the same [lib] name as the [package] name, it works fine. So it appears the problem is with crates that have a have a library ([lib]) name that is different from the package ([package]) name.
If I remove the [lib] section from the dependency's Cargo.toml file, it works.
Update: if crate-type = ["cdylib"] is removed from libfoo, this works with foo imported. If that is there, I get the same error with extern crate foo;.
Cargo is interested in package names when it comes to dependencies, while the compiler (rustc) is interested in library names when it comes to loading their metadata and linking with them.
Let's take a look again at this Cargo.toml excerpt:
[package]
name = "libfoo"
[lib]
name = "foo"
Here, the package name is libfoo and the library name is foo.
When you want to declare a dependency on libfoo in your project, you need to write the package name (libfoo) in the [dependencies] table. For example:
[dependencies]
libfoo = { git = "ssh://git#github.com/me/libfoo", branch = "dev" }
This is what you already have, and it's correct.
However, when you want to import the library in your crate, you need to write the library name in the extern crate item, i.e.
extern crate foo;
How did I figure this out? First, I wrote libfoo in both Cargo.toml and the extern crate item, as you described. When I ran cargo build, I noticed that libfoo was built successfully, indicating that Cargo correctly resolved the dependency. But I also noticed that the compiler couldn't find libfoo, as you experienced.
I then inspected the command line passed to rustc by running cargo build --verbose. This is what I saw (irrelevant parts omitted):
Running `rustc [...] --extern foo=/[path]/target/debug/deps/libfoo-5cf876c5c8ac1bfb.rlib`
The --extern name=path argument tells rustc that the crate named name is located in path. The name here is foo, so we must write extern crate foo; in the code to reference it.

error: can't find crate

I'm trying to use this library.
But, cargo build says this:
Compiling test v0.1.0 (file:///C:/path/to/project/test)
src\main.rs:1:1: 1:28 error: can't find crate for `jvm_assembler` [E0463]
src\main.rs:1 extern crate jvm_assembler;
^~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
Could not compile `test`.
To learn more, run the command again with --verbose.
My Cargo.toml is this:
[package]
name = "test"
version = "0.1.0"
authors = ["yomizu_rai"]
[dependencies]
jvm-assembler = "*"
src/main.rs is this, and there are no other sourcefiles.
extern crate jvm_assembler;
use jvm_assembler::*;
fn main() {}
I think my Cargo.toml is not wrong, and src/main.rs has no room for mistake.
Why can not rustc find jvm-assembler?
How do I resolve?
Cargo can only find crates by name if they are on crates.io. In your case you need to specify the git URL, see the section on dependencies in the Cargo documentation.

Resources