Mercurial > crates > nonstick
view libpam-sys/build.rs @ 107:49c6633f6fd2
Add Cargo.lock file.
This ensures that we get reproducible builds, particularly because
we want to support Rust v1.75.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Thu, 26 Jun 2025 22:42:32 -0400 |
parents | 49d9e2b5c189 |
children | e97534be35e3 |
line wrap: on
line source
use bindgen::MacroTypeVariation; use std::error::Error; use std::fmt::{Debug, Display, Formatter}; use std::path::PathBuf; use std::{env, fs}; enum PamImpl { Illumos, LinuxPam, OpenPam, } #[derive(Debug)] struct InvalidEnum(String); impl Display for InvalidEnum { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "invalid PAM impl {:?}", self.0) } } impl Error for InvalidEnum {} impl TryFrom<&str> for PamImpl { type Error = InvalidEnum; fn try_from(value: &str) -> Result<Self, Self::Error> { Ok(match value { "illumos" => Self::Illumos, "linux-pam" => Self::LinuxPam, "openpam" => Self::OpenPam, other => return Err(InvalidEnum(other.to_owned())), }) } } impl Debug for PamImpl { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { Debug::fmt( match self { Self::Illumos => "illumos", Self::LinuxPam => "linux-pam", Self::OpenPam => "openpam", }, f, ) } } fn main() { println!("cargo:rustc-link-lib=pam"); let out_file = PathBuf::from(env::var("OUT_DIR").unwrap()).join("constants.rs"); let pam_impl = do_detection(); if cfg!(feature = "use-system-headers") { let builder = bindgen::Builder::default() .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) .blocklist_function(".*") .blocklist_type(".*") .allowlist_var(".*") .default_macro_constant_type(MacroTypeVariation::Unsigned); let builder = match pam_impl { PamImpl::Illumos => builder.header_contents( "illumos.h", "\ #include <security/pam_appl.h> #include <security/pam_modules.h> ", ), PamImpl::LinuxPam => builder.header_contents( "linux-pam.h", "\ #include <security/_pam_types.h> #include <security/pam_appl.h> #include <security/pam_ext.h> #include <security/pam_modules.h> ", ), PamImpl::OpenPam => builder.header_contents( "openpam.h", "\ #include <security/pam_types.h> #include <security/openpam.h> #include <security/pam_appl.h> #include <security/pam_constants.h> ", ), }; let bindings = builder.generate().unwrap(); bindings.write_to_file(out_file).unwrap(); } else { // Just write empty data to the file to avoid conditional compilation // shenanigans. fs::write(out_file, "").unwrap(); } } fn do_detection() -> PamImpl { println!(r#"cargo:rustc-check-cfg=cfg(pam_impl, values("illumos", "linux-pam", "openpam"))"#); let pam_impl = _detect_internal(); println!("cargo:rustc-cfg=pam_impl={pam_impl:?}"); pam_impl } fn _detect_internal() -> PamImpl { if let Some(pam_impl) = option_env!("LIBPAMSYS_PAM_IMPL") { pam_impl.try_into().unwrap() } else if cfg!(feature = "use-system-headers") { // Detect which impl it is from system headers. if header_exists("security/_pam_types.h") { PamImpl::LinuxPam } else if header_exists("security/openpam.h") { PamImpl::OpenPam } else if header_exists("security/pam_appl.h") { PamImpl::Illumos } else { panic!("could not detect PAM implementation") } } else { // Otherwise, guess what PAM impl we're using based on the OS. if cfg!(target_os = "linux") { PamImpl::LinuxPam } else if cfg!(any( target_os = "macos", target_os = "freebsd", target_os = "netbsd", target_os = "dragonfly", target_os = "openbsd" )) { PamImpl::OpenPam } else { PamImpl::Illumos } } } fn header_exists(header: &str) -> bool { bindgen::Builder::default() .blocklist_item(".*") .header_contents("header.h", &format!("#include <{header}>")) .generate() .is_ok() }