Мы можем использовать скрипт сборки , чтобы убедиться, что включенный файл существует до того, как наш пакет попытается его включить. Однако сценарии сборки могут записывать только в уникальный выходной каталог текущей сборки, поэтому мы не можем просто создать отсутствующие входные файлы непосредственно в исходном каталоге.
ошибка: не удалось проверить архив пакета
Причина:
Исходный каталог был изменен на build.rs
во время cargo publish
. Скрипты сборки не должны ничего изменять за пределами OUT_DIR
.
Вместо этого наш скрипт сборки может создать файл для включения в каталог сборки, скопировав исходные данные, если он существует, и мы можем обновить код нашего пакета, чтобы включить эти данные из каталога сборки, а не из каталога исходного кода. , Путь сборки будет доступен в переменной окружения OUT_DIR
во время сборки, поэтому мы можем получить к нему доступ из std::env::var("OUT_DIR")
в нашем скрипте сборки и из env!("OUT_DIR")
в остальной части нашего пакета.
//! build.rs
use std::{fs, io};
fn main() {
let out_dir = std::env::var("OUT_DIR").unwrap();
fs::create_dir_all(&format!("{}/src/data", out_dir))
.expect("unable to create data directory");
let path = format!("src/data/computed.bin", name);
let out_path = format!("{}/{}", out_dir, path);
let mut out_file = fs::OpenOptions::new()
.append(true)
.create(true)
.open(&out_path)
.expect("unable to open/create data file");
if let Ok(mut source_file) = fs::File::open(&path) {
io::copy(&mut source_file, &mut out_file).expect("failed to copy data after opening");
}
}
//! src/foo.rs
fn precomputed_data() -> Option<&'static [u8]> {
let data = include_bytes!(concat!(env!("OUT_DIR"), "/src/data/computed.bin")).as_ref();
if !data.is_empty() {
Some(data)
} else {
None
}
}