Does cargo run a build script for bin targets too?

I'd like to build a binary executable linked with my own native library. I have:

[package]
ā€¦
build = "src/build.rs"

[lib]
name = "foo"

[[bin]]
name = "foo"
path = "src/bin.rs"

build.rs creates libfoo.a and prints cargo:rustc-link-lib=static=foo, etc. Everything builds and links fine for the library part (cargo build --lib), but the build script doesn't seem to be invoked for cargo build --bin (linking fails with missing symbols and linker command doesn't include directives from build.rs).

Is that expected? Can a built script be used for both lib and bin targets?

I'm developing a utility that could be used via a Rust API or via CLI, so I thought it'd be nice to have it as one project/crate. I know I could work around it by moving lib to a separate crate, but can I tell cargo to link the native library (or even the Rust library containing the native part), with the binary executable it produces?

2 Likes

Currently build scripts are just run once, so they'll need to produce all output necessary for any binary or library targets that the package has.

I thought my script did that. It always prints directives that all of my targets must use:

println!("cargo:rustc-link-search=native={}", destdir);
println!("cargo:root={}", destdir);
println!("cargo:rustc-link-lib=static=foo");

but cargo seems to use these directives only when building the lib target. Is that a bug? Are there other directives for bin targets?

Is there a documentation other than Page Moved ?

Ah yeah Cargo will only link native libraries once and then it assumes the binary links to the library. Currently there's not a way to tell Cargo that the binary doesn't link to the library so the native library should be linked twice.

2 Likes

So @kornel @alexcrichton what the proper way to handle situation when
you have "lib" create, with dependency on extern "C" library, and you want to
add [[bin]] into this crate?

Link the binary with your own Rust library (extern crate yourlib).

I think moving the C linking to a separate crate (like -sys crates) and explicitly depending on it in both lib and bin might also work.

Sorry for noise, the problem was in empty ".a" library. All other steps were right.