toml build dependencies rust rust-cargo

build - rust cargo toml



Obtenga una lista de dependencias activas y sus versiones durante la "construcción de carga" (1)

Algunas cajas ofrecen una const &str conversión de const &str , y otras no. Para tener una solución general, necesito una lista de todas las dependencias y sus versiones conocidas y utilizadas por cargo build durante la compilación, así que puedo construir mis propias compilaciones. Esta es mi propia versión y todas las versiones con las que compilé -Debug salida.

¿Es posible obtener una lista de todas las dependencias y su versión en build.rs ?

Cargo.lock parece ser una buena fuente. ¿Es realmente Cargo.lock analizar Cargo.lock en build.rs ? ¿Se garantiza que se actualizó a lo que Cargo realmente usa y se escribe en el disco?


Mi propia respuesta, resuelta al analizar Cargo.lock . A continuación, se incluye una lista de dependencias y dependencias de dependencias: cada casilla que terminó vinculándose de alguna manera (lto además).

En Cargo.toml :

[package] name = "mycrate" version = "0.1.0" authors = ["John Doe"] build = "build.rs" [build-dependencies] toml = "0.2"

En build.rs :

extern crate toml; use std::env; use std::fs; use std::path; use std::io::{Read, Write}; fn main() { // Read Cargo.lock and de-toml it let mut lock_buf = String::new(); fs::File::open("Cargo.lock").unwrap().read_to_string(&mut lock_buf).unwrap(); let lock_toml = toml::Parser::new(&lock_buf).parse().unwrap(); // Get the table of [[package]]s. This is the deep list of dependencies and dependencies of // dependencies. let mut packages = Vec::new(); for package in lock_toml.get("package").unwrap().as_slice().unwrap() { let package = package.as_table().unwrap(); packages.push((package.get("name").unwrap().as_str().unwrap(), package.get("version").unwrap().as_str().unwrap())); } packages.sort(); // Write out the file to be included in the module stub let out_dir = env::var("OUT_DIR").unwrap(); let mut versions_file = fs::File::create(&path::Path::new(&out_dir).join("versions.include")).unwrap(); versions_file.write(format!("pub const BUILD_DEPS: [(&''static str, &''static str); {}] = [", packages.len()).as_ref()).unwrap(); for package in packages { versions_file.write(format!("(/"{}/", /"{}/"),/n", package.0, package.1).as_ref()).unwrap(); } versions_file.write("];".as_ref()).unwrap(); }

En src/versions.rs :

//! Information about the build-environment // More info from env!() and friends go here include!(concat!(env!("OUT_DIR"), "/versions.include"));

En src/main.rs o donde sea necesario:

mod versions; fn main() { println!("I was built using {}", versions::BUILD_DEPS.iter().map(|&(ref pkg, ref ver)| format!("{} {}", pkg, ver)).collect::<Vec<_>>().join(", ")); }

La salida es entonces como

Fui construido usando android_glue 0.2.1, bitflags 0.3.3, bitflags 0.4.0, bitflags 0.6.0, bitflags 0.7.0, bloque 0.1.6, byteorder 0.5.3, bytes 0.3.0, cfg-if 0.1.0 , cgl 0.1.5, cgmath 0.7.0, clippy 0.0.104 ...

Por supuesto, podríamos construir una representación tipo cadena en tiempo de compilación, sin embargo, separarla ordenadamente nos da la oportunidad de analizar esta información en tiempo de ejecución. Hasta donde puedo ver, esto funciona si Cargo.lock no está presente: Cargo siempre lo genera antes de que build.rs se ejecute.