Unable to find symbols from extern crates included with `use` - rust

I'm trying to use some Rust libraries from crates on Github. This is the first time I've tried to do this. The code, lifted from an "html" library example, begins like this:
mod interactive_test {
extern crate http;
extern crate url;
use std::os;
use std::str;
use url::Url;
use http::client::RequestWriter;
use http::method::Get;
use http::headers::HeaderEnum;
// ...
}
fn main() {}
Errors look like this:
error[E0432]: unresolved import `url::Url`
--> src/main.rs:7:9
|
7 | use url::Url;
| ^^^^^^^^ Did you mean `self::url`?
error[E0432]: unresolved import `http::client::RequestWriter`
--> src/main.rs:9:9
|
9 | use http::client::RequestWriter;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Did you mean `interactive_test::http`?
error[E0432]: unresolved import `http::method::Get`
--> src/main.rs:10:9
|
10 | use http::method::Get;
| ^^^^^^^^^^^^^^^^^ Did you mean `self::http::method`?
error[E0432]: unresolved import `http::headers::HeaderEnum`
--> src/main.rs:11:9
|
11 | use http::headers::HeaderEnum;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ Did you mean `interactive_test::http`?
The Cargo.toml file contains
[dependencies.http]
http = "https://github.com/chris-morgan/rust-http"
[dependencies.url]
url = "0.2.7"
and the HTTP and URL packages were found and fetched by cargo build earlier.
The extern crate http and extern crate url lines do not generate errors; the crates are being found by the compiler, but those crates don't seem to contain the expected symbols. If I add `extern crate foo", I get an error, so that is checked.
This is probably some problem with how Rust or Cargo search for libraries. Rust is installed in ~/local, not as root, done by setting the --prefix parameter during installation. That may have broken something, although Cargo should handle that. Basic stuff like "hello_world" works fine; bringing in external libraries does not.
I notice that cargo update doesn't cause a re-fetch of the http and url crates from Github. The documentation indicates that it should.
Versions:
Ubuntu 14.04 LTS.
rustc 0.13.0-nightly (96a3c7c6a 2014-12-23 22:21:10 +0000)
cargo 0.0.1-pre-nightly (e11c317 2014-12-21 20:43:45 +0000)

The compiler gave you the answer you need.
Your extern crate statements are inside a module, and use statements require absolute paths. That is, when you say use url::Url; inside the interactive_test module, what you are actually saying is "use url::Url which is defined in the root module", which it isn't.
What you need to do is prefix the path with self:: to tell it to look in the current module. You can also use super:: to access the parent module (if that ever comes up).
Personally, I get around this by putting all my extern crate statements in the root module, which also serves as a kind of program-wide list of external crates being used.

Related

How to use my library from different project in rust [duplicate]

I've made a library:
cargo new my_lib
and I want to use that library in a different program:
cargo new my_program --bin
extern crate my_lib;
fn main {
println!("Hello, World!");
}
what do I need to do to get this to work?
They aren't in the same project folder.
.
├── my_lib
└── my_program
Hopefully this makes sense.
I thought I'd be able to override the path as per the Cargo guide, but it states
You cannot use this feature to tell Cargo how to find local unpublished crates.
This is when using the latest stable version of Rust (1.3).
Add a dependency section to your executable's Cargo.toml and specify the path:
[dependencies.my_lib]
path = "../my_lib"
or the equivalent alternate TOML:
[dependencies]
my_lib = { path = "../my_lib" }
Check out the Cargo docs for specifying dependencies for more detail, like how to use a git repository instead of a local path.
I was looking for an equivalent to mvn install. While this question is not quite a duplicate of my original question, anyone who stumbles across my original question and follows the link here will find a more complete answer.
The answer is "there is no equivalent to mvn install because you have to hard-code the path in the Cargo.toml file which will probably be wrong on someone else's computer, but you can get pretty close."
The existing answer is a bit brief and I had to flail around for a bit longer to actually get things working, so here's more detail:
/usr/bin/cargo run --color=always --package re5 --bin re5
Compiling re5 v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/re5)
error[E0432]: unresolved import `embroidery_stitcher`
--> re5/src/main.rs:5:5
|
5 | use embroidery_stitcher;
| ^^^^^^^^^^^^^^^^^^^ no `embroidery_stitcher` in the root
rustc --explain E0432 includes this paragraph that echos Shepmaster's answer:
Or, if you tried to use a module from an external crate, you may have missed
the extern crate declaration (which is usually placed in the crate root):
extern crate core; // Required to use the `core` crate
use core::any;
Switching from use to extern crate got me this:
/usr/bin/cargo run --color=always --package re5 --bin re5
Compiling embroidery_stitcher v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/embroidery_stitcher)
warning: function is never used: `svg_header`
--> embroidery_stitcher/src/lib.rs:2:1
|
2 | fn svg_header(w: i32, h: i32) -> String
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(dead_code)] on by default
Compiling re5 v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/re5)
error[E0603]: function `svg_header` is private
--> re5/src/main.rs:8:19
|
8 | let mut svg = embroidery_stitcher::svg_header(100,100);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I had to slap a pub on the front of that function
pub fn svg_header(w: i32, h: i32) -> String
Now it works.

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).

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.

