Skip to main content

memtrace_utils/
common.rs

1use anyhow::Context;
2use std::fs::File;
3use std::io::BufWriter;
4use std::path::Path;
5use std::{fs, io};
6
7pub fn download_lib_if_needed(
8    lib_dir: impl AsRef<Path>,
9    lib_version: &str,
10) -> anyhow::Result<String> {
11    if lib_dir.as_ref().is_file() {
12        anyhow::bail!("lib_dir is not a directory");
13    }
14
15    #[cfg(target_os = "macos")]
16    let ext = "dylib";
17    #[cfg(target_os = "linux")]
18    let ext = "so";
19
20    let lib_file = lib_dir
21        .as_ref()
22        .join(format!("libmemtrace_{}.{ext}", lib_version));
23
24    if lib_file.exists() {
25        return Ok(lib_file.to_str().unwrap().to_string());
26    }
27
28    println!("Loading libmemtrace version {}", lib_version);
29
30    fs::create_dir_all(lib_dir).context("failed to create dirs")?;
31
32    let mut response = reqwest::blocking::get(format!(
33        "https://github.com/blkmlk/memtrace-lib/releases/download/{}/libmemtrace_lib.{ext}",
34        lib_version
35    ))
36    .with_context(|| format!("failed to download libmemtrace_lib.{ext}"))?;
37
38    if !response.status().is_success() {
39        anyhow::bail!(
40            "failed to download libmemtrace_lib.{ext}. status: {}",
41            response.status()
42        );
43    }
44
45    let mut out_file =
46        BufWriter::new(File::create(&lib_file).context("failed to create output file")?);
47
48    io::copy(&mut response, &mut out_file).context("failed to write output file")?;
49
50    println!(
51        "Successfully loaded libmemtrace_lib.{ext} version {}",
52        lib_version
53    );
54
55    Ok(lib_file.to_str().unwrap().to_string())
56}
57