Cc linker not finding dependency crate

warning - I'm new to RUST.

Context

Trying to do a cargo build on a proprietary project let's call it project AAA. It depends on another proprietary rust project BBB stored in git repo.
Project BBB makes C bindings.

Cargo.toml of project AAA has line like this:

b = { git = "https://github.com/proprietary/BBB" }

project BBB produces library libbbb.so having following line in corresponding Cargo.toml

[lib]
name = "something"
path = "src/lib.rs"

and build = "build.rs"

and something is included in one of project AAA res files like this:
extern crate something;

Problem

runninng cargo build on project AAA results in

"cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-Wl,--eh-frame-hdr" "-L" 
...
  = note: /usr/bin/ld: cannot find -lbbb
          collect2: error: ld returned 1 exit status

If path to project BBB is added to LIBRARY_PATH then cargo build succeeds.
Path to the BBB project looks like this: /root/.cargo/git/checkouts/something-60687b7536060c70/3f8bc66/

Question

How to properly make dependency project BBB library crate visible to project AAA?

I don't know the exact details, but you need to use a build script to inform the compiler of the location of the things you need to link. I think the build script needs to print a line like the following:

cargo:rustc-link-search=native=<dir>

See more in Using C libraries in Rust: make a sys crate

Thank you @alice for a prompt answer.

but how would this instruction look if the dependency BBB project is managed by cargo and build in a cache directory like this /root/.cargo/git/checkouts/something-60687b7536060c70/3f8bc66/ ? I don't know the path in advance, unless there are some env/cargo variables...

I'm pretty certain that the path is going to available as an environment variable when running the build script. Maybe not for the AAA crate, but it should be there for the BBB crate's build script.

Tried THIS snippet to get environment vars, was hoping for something like THIS . Unfortunately no env vars hold path to a dependency project path.

FYI

adding build.sh to AAA project containg

fn main() {
    println!("cargo:rustc-link-search={}", "/root/.cargo/git/checkouts/something-60687b7536060c70/3f8bc66/");
}

works similarly as adding path to env var LIBRARY_PATH

You are linking to a pretty old version of the build script documentation. The up-to-date version is here.

I will note that it says this:

In general, it is best to avoid creating dynamic libraries in a build script (using existing system libraries is fine).

Are you sure that it shouldn't be either installed as a system library, or linked statically?

Either would probably do. Static linking should be easier (form C experience perspective). I'm bit reluctant making significant changes to inherited code as a first time rust user. But apparently there is no other way but to fix/change stuff. :slight_smile:

Adding

    println!("cargo:rustc-link-search={}", env::var("CARGO_MANIFEST_DIR").unwrap());

to the build.rs of the BBB project solved the problem. My mistake was trying to change parent project when child project needed fixing. So @alice indeed there was an env variable after all and my understanding of cargo build process was wrong. Thanks for assistance.

1 Like