2017-01-12 2 views
5

Einige Kisten bieten eine Kneipe const &str -Version Zeichenfolge, einige nicht. Um eine allgemeine Lösung zu haben, brauche ich eine Liste aller Abhängigkeiten und deren Versionen, wie sie von cargo build während der Kompilierung bekannt sind und verwendet werden, so dass ich meine eigene const &str von erstellen kann. Dies ist meine eigene Version und alle Versionen, die ich kompiliert wurde mit -Debug Ausgabe.Liste der aktiven Abhängigkeiten und ihrer Versionen während "Fracht bauen"

Ist es möglich, eine Liste aller Abhängigkeiten und ihrer Version in build.rs zu erhalten?

Cargo.lock scheint eine gute Quelle zu sein. Ist es wirklich vernünftig, Cargo.lock in build.rs zu analysieren? Ist es garantiert, dass Cargos aktualisiert wurde, was Cargo tatsächlich benutzt und auf die Festplatte geschrieben hat?

+0

Vielleicht könnte 'cargo veraltet' nützlich sein? – phimuemue

+0

Die Frachtsperre-Datei enthält all diese Informationen, aber ich bin nicht sicher, an welcher Stelle im Build-Prozess generiert wird. – squiguy

+0

'Cargo.lock' wäre eine gute Quelle, aber ist es wirklich gut,' Cargo.lock' in 'build.rs' zu analysieren? Ist es garantiert auf dem neuesten Stand zu sein und auf die Festplatte geschrieben zu werden, bevor 'build.rs' ausgeführt wird? – user2722968

Antwort

1

Meine eigene Antwort, gelöst durch Parsing Cargo.lock. Das Folgende gibt uns eine Liste von Abhängigkeiten und Abhängigkeiten von Abhängigkeiten - jede Kiste, die irgendwie verlinkt wurde (lto neben).

In Cargo.toml:

[package] 
name = "mycrate" 
version = "0.1.0" 
authors = ["John Doe"] 
build = "build.rs" 

[build-dependencies] 
toml = "0.2" 

In 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(); 
} 

In src/versions.rs:

//! Information about the build-environment 

// More info from env!() and friends go here 

include!(concat!(env!("OUT_DIR"), "/versions.include")); 

In src/main.rs oder wo auch immer benötigt:

mod versions; 

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

Ausgang ist dann wie

I gebaut wurde mit android_glue 0.2.1, 0.3.3 bitflags, bitflags 0.4.0, bitflags 0.6.0, 0.7.0 bitflags, Block 0.1.6, byteorder 0.5.3 Bytes 0.3.0, cfg-wenn 0.1.0, 0.1.5 CGL, cgmath 0.7.0, clippy 0.0.104 ...

natürlich haben wir ein Saiten- bauen könnte Eine ähnliche Darstellung zur Kompilierungszeit, wenn sie sauber getrennt ist, bietet die Möglichkeit, diese Informationen zur Laufzeit zu analysieren. Soweit ich das sehen kann funktioniert das wenn Cargo.lock nicht vorhanden ist: Cargo generiert es immer bevor build.rs läuft.

Verwandte Themen