diff --git a/.github/workflows/intel-mkl-tool.yml b/.github/workflows/intel-mkl-tool.yml index fab9c293..ed49bce4 100644 --- a/.github/workflows/intel-mkl-tool.yml +++ b/.github/workflows/intel-mkl-tool.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.61.0 + toolchain: 1.77.0 profile: minimal default: true override: true @@ -71,7 +71,7 @@ jobs: - uses: actions-rs/toolchain@v1 with: - toolchain: 1.61.0 + toolchain: 1.77.0 profile: minimal default: true override: true diff --git a/intel-mkl-src/Cargo.toml b/intel-mkl-src/Cargo.toml index ae88cfaf..7347ad5d 100644 --- a/intel-mkl-src/Cargo.toml +++ b/intel-mkl-src/Cargo.toml @@ -32,6 +32,9 @@ mkl-dynamic-ilp64-seq = [] [build-dependencies] anyhow = "1.0.58" ocipkg = "0.2.8" +flate2 = "1.0.28" +log = "0.4.21" +tar = "0.4.40" [build-dependencies.intel-mkl-tool] path = "../intel-mkl-tool" diff --git a/intel-mkl-src/build.rs b/intel-mkl-src/build.rs index 8bfd9ed5..953df678 100644 --- a/intel-mkl-src/build.rs +++ b/intel-mkl-src/build.rs @@ -22,7 +22,11 @@ use anyhow::Result; use intel_mkl_tool::*; -use std::str::FromStr; +use ocipkg::{ + distribution::{get_layer_bytes, MediaType}, + ImageName, +}; +use std::{env, fs, path::PathBuf, str::FromStr}; macro_rules! def_mkl_config { ($cfg:literal) => { @@ -67,18 +71,78 @@ fn main() -> Result<()> { // unless user set `LD_LIBRARY_PATH` explictly. if cfg.link == LinkType::Static { if cfg!(target_os = "linux") { - let _ = ocipkg::link_package(&format!( + link_package(&format!( "ghcr.io/rust-math/rust-mkl/linux/{}:2020.1-3038006115", MKL_CONFIG - )); + ))?; } if cfg!(target_os = "windows") { - let _ = ocipkg::link_package(&format!( + link_package(&format!( "ghcr.io/rust-math/rust-mkl/windows/{}:2022.0-3038006115", MKL_CONFIG - )); + ))?; } } Ok(()) } + +/// Copied from ocipkg to effectively backport the addition made in this commit upstream: +/// https://github.com/termoshtt/ocipkg/commit/7b382892834e577ccf65dd7b368f796903722f63 +fn link_package(image_name: &str) -> Result<()> { + const STATIC_PREFIX: &str = if cfg!(target_os = "windows") { + "" + } else { + "lib" + }; + + let image_name = ImageName::parse(image_name)?; + + let mut dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + if let Some(port) = image_name.port { + dir.push(format!("{}__{}", image_name.hostname, port)); + } else { + dir.push(&image_name.hostname); + } + dir.push(image_name.name.as_str()); + dir.push(format!("__{}", image_name.reference)); + + if !dir.exists() { + let blob = get_layer_bytes(&image_name, |media_type| { + match media_type { + MediaType::ImageLayerGzip => true, + // application/vnd.docker.image.rootfs.diff.tar.gzip case + MediaType::Other(ty) if ty.ends_with("tar.gzip") => true, + _ => false, + } + })?; + let buf = flate2::read::GzDecoder::new(blob.as_slice()); + + log::info!("Get {} into {}", image_name, dir.display()); + tar::Archive::new(buf).unpack(&dir)?; + } + println!("cargo:rustc-link-search={}", dir.display()); + for path in fs::read_dir(&dir)?.filter_map(|entry| { + let path = entry.ok()?.path(); + path.is_file().then(|| path) + }) { + let name = path + .file_stem() + .unwrap() + .to_str() + .expect("Non UTF-8 is not supported"); + let name = if let Some(name) = name.strip_prefix(STATIC_PREFIX) { + name + } else { + continue; + }; + if let Some(ext) = path.extension() { + if ext == STATIC_EXTENSION { + println!("cargo:rustc-link-lib=static={}", name); + } + } + } + println!("cargo:rerun-if-changed={}", dir.display()); + println!("cargo:rerun-if-env-changed=XDG_DATA_HOME"); + Ok(()) +}