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

1

9

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?

Outbid answered 12/1, 2017 at 16:37 Comment(4)
Maybe cargo outdated might be usefull?Nazi
The cargo lock file has all this information but I'm not sure at which point in the build process it is generated.Aeroballistics
Cargo.lock would be a good source but is it actually sound to parse Cargo.lock in build.rs? Is it guaranteed to be up to date and written to disk before build.rs is run?Outbid
That's something I'm unsure of and wouldn't really want to rely on :)Aeroballistics
O
1

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.

Ostend answered 14/9, 2023 at 21:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.