diff --git a/build.rs b/build.rs index a6faa31..be3afba 100644 --- a/build.rs +++ b/build.rs @@ -20,27 +20,4 @@ fn main(){ ::std::process::exit(0xfc); } } - maybe_test_helpers(); -} - -fn maybe_test_helpers() { - if env::var("OPT_LEVEL").ok().and_then(|v| v.parse().ok()).unwrap_or(0u64) != 0 { - // certainly not for testing, just skip. - return; - } - let mut outpath = if let Some(od) = env::var_os("OUT_DIR") { od } else { return }; - let target = if let Some(t) = env::var_os("TARGET") { t } else { return }; - let rustc = env::var_os("RUSTC").unwrap_or_else(|| { "rustc".into() }); - outpath.push("/libtest_helpers.dll"); // extension for windows required, POSIX does not care. - let _ = ::std::process::Command::new(rustc) - .arg("src/test_helpers.rs") - .arg("-o") - .arg(outpath) - .arg("-O") - .arg("--target") - .arg(target) - .output(); - // Ignore the failures here. We do not want failures of this thing to inhibit people from - // building and using the library. Might make it hard to debug why tests fail in case this - // library does not get built, though. } diff --git a/tests/functions.rs b/tests/functions.rs index 109689b..c9bc067 100644 --- a/tests/functions.rs +++ b/tests/functions.rs @@ -3,8 +3,25 @@ use libloading::{Symbol, Library}; const LIBPATH: &'static str = concat!(env!("OUT_DIR"), "/libtest_helpers.dll"); +fn make_helpers() { + static ONCE: ::std::sync::Once = ::std::sync::ONCE_INIT; + ONCE.call_once(|| { + let mut outpath = String::from(if let Some(od) = option_env!("OUT_DIR") { od } else { return }); + let rustc = option_env!("RUSTC").unwrap_or_else(|| { "rustc".into() }); + outpath.push_str(&"/libtest_helpers.dll"); // extension for windows required, POSIX does not care. + let _ = ::std::process::Command::new(rustc) + .arg("src/test_helpers.rs") + .arg("-o") + .arg(outpath) + .arg("-O") + .output() + .expect("could not compile the test helpers!"); + }); +} + #[test] fn test_id_u32() { + make_helpers(); let lib = Library::new(LIBPATH).unwrap(); unsafe { let f: Symbol u32> = lib.get(b"test_identity_u32\0").unwrap(); @@ -23,6 +40,7 @@ struct S { #[test] fn test_id_struct() { + make_helpers(); let lib = Library::new(LIBPATH).unwrap(); unsafe { let f: Symbol S> = lib.get(b"test_identity_struct\0").unwrap(); @@ -32,6 +50,7 @@ fn test_id_struct() { #[test] fn test_0_no_0() { + make_helpers(); let lib = Library::new(LIBPATH).unwrap(); unsafe { let f: Symbol S> = lib.get(b"test_identity_struct\0").unwrap(); @@ -47,6 +66,7 @@ fn wrong_name_fails() { #[test] fn missing_symbol_fails() { + make_helpers(); let lib = Library::new(LIBPATH).unwrap(); unsafe { lib.get::<*mut ()>(b"test_does_not_exist").err().unwrap(); @@ -56,6 +76,7 @@ fn missing_symbol_fails() { #[test] fn interior_null_fails() { + make_helpers(); let lib = Library::new(LIBPATH).unwrap(); unsafe { lib.get::<*mut ()>(b"test_does\0_not_exist").err().unwrap(); @@ -66,6 +87,7 @@ fn interior_null_fails() { #[test] #[should_panic] fn test_incompatible_type() { + make_helpers(); let lib = Library::new(LIBPATH).unwrap(); unsafe { let _ = lib.get::<()>(b"test_identity_u32\0"); @@ -75,6 +97,7 @@ fn test_incompatible_type() { #[test] #[should_panic] fn test_incompatible_type_named_fn() { + make_helpers(); unsafe fn get<'a, T>(l: &'a Library, _: T) -> libloading::Result> { l.get::(b"test_identity_u32\0") } @@ -83,3 +106,46 @@ fn test_incompatible_type_named_fn() { let _ = get(&lib, test_incompatible_type_named_fn); } } + +#[test] +fn test_static_u32() { + make_helpers(); + let lib = Library::new(LIBPATH).unwrap(); + unsafe { + let var: Symbol<*mut u32> = lib.get(b"TEST_STATIC_U32\0").unwrap(); + **var = 42; + let help: Symbol u32> = lib.get(b"test_get_static_u32\0").unwrap(); + assert_eq!(42, help()); + } +} + +#[test] +fn test_static_ptr() { + make_helpers(); + let lib = Library::new(LIBPATH).unwrap(); + unsafe { + let var: Symbol<*mut *mut ()> = lib.get(b"TEST_STATIC_PTR\0").unwrap(); + **var = *var as *mut _; + let works: Symbol bool> = + lib.get(b"test_check_static_ptr\0").unwrap(); + assert!(works()); + } +} + +#[cfg(any(windows, target_os="linux"))] +#[cfg(test_nightly)] +#[test] +fn test_tls_static() { + make_helpers(); + let lib = Library::new(LIBPATH).unwrap(); + unsafe { + let var: Symbol<*mut u32> = lib.get(b"TEST_THREAD_LOCAL\0").unwrap(); + **var = 84; + let help: Symbol u32> = lib.get(b"test_get_thread_local\0").unwrap(); + assert_eq!(84, help()); + } + ::std::thread::spawn(move || unsafe { + let help: Symbol u32> = lib.get(b"test_get_thread_local\0").unwrap(); + assert_eq!(0, help()); + }).join().unwrap(); +} diff --git a/tests/statics.rs b/tests/statics.rs deleted file mode 100644 index 7a7f4e9..0000000 --- a/tests/statics.rs +++ /dev/null @@ -1,44 +0,0 @@ -extern crate libloading; -use libloading::{Symbol, Library}; - -const LIBPATH: &'static str = concat!(env!("OUT_DIR"), "/libtest_helpers.dll"); - -#[test] -fn test_static_u32() { - let lib = Library::new(LIBPATH).unwrap(); - unsafe { - let var: Symbol<*mut u32> = lib.get(b"TEST_STATIC_U32\0").unwrap(); - **var = 42; - let help: Symbol u32> = lib.get(b"test_get_static_u32\0").unwrap(); - assert_eq!(42, help()); - } -} - -#[test] -fn test_static_ptr() { - let lib = Library::new(LIBPATH).unwrap(); - unsafe { - let var: Symbol<*mut *mut ()> = lib.get(b"TEST_STATIC_PTR\0").unwrap(); - **var = *var as *mut _; - let works: Symbol bool> = - lib.get(b"test_check_static_ptr\0").unwrap(); - assert!(works()); - } -} - -#[cfg(any(windows, target_os="linux"))] -#[cfg(test_nightly)] -#[test] -fn test_tls_static() { - let lib = Library::new(LIBPATH).unwrap(); - unsafe { - let var: Symbol<*mut u32> = lib.get(b"TEST_THREAD_LOCAL\0").unwrap(); - **var = 84; - let help: Symbol u32> = lib.get(b"test_get_thread_local\0").unwrap(); - assert_eq!(84, help()); - } - ::std::thread::spawn(move || unsafe { - let help: Symbol u32> = lib.get(b"test_get_thread_local\0").unwrap(); - assert_eq!(0, help()); - }).join().unwrap(); -}