How to use a local unpublished crate? - rust

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.

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

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.

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.

cannot find function `get_platform` in sdl2 0.31.0

I'm using the latest version of sdl2 (0.31.0) but cannot access get_platform:
extern crate sdl2;
pub fn main() {
println!("{}", sdl2::get_platform());
}
$ cargo run
Compiling repro v0.1.0 (file:///private/tmp/repro)
error[E0425]: cannot find function `get_platform` in module `sdl2`
--> src/main.rs:4:30
|
4 | println!("{}", sdl2::get_platform());
| ^^^^^^^^^^^^ not found in `sdl2`
I tried with use sdl2::*; and with cargo +nightly run, but neither removed the error.
The documentation you are reading is is not for the version you are using. Build it yourself (cargo doc --open) or view it on docs.rs.
That function was added recently and has not been released yet. Perhaps you should file an issue for the authors of the crate to let them know that having documentation that doesn't correspond to any released code is confusing.
In the meantime, you can use a git dependency if you really need it.

Resources