Skip to content

Commit 3d4b091

Browse files
committed
More static fixes
1 parent 338be0b commit 3d4b091

File tree

4 files changed

+64
-76
lines changed

4 files changed

+64
-76
lines changed

build.rs

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -94,43 +94,6 @@ fn files_with_extension<'e>(dir: &Path, extension: impl AsRef<OsStr> + 'e) -> Re
9494
})
9595
}
9696

97-
/// Returns Some(new_file_name) if some parts of the filename were removed, None otherwise
98-
fn cleanup_lib_filename(filename: &OsStr) -> Option<&OsStr> {
99-
let mut new_filename = filename;
100-
// used to check for the file extension (with dots stripped) and for the part of the filename
101-
const LIB_EXTS: [&str; 7] = [".so.", ".a.", ".dll.", ".lib.", ".dylib.", ".framework.", ".tbd."];
102-
let filename_path = Path::new(new_filename);
103-
// strip lib extension from the filename
104-
if let (Some(stem), Some(extension)) = (filename_path.file_stem(), filename_path.extension().and_then(OsStr::to_str)) {
105-
if LIB_EXTS.iter().any(|e| e.trim_matches('.').eq_ignore_ascii_case(extension)) {
106-
new_filename = stem;
107-
}
108-
}
109-
if let Some(mut file) = new_filename.to_str() {
110-
let orig_len = file.len();
111-
112-
// strip "lib" prefix from the filename unless targeting MSVC
113-
if !*TARGET_ENV_MSVC {
114-
file = file.strip_prefix("lib").unwrap_or(file);
115-
}
116-
117-
// strip lib extension + suffix (e.g. .so.4.6.0) from the filename
118-
LIB_EXTS.iter().for_each(|&inner_ext| {
119-
if let Some(inner_ext_idx) = file.find(inner_ext) {
120-
file = &file[..inner_ext_idx];
121-
}
122-
});
123-
if orig_len != file.len() {
124-
new_filename = OsStr::new(file);
125-
}
126-
}
127-
if new_filename.len() != filename.len() {
128-
Some(new_filename)
129-
} else {
130-
None
131-
}
132-
}
133-
13497
fn get_module_header_dir(header_dir: &Path) -> Option<PathBuf> {
13598
let mut out = header_dir.join("opencv2.framework/Headers");
13699
if out.exists() {

build/cmake_probe.rs

Lines changed: 52 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,62 @@ use semver::Version;
99
use shlex::Shlex;
1010

1111
use super::library::Linkage;
12-
use super::Result;
12+
use super::{Result, TARGET_ENV_MSVC};
1313

1414
#[derive(Debug, PartialEq, Eq)]
1515
pub struct LinkLib(pub Linkage, pub String);
1616

1717
impl LinkLib {
1818
#[inline]
1919
pub fn emit_cargo_rustc_link(&self) -> String {
20-
let link_spec = self.0.as_cargo_rustc_link_spec();
21-
let link_spec = if self.1.starts_with(link_spec) {
22-
""
20+
format!("cargo:rustc-link-lib={}{}", self.0.as_cargo_rustc_link_spec(), self.1)
21+
}
22+
23+
/// Returns Some(new_file_name) with extra parts of the filename were removed, None in case of error
24+
pub fn with_cleaned_up_lib_filename(self) -> Option<Self> {
25+
return Some(self);
26+
if matches!(self.0, Linkage::Static | Linkage::Framework) {
27+
Some(self)
2328
} else {
24-
link_spec
25-
};
26-
format!("cargo:rustc-link-lib={link_spec}{}", self.1)
29+
let mut new_filename = Path::new(&self.1).as_os_str();
30+
// used to check for the file extension (with dots stripped) and for the part of the filename
31+
const LIB_EXTS: [&str; 7] = [".so.", ".a.", ".dll.", ".lib.", ".dylib.", ".framework.", ".tbd."];
32+
let filename_path = Path::new(new_filename);
33+
// strip lib extension from the filename
34+
if let (Some(stem), Some(extension)) = (filename_path.file_stem(), filename_path.extension().and_then(OsStr::to_str)) {
35+
if LIB_EXTS.iter().any(|e| e.trim_matches('.').eq_ignore_ascii_case(extension)) {
36+
new_filename = stem;
37+
}
38+
}
39+
if let Some(mut file) = new_filename.to_str() {
40+
let orig_len = file.len();
41+
42+
// strip "lib" prefix from the filename unless targeting MSVC
43+
if !*TARGET_ENV_MSVC {
44+
file = file.strip_prefix("lib").unwrap_or(file);
45+
}
46+
47+
// strip lib extension + suffix (e.g. .so.4.6.0) from the filename
48+
LIB_EXTS.iter().for_each(|&inner_ext| {
49+
if let Some(inner_ext_idx) = file.find(inner_ext) {
50+
file = &file[..inner_ext_idx];
51+
}
52+
});
53+
if orig_len != file.len() {
54+
new_filename = OsStr::new(file);
55+
}
56+
}
57+
new_filename
58+
.to_str()
59+
.map(|new_filename| Self(self.0, new_filename.to_string()))
60+
}
2761
}
2862
}
2963

3064
impl From<&str> for LinkLib {
3165
fn from(value: &str) -> Self {
32-
Self(Linkage::Default, value.to_string())
66+
let (linkage, value) = Linkage::from_prefixed_str(value);
67+
Self(linkage, value.to_string())
3368
}
3469
}
3570

@@ -49,7 +84,8 @@ impl LinkSearch {
4984

5085
impl From<&str> for LinkSearch {
5186
fn from(value: &str) -> Self {
52-
Self(Linkage::Default, value.into())
87+
let (linkage, value) = Linkage::from_prefixed_str(value);
88+
Self(linkage, value.into())
5389
}
5490
}
5591

@@ -190,43 +226,30 @@ impl<'r> CmakeProbe<'r> {
190226
} else {
191227
framework.to_string()
192228
};
193-
let framework_path = Path::new(&framework);
194-
let has_extension = framework_path
195-
.extension()
196-
.and_then(OsStr::to_str)
197-
.map_or(false, |ext| ext.eq_ignore_ascii_case("framework"));
198-
let name = if has_extension {
199-
framework
200-
} else {
201-
format!("{}.framework", framework)
202-
};
203-
link_libs.push(LinkLib(Linkage::Framework, name));
229+
link_libs.push(LinkLib(Linkage::Framework, framework));
204230
} else if !arg.starts_with('-') {
205231
let path = Path::new(arg);
206-
let linkage = if Self::is_library_static(path) {
232+
let linkage = if Self::is_library_static_archive(path) {
207233
Linkage::Static
208234
} else {
209-
Linkage::Default
210-
};
211-
if let Some(file) = path.file_name().and_then(super::cleanup_lib_filename) {
212235
if let Some(parent) = path.parent().map(|p| p.to_owned()) {
213-
let search_path = LinkSearch(linkage, parent);
236+
let search_path = LinkSearch(Linkage::Default, parent);
214237
if !link_paths.contains(&search_path) {
215238
link_paths.push(search_path);
216239
}
217240
} else {
218241
panic!("{}", arg.to_string());
219242
}
220-
let file = file.to_str().expect("Non-UTF8 filename");
221-
link_libs.push(LinkLib(linkage, file.to_string()));
222-
}
243+
Linkage::Default
244+
};
245+
link_libs.push(LinkLib(linkage, path.to_str().expect("Non-UTF8 filename").to_string()));
223246
} else {
224247
eprintln!("=== Unexpected cmake compiler argument found: {arg}");
225248
}
226249
}
227250
}
228251

