Build only the PAM hook on macOS (0.10.2)

The gtklock module is Wayland-only and its GNU ld link flags
(--whole-archive) do not exist on macOS, so the macOS build stopped
there. macOS now builds just the PAM hook and the display binary, which
is all the Homebrew formula installs; libdl is optional (it is part of
libSystem on macOS).

Claude-Session: https://claude.ai/code/session_012LCTmU2ewo8tnM1dByYAoG
This commit is contained in:
Asger Geel Weirsøe
2026-09-30 21:59:59 +02:00
parent 198bbb2278
commit d5e1bd5016
3 changed files with 58 additions and 48 deletions
Generated
+1 -1
View File
@@ -10,7 +10,7 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]] [[package]]
name = "ahfail" name = "ahfail"
version = "0.10.1" version = "0.10.2"
dependencies = [ dependencies = [
"ahfail-ui", "ahfail-ui",
"cc", "cc",
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "ahfail" name = "ahfail"
version = "0.10.1" version = "0.10.2"
edition = "2021" edition = "2021"
description = "Screen locker that says ah ah ah when you get the password wrong" description = "Screen locker that says ah ah ah when you get the password wrong"
license = "AGPL-3.0-only" license = "AGPL-3.0-only"
+36 -26
View File
@@ -1,7 +1,7 @@
project( project(
'ahfail', 'ahfail',
['c', 'rust'], ['c', 'rust'],
version: '0.10.1', version: '0.10.2',
meson_version: '>=1.3.0', meson_version: '>=1.3.0',
default_options: ['warning_level=3', 'c_std=c11'] default_options: ['warning_level=3', 'c_std=c11']
) )
@@ -9,17 +9,7 @@ project(
ahfail_inc = include_directories('include') ahfail_inc = include_directories('include')
cc = meson.get_compiler('c') cc = meson.get_compiler('c')
m_dep = cc.find_library('m', required : false) is_linux = host_machine.system() == 'linux'
gtk_dep = dependency('gtk+-3.0')
gstplayer_dep = dependency('gstreamer-player-1.0')
gnome = import('gnome')
resources = gnome.compile_resources(
'ahfail-resources',
'assets/ahfail.gresource.xml',
source_dir: 'assets',
c_name: 'ahfail'
)
# All Rust artefacts come from ONE cargo invocation with one target directory. # All Rust artefacts come from ONE cargo invocation with one target directory.
# Four separate builds with four target directories compiled the whole GTK and # Four separate builds with four target directories compiled the whole GTK and
@@ -30,19 +20,29 @@ resources = gnome.compile_resources(
# client is not compiled in at all. # client is not compiled in at all.
cargo_features = get_option('update_check') ? '' : '--no-default-features' cargo_features = get_option('update_check') ? '' : '--no-default-features'
# The ahfail command is the Linux locker (Wayland/X11 + its own PAM service). # Linux builds everything: the ahfail locker, the gtklock module (Wayland), the
# macOS keeps the PAM hook and is built without it until it has been tested there. # PAM hook and its display binary. macOS only has the PAM hook + display binary:
is_linux = host_machine.system() == 'linux' # gtklock and the locker are Linux-only, and the module's GNU-ld link flags do
cargo_pkgs = '-p ahfail-gtklock -p ahfail-pam -p ahfail-display' + (is_linux ? ' -p ahfail' : '') # not exist on macOS.
cargo_outputs = ['libahfail_module.a', 'libahfail_pam.so', 'ahfail-display'] + (is_linux ? ['ahfail'] : [])
cargo_install_dirs = [false, get_option('libdir') / 'ahfail', get_option('libdir') / 'ahfail'] + (is_linux ? [get_option('bindir')] : [])
# Cargo names a cdylib .dylib on macOS. The installed name stays # Cargo names a cdylib .dylib on macOS. The installed name stays
# libahfail_pam.so: PAM loads the module by path, whatever the extension. # libahfail_pam.so: PAM loads the module by path, whatever the extension.
pam_built = host_machine.system() == 'darwin' ? 'libahfail_pam.dylib' : 'libahfail_pam.so' pam_built = host_machine.system() == 'darwin' ? 'libahfail_pam.dylib' : 'libahfail_pam.so'
if is_linux
cargo_pkgs = '-p ahfail-gtklock -p ahfail-pam -p ahfail-display -p ahfail'
cargo_outputs = ['libahfail_module.a', 'libahfail_pam.so', 'ahfail-display', 'ahfail']
# module archive: linked below, not installed; PAM hook + display: libdir/ahfail; locker: bindir.
cargo_install_dirs = [false, get_option('libdir') / 'ahfail', get_option('libdir') / 'ahfail', get_option('bindir')]
cargo_copy = (' && cp "@OUTDIR@/target/release/libahfail_module.a" "@OUTPUT0@"' cargo_copy = (' && cp "@OUTDIR@/target/release/libahfail_module.a" "@OUTPUT0@"'
+ ' && cp "@OUTDIR@/target/release/' + pam_built + '" "@OUTPUT1@"' + ' && cp "@OUTDIR@/target/release/libahfail_pam.so" "@OUTPUT1@"'
+ ' && cp "@OUTDIR@/target/release/ahfail-display" "@OUTPUT2@"' + ' && cp "@OUTDIR@/target/release/ahfail-display" "@OUTPUT2@"'
+ (is_linux ? ' && cp "@OUTDIR@/target/release/ahfail" "@OUTPUT3@"' : '')) + ' && cp "@OUTDIR@/target/release/ahfail" "@OUTPUT3@"')
else
cargo_pkgs = '-p ahfail-pam -p ahfail-display'
cargo_outputs = ['libahfail_pam.so', 'ahfail-display']
cargo_install_dirs = [get_option('libdir') / 'ahfail', get_option('libdir') / 'ahfail']
cargo_copy = (' && cp "@OUTDIR@/target/release/' + pam_built + '" "@OUTPUT0@"'
+ ' && cp "@OUTDIR@/target/release/ahfail-display" "@OUTPUT1@"')
endif
cargo_all = custom_target( cargo_all = custom_target(
'ahfail-cargo-build', 'ahfail-cargo-build',
@@ -61,13 +61,10 @@ cargo_all = custom_target(
build_by_default: true, build_by_default: true,
build_always_stale: true, # cargo decides what is out of date, not meson build_always_stale: true, # cargo decides what is out of date, not meson
install: true, install: true,
# module archive: linked below, not installed; PAM module + display binary:
# libdir/ahfail; the ahfail command: bindir.
install_dir: cargo_install_dirs, install_dir: cargo_install_dirs,
install_mode: 'rwxr-xr-x' install_mode: 'rwxr-xr-x'
) )
cargo_target = cargo_all[0] pam_cargo = is_linux ? cargo_all[1] : cargo_all[0]
pam_cargo = cargo_all[1]
# The locker's own PAM service. Shipped as its own file, like swaylock and # The locker's own PAM service. Shipped as its own file, like swaylock and
# gtklock do, so no other package's PAM configuration is ever touched. # gtklock do, so no other package's PAM configuration is ever touched.
@@ -78,11 +75,23 @@ if is_linux
) )
endif endif
if is_linux
m_dep = cc.find_library('m', required : false)
gtk_dep = dependency('gtk+-3.0')
gstplayer_dep = dependency('gstreamer-player-1.0')
resources = import('gnome').compile_resources(
'ahfail-resources',
'assets/ahfail.gresource.xml',
source_dir: 'assets',
c_name: 'ahfail'
)
# The gtklock module (Wayland): the Rust staticlib linked whole into a .so.
libahfail = shared_library( libahfail = shared_library(
'ahfail-module', 'ahfail-module',
resources, resources,
link_args: ['-Wl,--whole-archive', meson.current_build_dir() / 'libahfail_module.a', '-Wl,--no-whole-archive'], link_args: ['-Wl,--whole-archive', meson.current_build_dir() / 'libahfail_module.a', '-Wl,--no-whole-archive'],
link_depends: cargo_target, link_depends: cargo_all[0],
include_directories: ahfail_inc, include_directories: ahfail_inc,
dependencies: [gtk_dep, gstplayer_dep, m_dep], dependencies: [gtk_dep, gstplayer_dep, m_dep],
install: true, install: true,
@@ -99,12 +108,13 @@ smoke = executable(
) )
test('module symbols', smoke) test('module symbols', smoke)
endif
# PAM module smoke test: dlopen libahfail_pam.so and verify pam_sm_authenticate is exported. # PAM module smoke test: dlopen libahfail_pam.so and verify pam_sm_authenticate is exported.
pam_smoke = executable( pam_smoke = executable(
'pam_smoke_test', 'pam_smoke_test',
'tests/pam_smoke_test.c', 'tests/pam_smoke_test.c',
dependencies: [cc.find_library('dl', required: true)] dependencies: [cc.find_library('dl', required: false)] # part of libSystem on macOS
) )
test('pam symbols', pam_smoke, test('pam symbols', pam_smoke,