use std::process::ExitCode;
#[cfg(any(feature = "pkg-config", feature = "vcpkg"))]
enum LibraryResult<E, L> {
Skipped(E),
Failed(E),
Success(L),
}
#[cfg(feature = "pkg-config")]
fn try_pkgconfig() -> LibraryResult<pkg_config::Error, pkg_config::Library> {
let lib = pkg_config::Config::new()
.atleast_version("5.39")
.probe("libmagic");
match lib {
Err(err) => match err {
pkg_config::Error::EnvNoPkgConfig(_) => LibraryResult::Skipped(err),
_ => LibraryResult::Failed(err),
},
Ok(lib) => LibraryResult::Success(lib),
}
}
#[cfg(feature = "vcpkg")]
fn try_vcpkg() -> LibraryResult<vcpkg::Error, vcpkg::Library> {
let lib = vcpkg::find_package("libmagic");
match lib {
Err(err) => match err {
vcpkg::Error::DisabledByEnv(_) => LibraryResult::Skipped(err),
_ => LibraryResult::Failed(err),
},
Ok(lib) => {
println!("cargo:rustc-link-lib=shlwapi");
LibraryResult::Success(lib)
}
}
}
fn main() -> ExitCode {
if std::env::var("DOCS_RS").is_ok() {
println!("docs.rs detected, skipping build script");
return ExitCode::SUCCESS;
}
#[cfg(feature = "pkg-config")]
{
let lib = try_pkgconfig();
match lib {
LibraryResult::Skipped(err) => {
println!("pkg-config skipped: {err}");
}
LibraryResult::Failed(err) => {
println!("cargo:warning=pkg-config failed: {err}");
}
LibraryResult::Success(lib) => {
let includes = std::env::join_paths(lib.include_paths.iter())
.expect("parsed include paths from `pkg-config` should be joinable");
if includes.is_empty() {
let includedir = pkg_config::get_variable("libmagic", "includedir")
.expect("`pkg-config` package 'libmagic' should be found previously");
println!("cargo:include={includedir}");
} else {
println!("cargo:include={}", includes.to_string_lossy());
}
println!("pkg-config success: {lib:?}");
return ExitCode::SUCCESS;
}
}
}
#[cfg(not(feature = "pkg-config"))]
println!("pkg-config feature disabled");
#[cfg(feature = "vcpkg")]
{
let lib = try_vcpkg();
match lib {
LibraryResult::Skipped(err) => {
println!("vcpkg skipped: {err}");
}
LibraryResult::Failed(err) => {
println!("cargo:warning=vcpkg failed: {err}");
}
LibraryResult::Success(lib) => {
let includes = std::env::join_paths(lib.include_paths.iter())
.expect("include paths from `vcpkg` should be joinable");
if !includes.is_empty() {
println!("cargo:include={}", includes.to_string_lossy());
}
println!("vcpkg success: {lib:?}");
return ExitCode::SUCCESS;
}
}
}
#[cfg(not(feature = "vcpkg"))]
println!("vcpkg feature disabled");
#[cfg(not(any(feature = "pkg-config", feature = "vcpkg")))]
eprintln!(
"the pkg-config and vcpkg features are both disabled, \
this configuration requires you to override the build script: \
https://crates.io/crates/magic#override"
);
eprintln!("could not link to `libmagic`");
ExitCode::FAILURE
}