1pub mod archive;
17pub mod closure;
18pub mod db;
19pub mod ldconf;
20pub mod path;
21pub mod platform;
22pub mod prune;
23
24pub use closure::Closure;
25pub use db::{Database, Package};
26pub use platform::Pin;
27pub use prune::{PlatformLine, Policy, Pruned, Trace};
28
29pub const LIB_DIRS: &[&str] = &[
34 "usr/lib",
35 "usr/lib64",
36 "usr/lib32",
37 "usr/lib/x86_64-linux-gnu",
38 "usr/lib/aarch64-linux-gnu",
39 "usr/lib/i386-linux-gnu",
40 "usr/lib/arm-linux-gnueabihf",
41 "lib",
42 "lib64",
43 "lib32",
44 "lib/x86_64-linux-gnu",
45 "lib/aarch64-linux-gnu",
46 "lib/i386-linux-gnu",
47 "lib/arm-linux-gnueabihf",
48];
49
50pub const LIB_PATHS: &[&str] = &[
52 "/usr/lib",
53 "/usr/lib64",
54 "/usr/lib32",
55 "/usr/lib/x86_64-linux-gnu",
56 "/usr/lib/aarch64-linux-gnu",
57 "/usr/lib/i386-linux-gnu",
58 "/usr/lib/arm-linux-gnueabihf",
59 "/lib",
60 "/lib64",
61 "/lib32",
62 "/lib/x86_64-linux-gnu",
63 "/lib/aarch64-linux-gnu",
64 "/lib/i386-linux-gnu",
65 "/lib/arm-linux-gnueabihf",
66];
67
68pub fn is_top_level_lib_object(rel: &str) -> bool {
75 let Some((dir, name)) = rel.rsplit_once('/') else {
76 return false;
77 };
78 LIB_DIRS.contains(&dir) && name.contains(".so")
79}
80
81#[cfg(test)]
82mod lib_dirs_tests {
83 use super::is_top_level_lib_object;
84
85 #[test]
86 fn top_level_libraries_in_flat_and_multiarch_dirs() {
87 assert!(is_top_level_lib_object("usr/lib/libGL.so.1"));
88 assert!(is_top_level_lib_object("usr/lib64/libEGL.so.1"));
89 assert!(is_top_level_lib_object(
90 "usr/lib/x86_64-linux-gnu/libEGL.so.1"
91 ));
92 assert!(is_top_level_lib_object("lib/aarch64-linux-gnu/libc.so.6"));
93 }
94
95 #[test]
96 fn nested_or_non_library_files_are_not_top_level() {
97 assert!(!is_top_level_lib_object("usr/lib/fixture/plugins/a.so"));
98 assert!(!is_top_level_lib_object("usr/bin/app"));
99 assert!(!is_top_level_lib_object("usr/share/doc/libfixture/README"));
100 assert!(!is_top_level_lib_object("libEGL.so.1"));
101 }
102}