How to use a local unpublished crate?
Asked Answered
P

2

240

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

Pluck answered 8/10, 2015 at 21:1 Comment(0)
G
319

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.

Gompers answered 8/10, 2015 at 21:8 Comment(6)
Is there a way to use a local crate myself (for development) while leaving Cargo.toml referring to crates.io so others can also build my code?Boyles
Not possible by default at the moment. You can however work on a local branch, replace Cargo.toml with local dependency references (or mixed references), and before you merge or during, revert to or keep the main Cargo.toml file.Bernal
@DavidRoundy if you're still looking for an answer, it's now possible to do what you're asking. You can specify both version and path for a dependency and it will strip the path part out when you publish it :)Izanagi
Detailed documentation is available at doc.rust-lang.org/cargo/reference/…Forespeak
Is it possible to do the same but with git instead of version? Something like this my_lib = { path = "...", git = "..." } so that I can use my local copy during development and the remote git when someone clones the repo and tries to compile the program?Haze
There should really be a better way to do this other than using a relative path, which is something which could change. If one crate depends on another, and both are in the same workspace is there no way to specify a dependency without using a relative path?Sylviesylvite
F
0

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.

Fanatic answered 5/6, 2019 at 19:23 Comment(2)
And now this answer is a miniature article: purplefrog.com/~thoth/rust-external-librariesFanatic
Also, extern crate may only be used in edition 2015 or in other cases, since cargo itself already links these crates.Nisan

© 2022 - 2024 — McMap. All rights reserved.