How do I use a crate located in a different directory

My project's code was getting messy, so I took the time to organize it into modules. I needed to use a function that resided in a library file located in a different directory, so added the following line to my Cargo.toml dependencies section:

jt_lib = {path = "/home/camascounty/programming/rust/mine/jt_lib/src/"}

I then added the following line to the library file of the project on which I'm working:

    use crate::jt_lib::misc::*;

The compiler doesn't like it and throws the following errors:

error: failed to get `jt_lib` as a dependency of package `file_lib v0.1.0 (/home/camascounty/programming/rust/mine/file_lib)`

Caused by:
  failed to load source for dependency `jt_lib`

Caused by:
  Unable to update /home/camascounty/programming/rust/mine/jt_lib/src

Caused by:
  failed to read `/home/camascounty/programming/rust/mine/jt_lib/src/Cargo.toml`

Caused by:
  No such file or directory (os error 2)

I've double and triple-checked the path and it is correct. Tried adding the extern keyword and that just made it worse. So, what am I doing wrong?

Thanks for your help.

This tells you what's wrong, you need to put the path to Cargo.toml into the dependency declaration, like so:

jt_lib = {path = "/home/camascounty/programming/rust/mine/jt_lib"}

Thanks for the quick reply. :>)

Actually, that is one of the variations I've tried multiple times. Here is a copy of my Cargo.toml file in its current form:

[package]
name = "file_lib"
version = "0.1.0"
edition = "2021"

[dependencies]
# For use in creating menus.
dialoguer = { version = "0.11.0", features = ["completion"] }
console = "0.15.8"
jt_lib = {path = "/home/camascounty/programming/rust/mine/jt_lib/src"}

I had been using the line exactly as you suggested, multiple tries, then added ../src to the end of the path, since that is where the file actually resides. Made the change back again this morning, to check out your suggestion. Either way, it doesn't work. Still get the same errors.

Here's the error line when I delete the ../src from the path string:

error: failed to get `jt_lib` as a dependency of package `file_lib v0.1.0 (/home/camascounty/programming/rust/mine/file_lib)`

Can you please post more information?

  • The full error output from Cargo, not just one line
  • The contents of the file /home/camascounty/programming/rust/mine/jt_lib/Cargo.toml

We need much more context to be able to locate where the problem is.

Sure. Here you go. Here's the full error message:

camascounty@camas-county:~/programming/rust/mine/file_lib$ cargo build
error: failed to get `jt_lib` as a dependency of package `file_lib v0.1.0 (/home/camascounty/programming/rust/mine/file_lib)`

Caused by:
  failed to load source for dependency `jt_lib`

Caused by:
  Unable to update /home/camascounty/programming/rust/mine/jt_lib

Caused by:
  failed to parse manifest at `/home/camascounty/programming/rust/mine/jt_lib/Cargo.toml`

Caused by:
  no targets specified in the manifest
  either src/lib.rs, src/main.rs, a [lib] section, or [[bin]] section must be present
camascounty@camas-county:~/programming/rust/mine/file_lib$ 

Here's the Cargo.toml from the jt_lib directory:

[package]
name = "jt_lib"
version = "0.1.0"
edition = "2021"

[dependencies]
dialoguer = { version = "0.11.0", features = ["completion"] }
console = "0.15.8"

Appreciate your help. :>)

Cargo is telling you that jt_lib is not a valid package because it contains no targets. Since you intend it to be a library, you need a jt_lib/src/lib.rs file that defines the contents of the library — then the package will have a library target and you'll be past this error.

1 Like

I had renamed the jt_lib/src/lib.rs to jt_lib/src/jt_lib.rs in an attempt to get past this error. I have now changed it back to jt_lib/src/lib.rs, but the compiler still doesn't like it. So, here is the full slate of what things look like now.

The jt_lib/src directory looks like this:

camascounty@camas-county:~/programming/rust/mine/jt_lib/src$ dir
lib.rs

The use statement in the file_lib/src/lib.rs file looks like this:

    use crate::jt_lib::misc::*;

And the errors that result when I try to compile look like this:

   Compiling file_lib v0.1.0 (/home/camascounty/programming/rust/mine/file_lib)
error[E0433]: failed to resolve: could not find `jt_lib` in the crate root
  --> src/lib.rs:23:16
   |
23 |     use crate::jt_lib::misc::*;
   |                ^^^^^^ could not find `jt_lib` in the crate root

error[E0425]: cannot find function `activity_menu` in this scope
  --> src/lib.rs:55:22
   |
55 |         let choice = activity_menu(&fnames);
   |                      ^^^^^^^^^^^^^ not found in this scope

Some errors have detailed explanations: E0425, E0433.
For more information about an error, try `rustc --explain E0425`.
error: could not compile `file_lib` (lib) due to 2 previous errors

The Cargo.toml for the file_lib directory looks like this:

[package]
name = "file_lib"
version = "0.1.0"
edition = "2021"

[dependencies]
# For use in creating menus.
dialoguer = { version = "0.11.0", features = ["completion"] }
console = "0.15.8"
jt_lib = {path = "/home/camascounty/programming/rust/mine/jt_lib/"}

And the Cargo.toml for the jt_lib directory looks like this:

[package]
name = "jt_lib"
version = "0.1.0"
edition = "2021"

[dependencies]
dialoguer = { version = "0.11.0", features = ["completion"] }
console = "0.15.8"

Whew! I've spent hours trying to solve this. Thanks for helping me get it fixed.

This is the wrong path to refer to a different crate; it should be either one of:

use ::jt_lib::misc::*;
use jt_lib::misc::*;

(Also, this path assumes that jt_lib/src/lib.rs contains a mod misc {}, or mod misc;. I don't know whether you've done that.)

1 Like

Thank you! It works with either one of those. I find the line

use ::jt_lib::misc::*;

to be somewhat odd. Why the leading ::? I also don't understand why the crate keyword caused me trouble.

@kpreid Thanks for hanging in there with me this morning. :grinning:

1 Like

The leading :: is an explicit way of referring to the top level namespace where all the crates are. When you add a crate as a dependency (no matter if it's from crates.io, git or your local file system), it gets added to that top level namespace. The :: is usually not necessary, unless it happens to be ambiguous. There may be other cases I'm forgetting.

The crate keyword is special and always refers to the current crate, usually called the crate root. This is typically your lib.rs or bin.rs. When you write crate::something, you are referring to the module something that you have declared in your crate root file, not the previously mentioned top level namespace.

The logical structure looks kind of like this:

crate <-- this is your crate (you are here)
    my_module1
    my_module2
my_other_crate
    my_other_module
core
std
serde
other_crate
and_so_on

So to bring my_other_module into scope, you specify use my_other_crate::my_other_module.

2 Likes

Thanks. That clears it up. :>)

1 Like