comparison libpam-sys/libpam-sys-impls/build.rs @ 108:e97534be35e3

Make some proc macros for doing cfg-like stuff for PAM impls.
author Paul Fisher <paul@pfish.zone>
date Sat, 28 Jun 2025 00:34:45 -0400
parents
children bb465393621f
comparison
equal deleted inserted replaced
107:49c6633f6fd2 108:e97534be35e3
1 use strum::EnumString;
2
3 fn main() {
4 let pam_impl = match option_env!("LIBPAMSYS_IMPL") {
5 // The default option: Guess what PAM impl we're using based on OS.
6 None => {
7 // Otherwise, guess what PAM impl we're using based on the OS.
8 if cfg!(target_os = "linux") {
9 PamImpl::LinuxPam
10 } else if cfg!(any(
11 target_os = "macos",
12 target_os = "freebsd",
13 target_os = "netbsd",
14 target_os = "dragonfly",
15 target_os = "openbsd"
16 )) {
17 PamImpl::OpenPam
18 } else if cfg!(any()) {
19 PamImpl::Illumos
20 } else {
21 PamImpl::MinimalOpenPam
22 }
23 }
24 Some("_detect") => {
25 // Detect which impl it is from system headers.
26 if header_exists("security/_pam_types.h") {
27 PamImpl::LinuxPam
28 } else if header_exists("security/openpam.h") {
29 PamImpl::OpenPam
30 } else if header_exists("security/pam_appl.h") {
31 // We figure we're *probably* on Illumos or something like that.
32 PamImpl::Illumos
33 } else {
34 // If all else fails, assume the bare minimum.
35 PamImpl::MinimalOpenPam
36 }
37 }
38 Some(other) => match PamImpl::try_from(other) {
39 Ok(i) => i,
40 Err(_) => panic!("unknown PAM implementation {other:?}")
41 }
42 };
43 println!("cargo:rustc-env=LIBPAMSYS_IMPL={pam_impl:?}");
44 }
45
46 #[derive(Debug, EnumString)]
47 enum PamImpl {
48 Illumos,
49 LinuxPam,
50 OpenPam,
51 MinimalOpenPam,
52 }
53
54 fn header_exists(header: &str) -> bool {
55 bindgen::Builder::default()
56 .blocklist_item(".*")
57 .header_contents("header.h", &format!("#include <{header}>"))
58 .generate()
59 .is_ok()
60 }