Skip to content

Commit 1512f8c

Browse files
committed
openvino-finder: locate v2022.3 libraries in the system paths
Version 2022.3.0 of OpenVINO installs its libraries in the system install path on Linux. This change adds functionality to `openvino-finder` to locate these libraries, even in the presence of version terminators (e.g., `libopenvino_c.so.2022.3.0`).
1 parent 0bc3a8f commit 1512f8c

File tree

1 file changed

+89
-5
lines changed
  • crates/openvino-finder/src

1 file changed

+89
-5
lines changed

crates/openvino-finder/src/lib.rs

Lines changed: 89 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99
use cfg_if::cfg_if;
1010
use std::env;
11-
use std::path::PathBuf;
11+
use std::fs;
12+
use std::path::{Path, PathBuf};
1213

1314
/// Find the path to an OpenVINO library. This will try:
1415
/// - the `OPENVINO_INSTALL_DIR` environment variable with several subdirectories appended
@@ -74,6 +75,25 @@ pub fn find(library_name: &str) -> Option<PathBuf> {
7475
}
7576
}
7677

78+
// Search in OpenVINO's installation directories; after v2022.3, Linux packages will be
79+
// installed in the system's default library locations.
80+
for install_dir in SYSTEM_INSTALLATION_DIRECTORIES
81+
.iter()
82+
.map(PathBuf::from)
83+
.filter(|d| d.is_dir())
84+
{
85+
// Check if the file is located in the installation directory.
86+
let search_path = install_dir.join(&file);
87+
check_and_return!(search_path);
88+
89+
// Otherwise, check for version terminators: e.g., `libfoo.so.3.1.2`.
90+
let filenames = list_directory(&install_dir).expect("cannot list installation directory");
91+
let versions = get_suffixes(filenames, &file);
92+
if let Some(path) = build_latest_version(&install_dir, &file, versions) {
93+
check_and_return!(path);
94+
}
95+
}
96+
7797
// Search in OpenVINO's default installation directories (if they exist).
7898
for default_dir in DEFAULT_INSTALLATION_DIRECTORIES
7999
.iter()
@@ -108,15 +128,29 @@ cfg_if! {
108128

109129
cfg_if! {
110130
if #[cfg(any(target_os = "linux", target_os = "macos"))] {
111-
const DEFAULT_INSTALLATION_DIRECTORIES: & [& str] =
112-
&["/opt/intel/openvino_2022", "/opt/intel/openvino"];
131+
const DEFAULT_INSTALLATION_DIRECTORIES: &[&str] = &[
132+
"/opt/intel/openvino_2022",
133+
"/opt/intel/openvino",
134+
];
113135
} else if #[cfg(target_os = "windows")] {
114-
const DEFAULT_INSTALLATION_DIRECTORIES: & [& str] = &[
136+
const DEFAULT_INSTALLATION_DIRECTORIES: &[&str] = &[
115137
"C:\\Program Files (x86)\\Intel\\openvino_2022",
116138
"C:\\Program Files (x86)\\Intel\\openvino",
117139
];
118140
} else {
119-
const DEFAULT_INSTALLATION_DIRECTORIES: & [& str] = &[];
141+
const DEFAULT_INSTALLATION_DIRECTORIES: &[&str] = &[];
142+
}
143+
}
144+
145+
cfg_if! {
146+
if #[cfg(target_os = "linux")] {
147+
const SYSTEM_INSTALLATION_DIRECTORIES: &[&str] = &[
148+
"/usr/lib/x86_64-linux-gnu", // DEB-installed package (OpenVINO >= 2022.3)
149+
"/lib/x86_64-linux-gnu", // DEB-installed package (TBB)
150+
"/usr/lib64", // RPM-installed package >= 2022.3
151+
];
152+
} else {
153+
const SYSTEM_INSTALLATION_DIRECTORIES: &[&str] = &[];
120154
}
121155
}
122156

@@ -129,6 +163,39 @@ const KNOWN_BUILD_SUBDIRECTORIES: &[&str] = &[
129163
"temp/tbb/lib",
130164
];
131165

166+
167+
#[inline]
168+
fn list_directory(dir: &Path) -> Option<impl IntoIterator<Item = String>> {
169+
let traversal = fs::read_dir(dir).ok()?;
170+
Some(
171+
traversal
172+
.filter_map(Result::ok)
173+
.filter_map(|f| f.file_name().to_str().map(ToString::to_string)),
174+
)
175+
}
176+
177+
#[inline]
178+
fn get_suffixes(filenames: impl IntoIterator<Item = String>, prefix: &str) -> Vec<String> {
179+
filenames
180+
.into_iter()
181+
.filter_map(|f| f.strip_prefix(prefix).map(ToString::to_string))
182+
.collect()
183+
}
184+
185+
#[inline]
186+
fn build_latest_version(dir: &Path, prefix: &str, mut versions: Vec<String>) -> Option<PathBuf> {
187+
if versions.is_empty() {
188+
return None;
189+
}
190+
versions.sort();
191+
versions.reverse();
192+
let latest_version = versions
193+
.first()
194+
.expect("already checked that a version exists");
195+
let filename = format!("{}{}", prefix, latest_version);
196+
Some(dir.join(filename))
197+
}
198+
132199
#[cfg(test)]
133200
mod test {
134201
use super::*;
@@ -140,4 +207,21 @@ mod test {
140207
pretty_env_logger::init();
141208
assert!(find("openvino_c").is_some());
142209
}
210+
211+
/// This test shows how the finder would discover the latest shared library on an
212+
/// APT installation.
213+
#[test]
214+
fn find_latest_library() {
215+
let path = build_latest_version(
216+
&PathBuf::from("/usr/lib/x86_64-linux-gnu"),
217+
"libopenvino.so.",
218+
vec!["2022.1.0".into(), "2022.3.0".into()],
219+
);
220+
assert_eq!(
221+
path,
222+
Some(PathBuf::from(
223+
"/usr/lib/x86_64-linux-gnu/libopenvino.so.2022.3.0"
224+
))
225+
);
226+
}
143227
}

0 commit comments

Comments
 (0)