Mercurial > crates > nonstick
view libpam-sys/build.rs @ 134:6c1e1bdb4164
Use standard #[cfg] directives rather than custom proc macros.
Instead of having to do a bunch of custom parsing and other logic
that tools often choke on, this change introduces an easy way
to depend upon custom #[cfg]s provided by the libpam-sys crate.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Thu, 03 Jul 2025 11:03:36 -0400 |
parents | a632a8874131 |
children | efbc235f01d3 |
line wrap: on
line source
#![allow(unexpected_cfgs)] use std::env; use std::ffi::{c_void, CString}; use std::fs; use std::ptr::NonNull; include!("src/pam_impl.rs"); fn main() { println!("cargo:rustc-link-lib=pam"); let pam_impl = match option_env!("LIBPAMSYS_IMPL") { // The default option: Guess what PAM impl we're using based on OS. None | Some("") => detect(), Some(other) => match PamImpl::try_from(other) { Ok(i) => i, Err(_) => { panic!( "unknown PAM implementation {other:?}. valid LIBPAMSYS_IMPLs are {:?}, or unset to detect", PamImpl::items() ) } }, }; println!("{}", checkcfg()); let impl_str = format!("{pam_impl:?}"); println!("{}", implcfg(&impl_str)); println!("cargo:rustc-env=LIBPAMSYS_IMPL={impl_str}"); fs::write( format!("{}/pam_impl_const.rs", env::var("OUT_DIR").unwrap()), format!( "\ impl PamImpl {{\ /// The implementation of libpam this was built for (`{impl_str}`). pub const CURRENT: Self = Self::{impl_str};\ /// String version for internal consumption. const CURRENT_STR: &'static str = {impl_str:?};\ }} " ), ) .unwrap(); } fn detect() -> PamImpl { if let Some(lib) = LibPam::open() { if lib.has("pam_syslog") { return PamImpl::LinuxPam; } else if lib.has("_openpam_log") { return PamImpl::OpenPam; } else if lib.has("__pam_get_authtok") { return PamImpl::Sun; } } 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 if cfg!(any(target_os = "illumos", target_os = "solaris")) { PamImpl::Sun } else { PamImpl::XSso } } struct LibPam(NonNull<c_void>); impl LibPam { fn open() -> Option<Self> { NonNull::new(unsafe { libc::dlopen(b"libpam.so\0".as_ptr().cast(), libc::RTLD_LAZY) }) .map(Self) } fn has(&self, name: &str) -> bool { let name = CString::new(name).unwrap(); let symbol = unsafe { libc::dlsym(self.0.as_ptr(), name.as_ptr()) }; !symbol.is_null() } } impl Drop for LibPam { fn drop(&mut self) { unsafe { libc::dlclose(self.0.as_ptr()); } } }