[Solved] How to use local unpublished crate

Trying to use a utility in more than one project, and can't see how to set up Cargo.toml for it.

Directory structure:

├── projects
       ├── rust
       │     ├── stuff
       │           ├── main_proj
       └── utils
             ├──sub_proj

How should the Cargo.toml for main_proj read, to allow it to access sub_proj ?
The solutions in the cargo documentation mostly seem to need git, which I am not using.

You can probably use path attribute, but I'm not too sure; your example isn't very clear:

sub_proj = {path = "../../utils/sub_proj"}

Thanks! I tried that, and got error

extern crate sub_proj;
^^^^^^^^^^^^^^^^^^^^^ can't find crate

If I remove the extern crate line, I get

use sub_proj;
^^^^^^^^^^^^^ no 'sub_proj' in the root

Hmm, would you mind posting what you've put into your Cargo.toml file for main_proj?


Also, you don't really need to use extern crate anymore, rust 2018 got rid of it unless you're importing procedural macros.

This is what I have tried, with variants:

[package]
name = "main_proj"
version = "0.1.0"
authors = ["austin"]

[dependencies]
x11 = "^0"
libc = "^0"
sub_proj = { version = "^0", path = "../../utils/sub_proj" }

And what's in your sub_proj Cargo.toml? Also, can run run cargo build --verbose?

1 Like

Cargo.toml for sub_proj:

[package]
name = "sub_proj"
version = "0.1.0"
authors = ["austin"]

[dependencies]
config = "^0"

Running with --verbose gave the usual errors, followed by:

Caused by:
  process didn't exit successfully: `rustc --crate-name main_proj src/main.rs --color always --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=eb51c654374ab922 -C extra-filename=-eb51c654374ab922 --out-dir /.../projects/rust/stuff/main_proj/target/debug/deps -C incremental=/.../projects/rust/stuff/main_proj/target/debug/incremental -L dependency=/.../projects/rust/stuff/main_proj/target/debug/deps --extern libc=/.../projects/rust/stuff/main_proj/target/debug/deps/liblibc-8a23d7c4fb5bbf6b.rlib --extern toml=/.../projects/rust/stuff/main_proj/target/debug/deps/libtoml-265f618687463bd7.rlib --extern x11=/.../projects/rust/stuff/main_proj/target/debug/deps/libx11-9931f1c645e85ac4.rlib -L native=/usr/lib/x86_64-linux-gnu -L native=/usr/lib/x86_64-linux-gnu -L native=/usr/lib/x86_64-linux-gnu -L native=/usr/lib/x86_64-linux-gnu` (exit code: 1)

In other words, no mention of sub_proj at all.
Puzzling.

1 Like

Aha! You're not using rust 2018, try that because that made some major changes to the module system (Like removing the need to include the extern crate statement)


Change it to add this line under [package] in your Cargo.tomls

edition = "2018"

@OptimisticPeach if cargo isn't passing the dependency to rustc, no amount of tweaking the edition should fix the issue.

1 Like

@Austin something must be wrong with your dependency setup/filesystem layout. Here's a working example:

# dep/Cargo.toml

[package]
name = "dep"
version = "0.1.0"
edition = "2018"
// dep/src/lib.rs

pub fn hello() {
    println!("hello")
}
# Cargo.toml

[package]
name = "deptest"
version = "0.1.0"
edition = "2018"

[dependencies]
dep = { path = "dep" }
// src/main.rs

fn main() {
    dep::hello();
}
$ cargo run --verbose
   Compiling dep v0.1.0 (/tmp/deptest/dep)
     Running `rustc --edition=2018 --crate-name dep dep/src/lib.rs --color always
              --crate-type lib --emit=dep-info,link -C debuginfo=2 -C metadata=11c2843ee8b47c83
              -C extra-filename=-11c2843ee8b47c83 --out-dir /tmp/deptest/target/debug/deps
              -C incremental=/tmp/deptest/target/debug/incremental
              -L dependency=/tmp/deptest/target/debug/deps`
   Compiling deptest v0.1.0 (/tmp/deptest)
     Running `rustc --edition=2018 --crate-name deptest src/main.rs --color always
              --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=f4ffed667807d29b
              -C extra-filename=-f4ffed667807d29b --out-dir /tmp/deptest/target/debug/deps
              -C incremental=/tmp/deptest/target/debug/incremental
              -L dependency=/tmp/deptest/target/debug/deps 
             --extern dep=/tmp/deptest/target/debug/deps/libdep-11c2843ee8b47c83.rlib`
    Finished dev [unoptimized + debuginfo] target(s) in 0.33s
     Running `target/debug/deptest`
hello

Notice the --extern dep=... in the second invocation of rustc.

OK, added the edition = "2018", compiler said "only for nightly", so switched default toolchain to nightly and did rustup update. Now it doesn't object to extern crate lines being removed, but still gives the "no external crate" error on the use statement. :confused:

@jethrogb: in you example, the path to the dependency has no .. components; this corresponds with many of the examples I've found online. Is that something which confuses cargo maybe?

Relative paths with .. should work just fine. If Cargo can't find a dependency, it will complain before it even tries to run rustc.

1 Like

@jethrogb: Aaargh! Just checked your example more closely, and noticed the bit about sub_proj source being lib.rs instead of main.rs. Must have slept through that part of The Book! :blush:
I should perhaps have mentioned that I'm quite new to Rust.

All good now!

@jethrogb and @OptimisticPeach: many thanks to you for your help; you are legends! :star_struck:

1 Like

Ah, very interesting. I've filed a bug report for this case.