diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpam-sys/libpam-sys-impls/build.rs	Sat Jun 28 00:34:45 2025 -0400
@@ -0,0 +1,60 @@
+use strum::EnumString;
+
+fn main() {
+    let pam_impl = match option_env!("LIBPAMSYS_IMPL") {
+        // The default option: Guess what PAM impl we're using based on OS.
+        None => {
+            // Otherwise, guess what PAM impl we're using based on the OS.
+            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()) {
+                PamImpl::Illumos
+            } 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 Illumos or something like that.
+                PamImpl::Illumos
+            } 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:?}")
+        }
+    };
+    println!("cargo:rustc-env=LIBPAMSYS_IMPL={pam_impl:?}");
+}
+
+#[derive(Debug, EnumString)]
+enum PamImpl {
+    Illumos,
+    LinuxPam,
+    OpenPam,
+    MinimalOpenPam,
+}
+
+fn header_exists(header: &str) -> bool {
+    bindgen::Builder::default()
+        .blocklist_item(".*")
+        .header_contents("header.h", &format!("#include <{header}>"))
+        .generate()
+        .is_ok()
+}