2017-01-12 16 views
5

Một số thùng cung cấp một chuỗi const &str-phiên bản pub, một số thì không. Để có giải pháp chung, tôi cần danh sách tất cả các phụ thuộc và phiên bản của chúng được biết và sử dụng bởi cargo build trong khi biên dịch để tôi có thể tự tạo const &str của riêng mình Đây là phiên bản của riêng tôi và tất cả các phiên bản tôi đã biên dịch với -Debug đầu ra.Lấy danh sách các phụ thuộc hoạt động và các phiên bản của chúng trong quá trình "xây dựng hàng hóa"

Có thể nhận danh sách tất cả các phụ thuộc và phiên bản của chúng trong build.rs không?

Cargo.lock có vẻ là một nguồn tốt. Có thực sự là âm thanh để phân tích cú pháp Cargo.lock trong build.rs? Nó được đảm bảo đã được cập nhật cho những gì Cargo thực sự sử dụng và ghi vào đĩa?

+0

Có thể 'hàng hóa đã lỗi thời 'có thể hữu ích? – phimuemue

+0

Tệp khóa hàng có tất cả thông tin này nhưng tôi không chắc chắn tại điểm nào trong quá trình xây dựng được tạo. – squiguy

+0

'Cargo.lock' sẽ là một nguồn tốt nhưng thực sự là âm thanh để phân tích' Cargo.lock' trong 'build.rs'? Có đảm bảo được cập nhật và ghi vào đĩa trước khi 'build.rs' được chạy không? – user2722968

Trả lời

1

Câu trả lời của riêng tôi, được giải quyết bằng cách phân tích cú pháp Cargo.lock. Sau đây cho chúng ta một danh sách các phụ thuộc và phụ thuộc của các phụ thuộc - mỗi thùng mà kết thúc bằng cách liên kết bằng cách nào đó (lto bên cạnh).

Trong Cargo.toml:

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

[build-dependencies] 
toml = "0.2" 

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

Trong src/versions.rs:

//! Information about the build-environment 

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

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

Trong src/main.rs hoặc bất cứ nơi nào cần thiết:

mod versions; 

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

Output là sau đó như

tôi được xây dựng bằng android_glue 0.2.1, bitflags 0.3.3, 0.4.0 bitflags, bitflags 0.6.0, bitflags 0.7.0, 0.1.6 chặn, byteorder 0.5.3, byte 0.3.0, cfg-if 0.1.0, cgl 0.1.5, cgmath 0.7.0, clippy 0.0.104 ...

Tất nhiên, chúng ta có thể tạo chuỗi giống như biểu diễn tại thời gian biên dịch, mặc dù nó được phân tách gọn gàng tạo cơ hội phân tích cú pháp thông tin này trong thời gian chạy. Theo như tôi có thể thấy điều này hoạt động nếu Cargo.lock không có mặt: Hàng hóa luôn tạo ra trước khi build.rs được chạy.

Các vấn đề liên quan