user2722968
user2722968

Reputation: 16535

Get list of active dependencies and their versions during "cargo build"

Some crates offer a pub const &str-version string, some do not. To have a general solution, I need a list of all dependencies and their versions as known to and used by cargo build during compilation so I can build my own const &str of This is my own version and all the versions I was compiled with-Debug output.

Is it possible to get a list of all dependencies and their version in build.rs ?

Cargo.lock seems to be a good source. Is it actually sound to parse Cargo.lock in build.rs? Is it guaranteed to have been updated to what Cargo actually uses and written to disk?

Upvotes: 9

Views: 4084

Answers (1)

Zombie_Pigdragon
Zombie_Pigdragon

Reputation: 354

There's a crate for this: build-info (lib.rs, docs.rs).

It doesn't seem to be able to generate a 'static str including dependency info on its own, but it does automatically parse Cargo.lock and include the relevant info into the final binary, with a similar effect.

Sample code (build-info 0.0.32)

This code is a little bit more complicated than you may need it to be, if you don't want to include recursive dependencies.

build.rs

fn main() {
    build_info_build::build_script().collect_dependencies(true);
}

main.rs

use std::collections::BTreeSet;

build_info::build_info!(fn build_info);

/// Collect all of the dependencies of this workspace into a single set.
fn get_dependencies() -> BTreeSet<(&'static str, &'static build_info::semver::Version)> {
    // called recursively on each of the dependencies in the tree
    fn visit(
        info: &'static build_info::CrateInfo,
        set: &mut BTreeSet<(&'static str, &'static build_info::semver::Version)>,
    ) {
        set.insert((&info.name, &info.version));
        for dep in &info.dependencies {
            visit(dep, set);
        }
    }
    let mut set = BTreeSet::new();
    let root_info = &build_info().crate_info;
    visit(root_info, &mut set);
    set
}

fn main() {
    for (name, version) in get_dependencies() {
        println!("{} {}", name, version);
    }
}

Alternative Solutions

Check out cargo-audit and cargo-auditable for a security-oriented solution to the same problem, the former even works to some extent on programs that don't natively include this feature. Unfortunately, while cargo audit bin can be used to check for known security vulnerabilities in compiled Rust programs, I don't see any flags that print the list of libraries it recovers.

Upvotes: 2

Related Questions