Mercurial > crates > nonstick
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 109:bb465393621f | 110:2346fd501b7a |
|---|---|
| 1 //! This absurd build script basically sets up everything for libpam-sys-impl. | |
| 2 //! | |
| 3 //! 1. It's the definition site for the [`PamImpl`] enum, which then gets | |
| 4 //! output to the `OUT_DIR/pam_impl_enum.rs` file for parsing/inclusion | |
| 5 //! into the `__pam_impl_enum__` macro. | |
| 6 //! 2. It detects the current PAM implementation and sets an env var for | |
| 7 //! the macros in `libpam-sys-impl`. | |
| 8 | |
| 9 use std::{env, fs}; | |
| 1 use strum::EnumString; | 10 use strum::EnumString; |
| 11 use proc_macro2::TokenStream; | |
| 12 use quote::quote; | |
| 2 | 13 |
| 3 fn main() { | 14 fn main() { |
| 4 let pam_impl = match option_env!("LIBPAMSYS_IMPL") { | 15 let pam_impl = match option_env!("LIBPAMSYS_IMPL") { |
| 5 // The default option: Guess what PAM impl we're using based on OS. | 16 // The default option: Guess what PAM impl we're using based on OS. |
| 6 None => { | 17 None => { |
| 7 // Otherwise, guess what PAM impl we're using based on the OS. | |
| 8 if cfg!(target_os = "linux") { | 18 if cfg!(target_os = "linux") { |
| 9 PamImpl::LinuxPam | 19 PamImpl::LinuxPam |
| 10 } else if cfg!(any( | 20 } else if cfg!(any( |
| 11 target_os = "macos", | 21 target_os = "macos", |
| 12 target_os = "freebsd", | 22 target_os = "freebsd", |
| 13 target_os = "netbsd", | 23 target_os = "netbsd", |
| 14 target_os = "dragonfly", | 24 target_os = "dragonfly", |
| 15 target_os = "openbsd" | 25 target_os = "openbsd" |
| 16 )) { | 26 )) { |
| 17 PamImpl::OpenPam | 27 PamImpl::OpenPam |
| 18 } else if cfg!(any()) { | 28 } else if cfg!(any( |
| 19 PamImpl::Illumos | 29 target_os = "illumos", |
| 30 target_os = "solaris", | |
| 31 )) { | |
| 32 PamImpl::Sun | |
| 20 } else { | 33 } else { |
| 21 PamImpl::MinimalOpenPam | 34 PamImpl::MinimalOpenPam |
| 22 } | 35 } |
| 23 } | 36 } |
| 24 Some("_detect") => { | 37 Some("_detect") => { |
| 26 if header_exists("security/_pam_types.h") { | 39 if header_exists("security/_pam_types.h") { |
| 27 PamImpl::LinuxPam | 40 PamImpl::LinuxPam |
| 28 } else if header_exists("security/openpam.h") { | 41 } else if header_exists("security/openpam.h") { |
| 29 PamImpl::OpenPam | 42 PamImpl::OpenPam |
| 30 } else if header_exists("security/pam_appl.h") { | 43 } else if header_exists("security/pam_appl.h") { |
| 31 // We figure we're *probably* on Illumos or something like that. | 44 // We figure we're *probably* on a Sun derivative. |
| 32 PamImpl::Illumos | 45 PamImpl::Sun |
| 33 } else { | 46 } else { |
| 34 // If all else fails, assume the bare minimum. | 47 // If all else fails, assume the bare minimum. |
| 35 PamImpl::MinimalOpenPam | 48 PamImpl::MinimalOpenPam |
| 36 } | 49 } |
| 37 } | 50 } |
| 38 Some(other) => match PamImpl::try_from(other) { | 51 Some(other) => match PamImpl::try_from(other) { |
| 39 Ok(i) => i, | 52 Ok(i) => i, |
| 40 Err(_) => panic!("unknown PAM implementation {other:?}"), | 53 Err(_) => panic!("unknown PAM implementation {other:?}"), |
| 41 }, | 54 }, |
| 42 }; | 55 }; |
| 56 fs::write(format!("{}/pam_impl_enum.rs", env::var("OUT_DIR").unwrap()), PamImpl::enum_tokens().to_string()).unwrap(); | |
| 43 println!("cargo:rustc-env=LIBPAMSYS_IMPL={pam_impl:?}"); | 57 println!("cargo:rustc-env=LIBPAMSYS_IMPL={pam_impl:?}"); |
| 44 } | 58 } |
| 45 | 59 |
| 46 #[derive(Debug, EnumString)] | 60 /// This defines a local enum with an `enum_tokens()` method that can spit out |
| 47 enum PamImpl { | 61 /// its own contents. |
| 48 Illumos, | 62 macro_rules! self_aware_enum { |
| 49 LinuxPam, | 63 ( |
| 50 OpenPam, | 64 $(#here[$here:meta])* |
| 51 MinimalOpenPam, | 65 $(#[$attr:meta])* |
| 66 $name:ident { | |
| 67 $($tt:tt)* | |
| 68 } | |
| 69 ) => { | |
| 70 $(#[$here])* | |
| 71 $(#[$attr])* | |
| 72 pub enum $name { | |
| 73 $($tt)* | |
| 74 } | |
| 75 | |
| 76 impl $name { | |
| 77 fn enum_tokens() -> TokenStream { | |
| 78 quote!( | |
| 79 $(#[$attr])* | |
| 80 pub enum $name { | |
| 81 $($tt)* | |
| 82 } | |
| 83 ) | |
| 84 } | |
| 85 } | |
| 86 } | |
| 52 } | 87 } |
| 88 | |
| 89 self_aware_enum!( | |
| 90 #here[derive(EnumString, strum::Display)] | |
| 91 /// The PAM implementations supported by `libpam-sys`. | |
| 92 #[derive(Clone, Copy, Debug, PartialEq)] | |
| 93 PamImpl { | |
| 94 /// [Linux-PAM] is provided by most Linux distributions. | |
| 95 /// | |
| 96 /// [Linux-PAM]: https://github.com/linux-pam/linux-pam | |
| 97 LinuxPam, | |
| 98 /// [OpenPAM] is used by most BSDs, including Mac OS X. | |
| 99 /// | |
| 100 /// [OpenPAM]: https://git.des.dev/OpenPAM/OpenPAM | |
| 101 OpenPam, | |
| 102 /// Illumos and Solaris use a derivative of [Sun's implementation][sun]. | |
| 103 /// | |
| 104 /// [sun]: https://code.illumos.org/plugins/gitiles/illumos-gate/+/refs/heads/master/usr/src/lib/libpam | |
| 105 Sun, | |
| 106 /// Only the functionality in [the PAM spec], with OpenPAM/Sun consts. | |
| 107 /// | |
| 108 /// [the PAM spec]: https://pubs.opengroup.org/onlinepubs/8329799/toc.htm | |
| 109 MinimalOpenPam, | |
| 110 } | |
| 111 ); | |
| 53 | 112 |
| 54 fn header_exists(header: &str) -> bool { | 113 fn header_exists(header: &str) -> bool { |
| 55 bindgen::Builder::default() | 114 bindgen::Builder::default() |
| 56 .blocklist_item(".*") | 115 .blocklist_item(".*") |
| 57 .header_contents("header.h", &format!("#include <{header}>")) | 116 .header_contents("header.h", &format!("#include <{header}>")) |