What is the Rust/Cargo equivalent of `mvn install` for a personal library not uploaded to crates.io? [duplicate]

I've made a library:
cargo new my_lib
and I want to use that library in a different program:
cargo new my_program --bin
extern crate my_lib;
fn main {
println!("Hello, World!");
}
what do I need to do to get this to work?
They aren't in the same project folder.
.
├── my_lib
└── my_program
Hopefully this makes sense.
I thought I'd be able to override the path as per the Cargo guide, but it states
You cannot use this feature to tell Cargo how to find local unpublished crates.
This is when using the latest stable version of Rust (1.3).
Add a dependency section to your executable's Cargo.toml and specify the path:
[dependencies.my_lib]
path = "../my_lib"
or the equivalent alternate TOML:
[dependencies]
my_lib = { path = "../my_lib" }
Check out the Cargo docs for specifying dependencies for more detail, like how to use a git repository instead of a local path.
I was looking for an equivalent to mvn install. While this question is not quite a duplicate of my original question, anyone who stumbles across my original question and follows the link here will find a more complete answer.
The answer is "there is no equivalent to mvn install because you have to hard-code the path in the Cargo.toml file which will probably be wrong on someone else's computer, but you can get pretty close."
The existing answer is a bit brief and I had to flail around for a bit longer to actually get things working, so here's more detail:
/usr/bin/cargo run --color=always --package re5 --bin re5
Compiling re5 v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/re5)
error[E0432]: unresolved import `embroidery_stitcher`
--> re5/src/main.rs:5:5
|
5 | use embroidery_stitcher;
| ^^^^^^^^^^^^^^^^^^^ no `embroidery_stitcher` in the root
rustc --explain E0432 includes this paragraph that echos Shepmaster's answer:
Or, if you tried to use a module from an external crate, you may have missed
the extern crate declaration (which is usually placed in the crate root):
extern crate core; // Required to use the `core` crate
use core::any;
Switching from use to extern crate got me this:
/usr/bin/cargo run --color=always --package re5 --bin re5
Compiling embroidery_stitcher v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/embroidery_stitcher)
warning: function is never used: `svg_header`
--> embroidery_stitcher/src/lib.rs:2:1
|
2 | fn svg_header(w: i32, h: i32) -> String
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(dead_code)] on by default
Compiling re5 v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/re5)
error[E0603]: function `svg_header` is private
--> re5/src/main.rs:8:19
|
8 | let mut svg = embroidery_stitcher::svg_header(100,100);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I had to slap a pub on the front of that function
pub fn svg_header(w: i32, h: i32) -> String
Now it works.

How to use a local unpublished crate?

I've made a library:
cargo new my_lib
and I want to use that library in a different program:
cargo new my_program --bin
extern crate my_lib;
fn main {
println!("Hello, World!");
}
what do I need to do to get this to work?
They aren't in the same project folder.
.
├── my_lib
└── my_program
Hopefully this makes sense.
I thought I'd be able to override the path as per the Cargo guide, but it states
You cannot use this feature to tell Cargo how to find local unpublished crates.
This is when using the latest stable version of Rust (1.3).
Add a dependency section to your executable's Cargo.toml and specify the path:
[dependencies.my_lib]
path = "../my_lib"
or the equivalent alternate TOML:
[dependencies]
my_lib = { path = "../my_lib" }
Check out the Cargo docs for specifying dependencies for more detail, like how to use a git repository instead of a local path.
I was looking for an equivalent to mvn install. While this question is not quite a duplicate of my original question, anyone who stumbles across my original question and follows the link here will find a more complete answer.
The answer is "there is no equivalent to mvn install because you have to hard-code the path in the Cargo.toml file which will probably be wrong on someone else's computer, but you can get pretty close."
The existing answer is a bit brief and I had to flail around for a bit longer to actually get things working, so here's more detail:
/usr/bin/cargo run --color=always --package re5 --bin re5
Compiling re5 v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/re5)
error[E0432]: unresolved import `embroidery_stitcher`
--> re5/src/main.rs:5:5
|
5 | use embroidery_stitcher;
| ^^^^^^^^^^^^^^^^^^^ no `embroidery_stitcher` in the root
rustc --explain E0432 includes this paragraph that echos Shepmaster's answer:
Or, if you tried to use a module from an external crate, you may have missed
the extern crate declaration (which is usually placed in the crate root):
extern crate core; // Required to use the `core` crate
use core::any;
Switching from use to extern crate got me this:
/usr/bin/cargo run --color=always --package re5 --bin re5
Compiling embroidery_stitcher v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/embroidery_stitcher)
warning: function is never used: `svg_header`
--> embroidery_stitcher/src/lib.rs:2:1
|
2 | fn svg_header(w: i32, h: i32) -> String
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(dead_code)] on by default
Compiling re5 v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/re5)
error[E0603]: function `svg_header` is private
--> re5/src/main.rs:8:19
|
8 | let mut svg = embroidery_stitcher::svg_header(100,100);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I had to slap a pub on the front of that function
pub fn svg_header(w: i32, h: i32) -> String
Now it works.

Resources