How to use nonstandard crate with path?

for example:

extern crate path/winapi;

comparing to Go, Go uses system environment variable point to, for example,d:\code\go where was src folder and subfolders where import was searched.
In thread https://users.rust-lang.org/t/create-a-window-use-winapi-ask-for-help/7914 is example using winapi, but where is searched this crate?

In some languages (like Go and Python), there is a global "storage" of all installed packages (usually pointed to by some environmental variable, like PYTHON_PATH, GO_PATH, classpath), so when you name a thing, compiler/interpreter will search for it in the storage.

In general, this is not the case in Rust. When you write extern crate foo, you need to pass --extern foo=/path/to/foo when you invoke the compiler. Compiler does not search for libraries (in general), you must explicitly tell it where to find what. This is more work (a flag for each external dependency instead of a single searchpath), but it allows for some powerful features, like linking in two versions of the same library simultaneously (--extern foo_1=/path/to/foo/v1/ --extern foo_2=/path/to/foo/v2/).

Luckily, all this work of specifying dependencies is done by the Rust package manager/build tool Cargo.

When you add winapi = "0.2" to the dependencies section of Cargo.toml, Cargo will take care of downloading the source code and providing the necessary flags:

$ cargo build --verbose
  Updating registry `https://github.com/rust-lang/crates.io-index`
 Downloading winapi v0.2.8
   Compiling winapi v0.2.8
     # Compile the winapi. Note that `--out-dir` and `-C extra-filename` flags instruct rustc where to put the compiled library
     Running `rustc --crate-name winapi /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/winapi-0.2.8/src/lib.rs --crate-type lib --emit=dep-info,link -C debuginfo=2 -C metadata=a5898d7aceb63fac 
        -C extra-filename=-a5898d7aceb63fac --out-dir /home/user/trash/dep/target/debug/deps 
        -L dependency=/home/user/trash/dep/target/debug/deps --cap-lints allow`
   Compiling dep v0.1.0 (file:///home/user/trash/dep)
     # Note how Cargo passes `--extern` with the filename from the previous step
     Running `rustc --crate-name dep src/lib.rs --crate-type lib --emit=dep-info,link -C debuginfo=2 -C metadata=36885cbee95dd090 -C extra-filename=-36885cbee95dd090 --out-dir /home/user/trash/dep/target/debug/deps -L dependency=/home/user/trash/dep/target/debug/deps 
        --extern winapi=/home/user/trash/dep/target/debug/deps/libwinapi-a5898d7aceb63fac.rlib`
    Finished dev [unoptimized + debuginfo] target(s) in 0.61 secs

1 Like

for example , how to compile sample "menu.rs" from rust_minifb crate?
I have compiled rust_minifb and target is libminifb.rlib and folder deps/ with libuser32-4115029c89e6e98c.rlib and others.
I am creating mk.bat :
rustc menu.rs --extern minifb=..\target\debug\libminifb.rlib --extern user32=..\target\debug\deps\libuser32-4115029c89e6e98c.rlib
but is error:
error[E0463]: can't find crate for user32 which minifb depends on

You don't need to invoke rustc manually. Everything should be handled by Cargo.

If you want to compile literally this example, you need to clone the minifb repo and use cargo build:

$ git clone https://github.com/emoon/rust_minifb.git
$ cd rust_minifb
$ cargo build --example menu

If you are starting your own project that uses minifb, you need the following steps

$ cargo new --bin mini_project
$ cd mini_project
# edit Cargo.toml and add `minifb = "*"` to dependencies
# copy paste examples/menu.rs from minifb to src/main.rs
$ cargo run

Thanks, it works! From what cargo know where is minifb? Crate minifb is downloading from net? because after "cargo run" it write "downloading minifb", but only one - if I deleted target folder and type "cargo run" then is only compiling

It downloads it from https://crates.io and caches in ~/.cargo/registry/

How to use my own library not published to crates.io? Only I have directory?

Everything about dependencies is explained in the docs: Page Moved :slight_smile:

You can use path dependencies like my_lib = { path = "../libs/my_lib" }.

2 Likes