229-
fn is_library_static(path: &Path) -> bool {
252+
fn is_library_static_archive(path: &Path) -> bool {
230253
path.extension().map_or(false, |ext| ext.eq_ignore_ascii_case("a"))
231254
}
232255

build/library.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use dunce::canonicalize;
88
use semver::Version;
99

1010
use super::cmake_probe::{CmakeProbe, LinkLib, LinkSearch};
11-
use super::{cleanup_lib_filename, get_version_from_headers, Result, MANIFEST_DIR, OUT_DIR, TARGET_VENDOR_APPLE};
11+
use super::{get_version_from_headers, Result, MANIFEST_DIR, OUT_DIR, TARGET_VENDOR_APPLE};
1212

1313
struct PackageName;
1414

@@ -103,6 +103,13 @@ impl Linkage {
103103
Self::Framework => "framework=",
104104
}
105105
}
106+
107+
pub fn from_prefixed_str(s: &str) -> (Self, &str) {
108+
[Self::Dynamic, Self::Static, Self::Framework]
109+
.iter()
110+
.find_map(|l| s.strip_prefix(l.as_cargo_rustc_link_spec()).map(|s| (*l, s)))
111+
.unwrap_or((Self::Default, s))
112+
}
106113
}
107114

108115
#[derive(Debug)]
@@ -114,15 +121,9 @@ pub struct Library {
114121

115122
impl Library {
116123
fn process_library_list(libs: impl IntoIterator<Item = LinkLib>) -> impl Iterator<Item = LinkLib> {
117-
libs.into_iter().filter_map(|LinkLib(linkage, path)| {
118-
let path = Path::new(&path);
119-
if let Some(filename) = path.file_name() {
120-
let filename = cleanup_lib_filename(filename).unwrap_or(filename);
121-
filename.to_str().map(|f| LinkLib(linkage, f.to_owned()))
122-
} else {
123-
None
124-
}
125-
})
124+
libs
125+
.into_iter()
126+
.filter_map(|link_lib| link_lib.with_cleaned_up_lib_filename())
126127
}
127128

128129
fn version_from_include_paths(include_paths: impl IntoIterator<Item = impl AsRef<Path>>) -> Option<Version> {

tests/mat.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use matches::assert_matches;
66
use opencv::core::{MatConstIterator, MatIter, Point, Point2d, Rect, Scalar, Size, Vec2b, Vec2s, Vec3d, Vec3f, Vec4w, Vector};
77
use opencv::prelude::*;
88
use opencv::{core, imgproc, Error, Result};
9+
910
const PIXEL: &[u8] = include_bytes!("pixel.png");
1011

1112
#[test]

0 commit comments

Comments
 (0)