test_cdylib/lib.rs
1//! test-cdylib is a library for dynamically linking to cdylib projects from
2//! test code. This allows testing for the existence of exported items.
3//!
4//! # Testing a cdylib project
5//!
6//! A cdylib project can be tested like this:
7//!
8//! ```no_run
9//! #[test]
10//! fn api_test() {
11//! let dylib_path = test_cdylib::build_current_project();
12//!
13//! // Or load the shared library using any other method of your choice.
14//! let dylib = dlopen::symbor::Library::open(&dylib_path).unwrap();
15//!
16//! // Test the api as necessary.
17//! }
18//! ```
19//!
20//! This will build the current project, if it is not already built, and return
21//! the path to the compiled library.
22//!
23//! ## Testing a cdylib building library
24//!
25//! Libraries that are meant to help create cdylib interfaces can be tested in two
26//! ways. First is to link to an example, e.g.
27//!
28//! ```rust
29//! #[test]
30//! fn api_gen_test() {
31//! let dylib_path = test_cdylib::build_example("example");
32//!
33//! // Or load the shared library using any other method of your choice.
34//! let dylib = dlopen::symbor::Library::open(&dylib_path).unwrap();
35//!
36//! // Test the api as necessary.
37//! }
38//! ```
39//!
40//! This will build the example and return the path to the compiled library.
41//!
42//! The second way is to build a file as a cdylib, e.g.
43//!
44//! ```rust
45//! #[test]
46//! fn api_gen_test() {
47//! let dylib_path = test_cdylib::build_path("tests/cdylib/api_test.rs");
48//!
49//! // Or load the shared library using any other method of your choice.
50//! let dylib = dlopen::symbor::Library::open(&dylib_path).unwrap();
51//!
52//! // Test the api as necessary.
53//! }
54//! ```
55//!
56//! This will build the given file as a cdylib project, and return the path to
57//! the compiled library. All dependencies and dev-dependencies are available. Note
58//! that this will cause all dependencies to be rebuilt, which can slow down testing
59//! significantly.
60//!
61//! ## Multiple tests with the same library
62//!
63//! Multiple tests can link to the same library by using
64//! [once_cell](https://crates.io/crates/once_cell) to contain the path to the
65//! library, e.g.
66//!
67//! ```rust
68//! use std::path::PathBuf;
69//! use once_cell::sync::Lazy;
70//! static LIB_PATH: Lazy<PathBuf> = Lazy::new(|| test_cdylib::build_current_project());
71//! ```
72//!
73//! The same can be done for both `build_example` and `build_path`.
74
75#![forbid(unsafe_code)]
76
77use std::path::{Path, PathBuf};
78
79#[macro_use]
80mod path;
81
82mod cargo;
83mod dependencies;
84mod error;
85mod features;
86mod manifest;
87mod run;
88mod rustflags;
89
90/// Builds the given file as a cdylib and returns the path to the compiled object.
91pub fn build_file<P: AsRef<Path>>(path: P) -> PathBuf {
92 run::run(path.as_ref()).unwrap()
93}
94
95/// Builds the current project as a cdylib and returns the path to the compiled object.
96pub fn build_current_project() -> PathBuf {
97 cargo::build_self_cdylib().unwrap()
98}
99
100/// Builds the given example as a cdylib and returns the path to the compiled object.
101pub fn build_example(name: &str) -> PathBuf {
102 cargo::build_example(name).unwrap()
103}