Skip to content

Commit

Permalink
Convert script to Swift Package Manager library (#5)
Browse files Browse the repository at this point in the history
* Convert to Swift Package Manager module

* Update Makefile to use SPM build

This also avoids the incredibly cursed SDK parsing

* Switch from a Swift version check to a module import check

The check for the Swift 6.0 compiler was trying to do the same thing
(ensure that the 15.0 SDK or newer was in use before compiling code that
would error on earlier SDKs), but there were niche situations where it
would not work.

Thanks to <https://marcoeidinger.github.io/appleframeworks/>, I have
found a framework (CoreHID) that only exists in the 15.0 SDK or newer,
so I have switched to checking if that module can be imported.

* Use Swift's ability to create a universal binary

* Restore legacy build in Makefile

* fix makefile

---------

Co-authored-by: Logicer <[email protected]>
  • Loading branch information
Samasaur1 and Logicer16 authored Dec 25, 2024
1 parent a1844b8 commit bb9c6ea
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 14 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
*.swp
*.swo
._*
/.build
25 changes: 12 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,24 @@ VERSION = $(shell cat VERSION)
LIBRARY_PREFIX = pam_watchid
LIBRARY_NAME = $(LIBRARY_PREFIX).so
DESTINATION = /usr/local/lib/pam
TARGET = apple-darwin$(shell uname -r)
TARGET = apple-macosx10.15
PAM_FILE_BASE = /etc/pam.d/sudo
PAM_TEXT = auth sufficient $(LIBRARY_NAME)
PAM_TID_TEXT = auth sufficient pam_tid.so

# Determine if the macOS Sequoia SDK or later is available.
DEFINES =
# Due to the different ways in which the CLT and Xcode structure their SDK paths, one of the following will always be an empty string depending on what is configured by xcode-select.
CLT_SDK_MAJOR_VER = $(shell xcrun --sdk macosx --show-sdk-path | xargs readlink -f | xargs basename | sed 's/MacOSX//' | cut -d. -f1)
XCODE_SDK_MAJOR_VER = $(shell xcrun --sdk macosx --show-sdk-path | xargs basename | sed 's/MacOSX//' | cut -d. -f1)
SDK_REQUIRED_MAJOR_VER = 15
ifeq "$(SDK_REQUIRED_MAJOR_VER)" "$(word 1, $(sort $(SDK_REQUIRED_MAJOR_VER) $(XCODE_SDK_MAJOR_VER) $(CLT_SDK_MAJOR_VER)))"
DEFINES += -DSEQUOIASDK
endif

all:
swiftc watchid-pam-extension.swift $(DEFINES) -o $(LIBRARY_PREFIX)_x86_64.so -target x86_64-$(TARGET) -emit-library
swiftc watchid-pam-extension.swift $(DEFINES) -o $(LIBRARY_PREFIX)_arm64.so -target arm64-$(TARGET) -emit-library
ifeq ($(shell [[ '$(shell xcode-select -p)' == '/Library/Developer/CommandLineTools' ]] && echo true),true)
# Legacy build
# For CLT due to poor support for building swift packages.
# Swift packages do work in macOS Sonoma and later with the CLT, but are an order of magnitude slower than Xcode.
swiftc Sources/pam-watchid/pam_watchid.swift -o $(LIBRARY_PREFIX)_x86_64.so -target x86_64-$(TARGET) -emit-library
swiftc Sources/pam-watchid/pam_watchid.swift -o $(LIBRARY_PREFIX)_arm64.so -target arm64-$(TARGET) -emit-library
lipo -create $(LIBRARY_PREFIX)_arm64.so $(LIBRARY_PREFIX)_x86_64.so -output $(LIBRARY_NAME)
else
# Swift Package Manager build
swift build -c release --arch x86_64 --arch arm64
mv .build/apple/Products/Release/libpam-watchid.dylib $(LIBRARY_NAME)
endif

install: all
sudo mkdir -p $(DESTINATION)
Expand Down
22 changes: 22 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// swift-tools-version:5.1
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "pam-watchid",
platforms: [.macOS(.v10_15)],
products: [
// Products define the executables and libraries a package produces, making them visible to other packages.
.library(
name: "pam-watchid",
type: .dynamic,
targets: ["pam-watchid"]),
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.
.target(
name: "pam-watchid"),
]
)
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ private func parseArguments(argc: Int, argv: vchar) -> [String: String] {

private extension LAPolicy {
static var deviceOwnerAuthenticationIgnoringUserID: LAPolicy {
#if SEQUOIASDK
#if canImport(CoreHID) // Check for the 15.0 SDK
if #available(macOS 15, *) {
return .deviceOwnerAuthenticationWithBiometricsOrCompanion
} else {
Expand Down

0 comments on commit bb9c6ea

Please sign in to comment.