215

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

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Andre S.
  • 2,372
  • 2
  • 14
  • 9

2 Answers2

286

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.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • 14
    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? – David Roundy Jun 19 '17 at 22:21
  • 1
    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. – Paul-Sebastian Manole Sep 17 '18 at 14:38
  • 15
    @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 :) – Connie Hilarides Feb 01 '19 at 19:52
  • Detailed documentation is available at https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#specifying-path-dependencies – David J. Sep 13 '19 at 22:07
  • 7
    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? – Ruben Kostandyan Nov 23 '19 at 21:36
  • 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? – FreelanceConsultant May 12 '23 at 11:02
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.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Mutant Bob
  • 3,121
  • 2
  • 27
  • 52