Mercurial > crates > nonstick
view libpam-sys/libpam-sys-impls/build.rs @ 110:2346fd501b7a
Add tests for constants and do other macro niceties.
- Adds tests for all the constants. Pretty sweet.
- Moves documentation for cfg-pam-impl macro to `libpam-sys`.
- Renames `Illumos` to `Sun`.
- other stuff
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Sun, 29 Jun 2025 02:15:46 -0400 |
parents | bb465393621f |
children | 178310336596 |
line wrap: on
line source
//! This absurd build script basically sets up everything for libpam-sys-impl. //! //! 1. It's the definition site for the [`PamImpl`] enum, which then gets //! output to the `OUT_DIR/pam_impl_enum.rs` file for parsing/inclusion //! into the `__pam_impl_enum__` macro. //! 2. It detects the current PAM implementation and sets an env var for //! the macros in `libpam-sys-impl`. use std::{env, fs}; use strum::EnumString; use proc_macro2::TokenStream; use quote::quote; fn main() { let pam_impl = match option_env!("LIBPAMSYS_IMPL") { // The default option: Guess what PAM impl we're using based on OS. None => { 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::MinimalOpenPam } } Some("_detect") => { // 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") { // We figure we're *probably* on a Sun derivative. PamImpl::Sun } else { // If all else fails, assume the bare minimum. PamImpl::MinimalOpenPam } } Some(other) => match PamImpl::try_from(other) { Ok(i) => i, Err(_) => panic!("unknown PAM implementation {other:?}"), }, }; fs::write(format!("{}/pam_impl_enum.rs", env::var("OUT_DIR").unwrap()), PamImpl::enum_tokens().to_string()).unwrap(); println!("cargo:rustc-env=LIBPAMSYS_IMPL={pam_impl:?}"); } /// This defines a local enum with an `enum_tokens()` method that can spit out /// its own contents. macro_rules! self_aware_enum { ( $(#here[$here:meta])* $(#[$attr:meta])* $name:ident { $($tt:tt)* } ) => { $(#[$here])* $(#[$attr])* pub enum $name { $($tt)* } impl $name { fn enum_tokens() -> TokenStream { quote!( $(#[$attr])* pub enum $name { $($tt)* } ) } } } } self_aware_enum!( #here[derive(EnumString, strum::Display)] /// The PAM implementations supported by `libpam-sys`. #[derive(Clone, Copy, Debug, PartialEq)] PamImpl { /// [Linux-PAM] is provided by most Linux distributions. /// /// [Linux-PAM]: https://github.com/linux-pam/linux-pam LinuxPam, /// [OpenPAM] is used by most BSDs, including Mac OS X. /// /// [OpenPAM]: https://git.des.dev/OpenPAM/OpenPAM OpenPam, /// Illumos and Solaris use a derivative of [Sun's implementation][sun]. /// /// [sun]: https://code.illumos.org/plugins/gitiles/illumos-gate/+/refs/heads/master/usr/src/lib/libpam Sun, /// Only the functionality in [the PAM spec], with OpenPAM/Sun consts. /// /// [the PAM spec]: https://pubs.opengroup.org/onlinepubs/8329799/toc.htm MinimalOpenPam, } ); fn header_exists(header: &str) -> bool { bindgen::Builder::default() .blocklist_item(".*") .header_contents("header.h", &format!("#include <{header}>")) .generate() .is_ok() }