mirror of
https://github.com/openharmony/third_party_rust_libloading.git
synced 2026-07-19 13:16:19 -04:00
Make resolve_name a stand-alone function.
This commit is contained in:
committed by
Simonas Kazlauskas
parent
75527deec8
commit
7e5f290148
+4
-2
@@ -1,16 +1,18 @@
|
||||
//! Project changelog
|
||||
|
||||
// TODO: for the next breaking release rename `Error::LoadLibraryW` to `Error::LoadLibraryExW`.
|
||||
|
||||
// TODO: for the next breaking release use `RTLD_LAZY | RTLD_LOCAL` by default on unix.
|
||||
|
||||
/// Release 0.6.3 (2020-08-22)
|
||||
///
|
||||
/// * Improve documentation, allowing to view all of the os-specific functionality from
|
||||
/// documentation generated for any target;
|
||||
/// * Add [`os::windows::Library::this`];
|
||||
/// * Added constants to use with OS-specific `Library::open`.
|
||||
/// * Added constants to use with OS-specific `Library::open`;
|
||||
/// * Add [`library_filename`].
|
||||
///
|
||||
/// [`os::windows::Library::this`]: crate::os::windows::Library::this
|
||||
/// [`library_filename`]: crate::library_filename
|
||||
|
||||
/// Release 0.6.2 (2020-05-06)
|
||||
///
|
||||
|
||||
+32
-143
@@ -45,12 +45,10 @@
|
||||
#![cfg_attr(docsrs, deny(broken_intra_doc_links))]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
|
||||
use std::ffi::OsStr;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fmt;
|
||||
use std::ops::{self, Deref};
|
||||
use std::ops;
|
||||
use std::marker;
|
||||
|
||||
#[cfg(unix)]
|
||||
@@ -89,13 +87,15 @@ impl Library {
|
||||
/// [`SetErrorMode`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms680621(v=vs.85).aspx
|
||||
///
|
||||
/// Calling this function from multiple threads is not safe if used in conjunction with
|
||||
/// path-less filename and library search path is modified (`SetDllDirectory` function on
|
||||
/// relative filenames and the library search path is modified (`SetDllDirectory` function on
|
||||
/// Windows, `{DY,}LD_LIBRARY_PATH` environment variable on UNIX).
|
||||
///
|
||||
/// # Platform-specific behaviour
|
||||
///
|
||||
/// When a plain library filename is supplied, locations where library is searched for is
|
||||
/// platform specific and cannot be adjusted in a portable manner.
|
||||
/// platform specific and cannot be adjusted in a portable manner. See documentation for
|
||||
/// the platform specific [`os::unix::Library::new`] and [`os::windows::Library::new`] methods
|
||||
/// for further information on library lookup behaviour.
|
||||
///
|
||||
/// ## Windows
|
||||
///
|
||||
@@ -113,9 +113,10 @@ impl Library {
|
||||
/// `awesome.module`) allows to avoid code which has to account for platform’s conventional
|
||||
/// library filenames.
|
||||
///
|
||||
/// Strive to specify absolute or relative path to your library, unless system-wide libraries
|
||||
/// are being loaded. Platform-dependent library search locations combined with various quirks
|
||||
/// related to path-less filenames may cause flaky code.
|
||||
/// Strive to specify an absolute or at least a relative path to your library, unless
|
||||
/// system-wide libraries are being loaded. Platform-dependent library search locations
|
||||
/// combined with various quirks related to path-less filenames may cause flakiness in
|
||||
/// programs.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@@ -130,35 +131,6 @@ impl Library {
|
||||
imp::Library::new(filename).map(From::from)
|
||||
}
|
||||
|
||||
fn resolve_name<'a>(name: &'a str) -> Cow<'a, str> {
|
||||
match (name.starts_with(DLL_PREFIX), name.ends_with(DLL_SUFFIX)) {
|
||||
(true, true) => Cow::Borrowed(name),
|
||||
(true, false) => Cow::Owned(format!("{}{}", name, DLL_SUFFIX)),
|
||||
(false, true) => Cow::Owned(format!("{}{}", DLL_PREFIX, name)),
|
||||
(false, false) => Cow::Owned(format!("{}{}{}", DLL_PREFIX, name, DLL_SUFFIX)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads a library and does resolve it's name to match platform-specific
|
||||
/// naming schemes.
|
||||
///
|
||||
/// For a given library called `engine`, this method will resolve the name
|
||||
/// to the following:
|
||||
/// - `Linux`: `libengine.so`
|
||||
/// - `macOS`: `libengine.dylib`
|
||||
/// - `Windows`: `engine.dll`
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// This function does only work with library names and does not work when
|
||||
/// supplying a path to a library. The function assumes that the library is
|
||||
/// already present inside a path that is detectable and searchable by the
|
||||
/// OS during runtime.
|
||||
pub fn with_name_resolve<T: AsRef<str>>(libname: T) -> Result<Library, Error> {
|
||||
let resolved_name = Self::resolve_name(libname.as_ref());
|
||||
Self::new(resolved_name.deref())
|
||||
}
|
||||
|
||||
/// Get a pointer to function or static variable by symbol name.
|
||||
///
|
||||
/// The `symbol` may not contain any null bytes, with an exception of last byte. A null
|
||||
@@ -369,109 +341,26 @@ impl<'lib, T> fmt::Debug for Symbol<'lib, T> {
|
||||
unsafe impl<'lib, T: Send> Send for Symbol<'lib, T> {}
|
||||
unsafe impl<'lib, T: Sync> Sync for Symbol<'lib, T> {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Library;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
#[test]
|
||||
fn test_resolve_name_none() {
|
||||
let name = "audioengine";
|
||||
let resolved = Library::resolve_name(name);
|
||||
assert_eq!(&resolved, "audioengine.dll");
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_resolve_name_none() {
|
||||
let name = "audioengine";
|
||||
let resolved = Library::resolve_name(name);
|
||||
assert_eq!(&resolved, "libaudioengine.so");
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[test]
|
||||
fn test_resolve_name_none() {
|
||||
let name = "audioengine";
|
||||
let resolved = Library::resolve_name(name);
|
||||
assert_eq!(&resolved, "libaudioengine.dylib");
|
||||
}
|
||||
|
||||
// prefix only
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
#[test]
|
||||
fn test_resolve_name_prefix() {
|
||||
let name = "audioengine";
|
||||
let resolved = Library::resolve_name(name);
|
||||
assert_eq!(&resolved, "audioengine.dll");
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_resolve_name_prefix() {
|
||||
let name = "libaudioengine";
|
||||
let resolved = Library::resolve_name(name);
|
||||
assert_eq!(&resolved, "libaudioengine.so");
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[test]
|
||||
fn test_resolve_name_prefix() {
|
||||
let name = "libaudioengine";
|
||||
let resolved = Library::resolve_name(name);
|
||||
assert_eq!(&resolved, "libaudioengine.dylib");
|
||||
}
|
||||
|
||||
// suffix only
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
#[test]
|
||||
fn test_resolve_name_suffix() {
|
||||
let name = "audioengine.dll";
|
||||
let resolved = Library::resolve_name(name);
|
||||
assert_eq!(&resolved, "audioengine.dll");
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_resolve_name_suffix() {
|
||||
let name = "audioengine.so";
|
||||
let resolved = Library::resolve_name(name);
|
||||
assert_eq!(&resolved, "libaudioengine.so");
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[test]
|
||||
fn test_resolve_name_suffix() {
|
||||
let name = "audioengine.dylib";
|
||||
let resolved = Library::resolve_name(name);
|
||||
assert_eq!(&resolved, "libaudioengine.dylib");
|
||||
}
|
||||
|
||||
// both
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
#[test]
|
||||
fn test_resolve_name_prefix_and_suffix() {
|
||||
let name = "audioengine.dll";
|
||||
let resolved = Library::resolve_name(name);
|
||||
assert_eq!(&resolved, "audioengine.dll");
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_resolve_name_prefix_and_suffix() {
|
||||
let name = "libaudioengine.so";
|
||||
let resolved = Library::resolve_name(name);
|
||||
assert_eq!(&resolved, "libaudioengine.so");
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[test]
|
||||
fn test_resolve_name_prefix_and_suffix() {
|
||||
let name = "libaudioengine.dylib";
|
||||
let resolved = Library::resolve_name(name);
|
||||
assert_eq!(&resolved, "libaudioengine.dylib");
|
||||
}
|
||||
/// Converts a library name to a filename generally appropriate for use on the system.
|
||||
///
|
||||
/// The function will prepend prefixes (such as `lib`) and suffixes (such as `.so`) to the library
|
||||
/// `name` to construct the filename.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// It can be used to load global libraries in a platform independent manner:
|
||||
///
|
||||
/// ```
|
||||
/// use libloading::{Library, library_filename};
|
||||
/// // Will attempt to load `libLLVM.so` on Linux, `libLLVM.dylib` on macOS and `LLVM.dll` on
|
||||
/// // Windows.
|
||||
/// let library = Library::new(library_filename("LLVM"));
|
||||
/// ```
|
||||
pub fn library_filename<S: AsRef<OsStr>>(name: S) -> OsString {
|
||||
let name = name.as_ref();
|
||||
let mut string = OsString::with_capacity(name.len() + DLL_PREFIX.len() + DLL_SUFFIX.len());
|
||||
string.push(DLL_PREFIX);
|
||||
string.push(name);
|
||||
string.push(DLL_SUFFIX);
|
||||
string
|
||||
}
|
||||
|
||||
@@ -84,6 +84,10 @@ impl Library {
|
||||
/// path, the function uses a windows-specific search strategy to find the module; for more
|
||||
/// information, see the [Remarks on MSDN][msdn].
|
||||
///
|
||||
/// If the `filename` specifies a library filename without path and with extension omitted,
|
||||
/// `.dll` extension is implicitly added. This behaviour may be suppressed by appending a
|
||||
/// trailing `.` to the `filename`.
|
||||
///
|
||||
/// This is equivalent to [`Library::load_with_flags`]`(filename, 0)`.
|
||||
///
|
||||
/// [msdn]: https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryw#remarks
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
extern crate libloading;
|
||||
use libloading::library_filename;
|
||||
use std::path::Path;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
const EXPECTED: &str = "audioengine.dll";
|
||||
#[cfg(target_os = "linux")]
|
||||
const EXPECTED: &str = "libaudioengine.so";
|
||||
#[cfg(target_os = "macos")]
|
||||
const EXPECTED: &str = "libaudioengine.dylib";
|
||||
|
||||
#[test]
|
||||
fn test_library_filename() {
|
||||
let name = "audioengine";
|
||||
let resolved = library_filename(name);
|
||||
assert!(Path::new(&resolved).ends_with(EXPECTED));
|
||||
}
|
||||
Reference in New Issue
Block a user