use crate::BuildScript;
use crate::{
cargo_rustc_link_lib as cargo_rustc_link_lib_,
cargo_rustc_link_search as cargo_rustc_link_search_,
};
use once_cell::sync::Lazy;
use std::path::PathBuf;
use std::sync::{LockResult, Mutex, MutexGuard};
static BUILD_SCRIPT: Lazy<Mutex<BuildScript>> = Lazy::new(|| {
let mut build_script = BuildScript::default();
build_script.now();
Mutex::new(build_script)
});
fn lock_mutex<T>(lock: LockResult<MutexGuard<T>>) -> MutexGuard<T> {
lock.expect("mutex is poisoned")
}
fn build_script() -> MutexGuard<'static, BuildScript<'static>> {
lock_mutex(BUILD_SCRIPT.lock())
}
pub fn cargo_rerun_if_changed(path: impl Into<PathBuf>) {
build_script().cargo_rerun_if_changed(path.into());
}
pub fn cargo_rerun_if_env_changed(var: impl Into<String>) {
build_script().cargo_rerun_if_env_changed(&var.into());
}
pub fn cargo_rustc_link_lib(name: impl Into<String>) {
build_script().cargo_rustc_link_lib(None, &name.into());
}
pub fn cargo_rustc_link_lib_mapping(kind: cargo_rustc_link_lib_::Kind, name: impl Into<String>) {
build_script().cargo_rustc_link_lib(kind.into(), &name.into());
}
pub fn cargo_rustc_link_search(path: impl Into<PathBuf>) {
build_script().cargo_rustc_link_search(None, path.into());
}
pub fn cargo_rustc_link_search_mapping(
kind: cargo_rustc_link_search_::Kind,
path: impl Into<PathBuf>,
) {
build_script().cargo_rustc_link_search(kind.into(), path.into());
}
pub fn cargo_rustc_flags(flags: impl Into<String>) {
build_script().cargo_rustc_flags(&flags.into());
}
pub fn cargo_rustc_cfg(key: impl Into<String>) {
build_script().cargo_rustc_cfg(&key.into(), None);
}
pub fn cargo_rustc_cfg_mapping(key: impl Into<String>, value: impl Into<String>) {
build_script().cargo_rustc_cfg(&key.into(), Some(&value.into()));
}
pub fn cargo_rustc_env(var: impl Into<String>, value: impl Into<String>) {
build_script().cargo_rustc_env(&var.into(), &value.into());
}
pub fn cargo_rustc_cdylib_link_arg(flag: impl Into<String>) {
build_script().cargo_rustc_cdylib_link_arg(&flag.into());
}
pub fn cargo_warning(message: impl Into<String>) {
build_script().cargo_warning(&message.into());
}
pub fn cargo_mapping(key: impl Into<String>, value: impl Into<String>) {
build_script().cargo_mapping(&key.into(), &value.into());
}
#[cfg(test)]
mod tests {
use gag::BufferRedirect;
use serial_test::serial;
use std::io::Read;
fn test(func: impl Fn(), expected: &str) -> bool {
let mut output = String::new();
let mut buffer = BufferRedirect::stdout().unwrap();
func();
buffer.read_to_string(&mut output).unwrap();
output.contains(expected)
}
macro_rules! new_test {
($name:ident, $func:expr, $expected:literal) => {
#[test]
#[serial]
fn $name() {
assert!(test($func, $expected))
}
};
}
new_test!(
test_cargo_rerun_if_changed,
|| super::cargo_rerun_if_changed("path"),
"cargo:rerun-if-changed=path"
);
new_test!(
test_cargo_rerun_if_env_changed,
|| super::cargo_rerun_if_env_changed("var"),
"cargo:rerun-if-env-changed=var"
);
new_test!(
test_cargo_rustc_link_lib,
|| super::cargo_rustc_link_lib("name"),
"cargo:rustc-link-lib=name"
);
#[test]
#[serial]
fn test_cargo_rustc_link_lib_mapping() {
use crate::cargo_rustc_link_lib::Kind;
let kinds = [Kind::Framework, Kind::Static, Kind::DynamicLibrary];
for &kind in kinds.iter() {
assert!(test(
|| super::cargo_rustc_link_lib_mapping(kind, "name"),
&format!("cargo:rustc-link-lib={}=name", {
let kind: String = kind.into();
kind
})
))
}
}
new_test!(
test_cargo_rustc_link_search,
|| super::cargo_rustc_link_search("path"),
"cargo:rustc-link-search=path"
);
#[test]
#[serial]
fn test_cargo_rustc_link_search_mapping() {
use crate::cargo_rustc_link_search::Kind;
let kinds = [
Kind::Framework,
Kind::All,
Kind::Crate,
Kind::Dependency,
Kind::Native,
];
for &kind in kinds.iter() {
assert!(test(
|| super::cargo_rustc_link_search_mapping(kind, "path"),
&format!("cargo:rustc-link-search={}=path", {
let kind: String = kind.into();
kind
})
))
}
}
new_test!(
test_cargo_rustc_flags,
|| super::cargo_rustc_flags("flags"),
"cargo:rustc-flags=flags"
);
new_test!(
test_cargo_rustc_cfg,
|| super::cargo_rustc_cfg("key"),
"cargo:rustc-cfg=key"
);
new_test!(
test_cargo_rustc_cfg_mapping,
|| super::cargo_rustc_cfg_mapping("key", "value"),
"cargo:rustc-cfg=key=\"value\""
);
new_test!(
test_cargo_rustc_env,
|| super::cargo_rustc_env("var", "value"),
"cargo:rustc-env=var=value"
);
new_test!(
test_cargo_rustc_cdylib_link_arg,
|| super::cargo_rustc_cdylib_link_arg("flag"),
"cargo:rustc-cdylib-link-arg=flag"
);
new_test!(
test_cargo_warning,
|| super::cargo_warning("message"),
"cargo:warning=message"
);
new_test!(
test_cargo_mapping,
|| super::cargo_mapping("key", "value"),
"cargo:key=value"
);
}