Files
ndbioimage/build.rs
T
w.pomp ff7cd562af - implement shape in Rust
- implement more readers
- fix downloading of bioformats jar
- (mostly) compatible with python version
2026-07-13 13:40:34 +02:00

178 lines
5.7 KiB
Rust

#[cfg(feature = "bioformats_java")]
const BIOFORMATS_VERSION: &str = "8.5.0";
#[cfg(feature = "bioformats_java")]
mod bioformats {
use std::error::Error;
use std::fmt::{Display, Formatter};
#[derive(Clone, Debug)]
pub(crate) enum BuildError {
J4rsVersionNotFound,
}
impl Display for BuildError {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), std::fmt::Error> {
match self {
Self::J4rsVersionNotFound => write!(fmt, "J4rsVersion not found in Cargo.lock"),
}
}
}
impl Error for BuildError {}
fn get_j4rs_version() -> Result<String, Box<dyn Error>> {
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
let lock_path = std::path::Path::new(&manifest_dir).join("Cargo.lock");
let lock_toml = std::fs::read_to_string(&lock_path)?;
let value: toml::Value = toml::from_str(&lock_toml)?;
if let Some(packages) = value.get("package").and_then(|v| v.as_array()) {
for package in packages {
if let (Some(name), Some(version)) = (
package.get("name").and_then(|v| v.as_str()),
package.get("version"),
) && name == "j4rs"
{
return Ok(version
.to_string()
.strip_prefix("\"")
.and_then(|v| v.strip_suffix("\""))
.ok_or(BuildError::J4rsVersionNotFound)?
.to_string());
}
}
}
Err(Box::new(BuildError::J4rsVersionNotFound {}))
}
pub(crate) fn build() -> Result<(), Box<dyn Error>> {
let j4rs_version = get_j4rs_version()?;
let out_dir = std::env::var("OUT_DIR")?;
let dest_path = std::path::Path::new(&out_dir).join("constants.rs");
let contents = format!(
r#"
/// Generated by build.rs
pub(super) const J4RS_VERSION: &str = "{}";
pub(super) const BIOFORMATS_VERSION: &str = "{}";
"#,
j4rs_version,
crate::BIOFORMATS_VERSION,
);
std::fs::write(&dest_path, contents)?;
Ok(())
}
}
#[cfg(all(not(feature = "python"), feature = "bioformats_java"))]
mod no_python_bioformats {
use j4rs::errors::J4RsError;
use j4rs::{JvmBuilder, MavenArtifact, MavenArtifactRepo, MavenSettings};
use retry::delay::Exponential;
use retry::{delay, retry};
use std::error::Error;
use std::fmt::{Display, Formatter};
#[derive(Clone, Debug)]
pub(crate) enum BuildError {
BioFormatsNotDownloaded,
}
impl Display for BuildError {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), std::fmt::Error> {
write!(fmt, "Bioformats package not downloaded")
}
}
impl Error for BuildError {}
pub(crate) fn build() -> Result<(), Box<dyn Error>> {
retry(
Exponential::from_millis(1000).map(delay::jitter).take(4),
deploy_java_artifacts,
)?;
let path = default_jassets_path()?;
if !path.join("bioformats_package-8.5.0.jar").exists() {
Err(BuildError::BioFormatsNotDownloaded)?;
}
Ok(())
}
fn default_jassets_path() -> Result<std::path::PathBuf, J4RsError> {
let is_build_script = std::env::var("OUT_DIR").is_ok();
let mut start_path = if is_build_script {
std::path::PathBuf::from(std::env::var("OUT_DIR")?)
} else {
std::env::current_exe()?
};
start_path = std::fs::canonicalize(start_path)?;
while start_path.pop() {
for entry in std::fs::read_dir(&start_path)? {
let path = entry?.path();
if path.file_name().map(|x| x == "jassets").unwrap_or(false) {
return Ok(path);
}
}
}
Err(J4RsError::GeneralError(
"Can not find jassets directory".to_string(),
))
}
fn deploy_java_artifacts() -> Result<(), J4RsError> {
let jvm = JvmBuilder::new()
.skip_setting_native_lib()
.with_maven_settings(MavenSettings::new(vec![MavenArtifactRepo::from(
"openmicroscopy::https://artifacts.openmicroscopy.org/artifactory/ome.releases",
)]))
.build()?;
jvm.deploy_artifact(&MavenArtifact::from("ome:bioformats_package:8.5.0"))?;
#[cfg(feature = "gpl-formats")]
jvm.deploy_artifact(&MavenArtifact::from("ome:formats-gpl:8.5.0"))?;
Ok(())
}
}
#[cfg(all(feature = "python", feature = "bioformats_java"))]
mod python_bioformats {
pub(crate) fn build() -> Result<(), Box<dyn std::error::Error>> {
let py_src_path = std::env::current_dir()?.join("py").join("ndbioimage");
let py_jassets_path = py_src_path.join("jassets");
let py_deps_path = py_src_path.join("deps");
if py_jassets_path.exists() {
std::fs::remove_dir_all(&py_jassets_path)?;
}
if py_deps_path.exists() {
std::fs::remove_dir_all(&py_deps_path)?;
}
j4rs::Jvm::copy_j4rs_libs_under(py_src_path.to_str().unwrap())?;
Ok(())
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("cargo::rerun-if-changed=build.rs");
if std::env::var("DOCS_RS").is_err() {
#[cfg(feature = "movie")]
ffmpeg_sidecar::download::auto_download()?;
#[cfg(feature = "bioformats_java")]
bioformats::build()?;
#[cfg(all(not(feature = "python"), feature = "bioformats_java"))]
no_python_bioformats::build()?;
#[cfg(all(feature = "python", feature = "bioformats_java"))]
python_bioformats::build()?;
}
Ok(())
}