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}>")) |