Skip to content

Commit 2fb8283

Browse files
committed
Added optional semver matching for libcamera bindings
1 parent 62ad9bd commit 2fb8283

File tree

2 files changed

+54
-11
lines changed

2 files changed

+54
-11
lines changed

libcamera/Cargo.toml

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ categories = ["api-bindings", "computer-vision", "multimedia"]
1111
readme = "../README.md"
1212

1313
[features]
14-
default = ["vendor_draft"]
14+
default = ["vendor_draft", "libcamera_semver_versioning"]
15+
16+
libcamera_semver_versioning = []
17+
1518
vendor_draft = []
1619
vendor_rpi = []
1720

@@ -26,3 +29,4 @@ thiserror = "1.0"
2629

2730
[build-dependencies]
2831
libcamera-sys = { path = "../libcamera-sys", version = "0.2.3" }
32+
semver = "1.0.22"

libcamera/build.rs

+49-10
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,62 @@ use std::{
33
path::{Path, PathBuf},
44
};
55

6+
use semver::{Comparator, Op, Version};
7+
68
fn main() {
7-
let version = format!(
8-
"{}.{}.{}",
9-
libcamera_sys::LIBCAMERA_VERSION_MAJOR,
10-
libcamera_sys::LIBCAMERA_VERSION_MINOR,
11-
libcamera_sys::LIBCAMERA_VERSION_PATCH
9+
let libcamera_version = Version::new(
10+
libcamera_sys::LIBCAMERA_VERSION_MAJOR as _,
11+
libcamera_sys::LIBCAMERA_VERSION_MINOR as _,
12+
libcamera_sys::LIBCAMERA_VERSION_PATCH as _,
1213
);
1314

14-
let versioned_files = Path::new("versioned_files").join(&version);
15+
let versioned_files = Path::new("versioned_files");
16+
let mut candidates = std::fs::read_dir(versioned_files)
17+
.unwrap()
18+
.filter_map(|entry| entry.ok())
19+
.filter_map(|entry| {
20+
let path = entry.path();
21+
let version = Version::parse(path.file_name()?.to_str()?).ok()?;
1522

16-
if std::fs::metadata(&versioned_files).is_err() {
17-
panic!("Unsupported version of libcamera detected: {version}");
18-
}
23+
Some((version, path))
24+
})
25+
.collect::<Vec<_>>();
26+
candidates.sort_unstable_by_key(|(version, _)| version.clone());
27+
28+
// Filter to only compatible versions
29+
let matching = candidates.iter().filter(|(candidate, _)| {
30+
#[cfg(feature = "libcamera_semver_versioning")]
31+
let op = Op::Caret;
32+
#[cfg(not(feature = "libcamera_semver_versioning"))]
33+
let op = Op::Exact;
34+
35+
let comparator = Comparator {
36+
op,
37+
major: candidate.major,
38+
minor: Some(candidate.minor),
39+
patch: Some(candidate.patch),
40+
pre: Default::default(),
41+
};
42+
43+
comparator.matches(&libcamera_version)
44+
});
45+
46+
// And take the most recent compatible version
47+
let (_, selected_version) = match matching.max_by_key(|(version, _)| version.clone()) {
48+
Some(v) => v,
49+
None => panic!(
50+
"Unsupported version of libcamera detected: {libcamera_version}\nsupported versions are: \n{}",
51+
candidates
52+
.iter()
53+
.map(|(v, _)| format!("\t{v}"))
54+
.collect::<Vec<_>>()
55+
.join("\n")
56+
),
57+
};
1958

2059
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
2160

2261
for file in ["controls.rs", "properties.rs"] {
23-
std::fs::copy(versioned_files.join(file), out_path.join(file)).unwrap();
62+
std::fs::copy(selected_version.join(file), out_path.join(file)).unwrap();
2463
}
2564
}

0 commit comments

Comments
 (0)