diff --git a/Cargo.toml b/Cargo.toml index 1cd7b7b28..e5592ecc9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,8 @@ keywords = ["dlopen", "load", "shared", "dylib"] categories = ["api-bindings"] rust-version = "1.88.0" edition = "2021" +autotests = false +include = ["Cargo.toml", "LICENSE", "README.mkd", "src/**/*.rs", "tests/**/*.rs", "tests/ordinals.def"] [features] default = ["std"] @@ -42,3 +44,8 @@ unexpected_cfgs = { level = "warn", check-cfg = [ 'cfg(libloading_docs)', 'cfg(target_os, values("cygwin"))', ] } + +[[test]] +path = "tests/lib.rs" +name = "integration-tests" +harness = true diff --git a/src/test_helpers.rs b/src/test_helpers.rs index 9e3e9924f..8b02458a6 100644 --- a/src/test_helpers.rs +++ b/src/test_helpers.rs @@ -1,6 +1,6 @@ //! This is a separate file containing helpers for tests of this library. It is built into a //! dynamic library by the build.rs script. -#![crate_type="cdylib"] +#![crate_type = "cdylib"] #[no_mangle] pub static mut TEST_STATIC_U32: u32 = 0; @@ -18,7 +18,7 @@ pub struct S { a: u64, b: u32, c: u16, - d: u8 + d: u8, } #[no_mangle] @@ -35,3 +35,8 @@ pub unsafe extern "C" fn test_get_static_u32() -> u32 { pub unsafe extern "C" fn test_check_static_ptr() -> bool { TEST_STATIC_PTR == (&mut TEST_STATIC_PTR as *mut *mut _ as *mut _) } + +#[unsafe(no_mangle)] +pub extern "C" fn test_ordinals() -> *const std::ffi::c_char { + "bunny\0".as_ptr().cast() +} diff --git a/tests/functions.rs b/tests/functions.rs index 6f4fc2755..0ee2af971 100644 --- a/tests/functions.rs +++ b/tests/functions.rs @@ -1,10 +1,10 @@ use libloading::{Library, Symbol}; -use std::os::raw::c_void; const TARGET_DIR: Option<&'static str> = option_env!("CARGO_TARGET_DIR"); const TARGET_TMPDIR: Option<&'static str> = option_env!("CARGO_TARGET_TMPDIR"); +const MANIFEST_DIR: &'static str = env!("CARGO_MANIFEST_DIR"); -fn lib_path() -> std::path::PathBuf { +pub fn lib_path() -> std::path::PathBuf { [ TARGET_TMPDIR.unwrap_or(TARGET_DIR.unwrap_or("target")), "libtest_helpers.module", @@ -13,7 +13,7 @@ fn lib_path() -> std::path::PathBuf { .collect() } -fn make_helpers() { +pub fn make_helpers() { static ONCE: ::std::sync::Once = ::std::sync::Once::new(); ONCE.call_once(|| { if std::env::var_os("PRECOMPILED_TEST_HELPER").is_some() { @@ -31,6 +31,9 @@ fn make_helpers() { } else { eprintln!("WARNING: $TARGET NOT SPECIFIED! BUILDING HELPER MODULE FOR NATIVE TARGET."); } + if cfg!(target_env = "msvc") { + cmd.arg(format!("-Clink-arg=/DEF:{MANIFEST_DIR}/tests/ordinals.def")); + } assert!(cmd .status() .expect("could not compile the test helpers!") @@ -194,7 +197,7 @@ fn test_try_into_ptr() { unsafe { let lib = Library::new(lib_path()).unwrap(); let f: Symbol u32> = lib.get(b"test_identity_u32\0").unwrap(); - let ptr: *mut c_void = f.try_as_raw_ptr().unwrap(); + let ptr: *mut std::ffi::c_void = f.try_as_raw_ptr().unwrap(); assert!(!ptr.is_null()); let ptr_casted: extern "C" fn(u32) -> u32 = std::mem::transmute(ptr); assert_eq!(42, ptr_casted(42)); diff --git a/tests/lib.rs b/tests/lib.rs new file mode 100644 index 000000000..c1250ef53 --- /dev/null +++ b/tests/lib.rs @@ -0,0 +1,5 @@ +mod constants; +mod functions; +mod library_filename; +mod markers; +mod windows; diff --git a/tests/nagisa32.dll b/tests/nagisa32.dll deleted file mode 100644 index 0a6218ade..000000000 Binary files a/tests/nagisa32.dll and /dev/null differ diff --git a/tests/nagisa64.dll b/tests/nagisa64.dll deleted file mode 100644 index bacaa4b96..000000000 Binary files a/tests/nagisa64.dll and /dev/null differ diff --git a/tests/ordinals.def b/tests/ordinals.def new file mode 100644 index 000000000..1352bf958 --- /dev/null +++ b/tests/ordinals.def @@ -0,0 +1,9 @@ +LIBRARY test_helpers +EXPORTS + test_ordinals @1 NONAME + test_identity_u32 @2 + test_identity_struct @3 + test_check_static_ptr @4 + test_get_static_u32 @5 + TEST_STATIC_U32 @6 + TEST_STATIC_PTR @7 diff --git a/tests/windows.rs b/tests/windows.rs index 13a414502..f6f4bb159 100644 --- a/tests/windows.rs +++ b/tests/windows.rs @@ -3,27 +3,15 @@ extern crate libloading; use libloading::os::windows::*; use std::ffi::CStr; use std::os::raw::c_void; -// The ordinal DLL contains exactly one function (other than DllMain, that is) with ordinal number -// 1. This function has the sugnature `fn() -> *const c_char` and returns a string "bunny\0" (in -// reference to WindowsBunny). -// -// Both x86_64 and x86 versions of the .dll are functionally the same. Ideally we would compile the -// dlls with well known ordinals from our own testing helpers library, but rustc does not allow -// specifying a custom .def file (https://github.com/rust-lang/rust/issues/35089) -// -// The DLLs were kindly compiled by WindowsBunny (aka. @retep998). -#[cfg(target_arch = "x86")] -fn load_ordinal_lib() -> Library { - unsafe { Library::new("tests/nagisa32.dll").expect("nagisa32.dll") } -} - -#[cfg(target_arch = "x86_64")] +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] fn load_ordinal_lib() -> Library { - unsafe { Library::new("tests/nagisa64.dll").expect("nagisa64.dll") } + let path = super::functions::lib_path(); + super::functions::make_helpers(); + unsafe { Library::new(path.display().to_string()).expect("Windows test dll not found") } } -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_env = "msvc"))] #[test] fn test_ordinal() { let lib = load_ordinal_lib(); @@ -33,7 +21,7 @@ fn test_ordinal() { } } -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_env = "msvc"))] #[test] fn test_try_into_ptr() { let lib = load_ordinal_lib(); @@ -44,12 +32,13 @@ fn test_try_into_ptr() { } } -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_env = "msvc"))] #[test] fn test_ordinal_missing_fails() { let lib = load_ordinal_lib(); unsafe { - let r: Result *const i8>, _> = lib.get_ordinal(2); + // there are a few other symbols in the test DLL + let r: Result *const i8>, _> = lib.get_ordinal(8); r.err().unwrap(); let r: Result *const i8>, _> = lib.get_ordinal(!0); r.err().unwrap();