From b48a014233b60af9108c0de83b764ee3ae87c1d7 Mon Sep 17 00:00:00 2001 From: marinmarian Date: Fri, 8 May 2026 15:08:36 +0200 Subject: [PATCH] Enable macOS build for the face-auth path The face-auth path (FaceAuthenticator, DeviceController, FwUpdater) is platform-agnostic apart from the serial transport. The existing LinuxSerial implementation uses only POSIX APIs (termios.h / unistd.h / fcntl.h), so it builds and runs on macOS unchanged. Changes: - cmake/OS.cmake: add an APPLE branch matching the existing ANDROID style (no platform-specific defines needed). - src/PacketManager/CMakeLists.txt: include LinuxSerial on APPLE too, with a comment explaining why the same source is reused. - Four platform guards extended from '#elif defined(__linux__)' to '#elif defined(__linux__) || defined(__APPLE__)' so the LinuxSerial header is selected on macOS: src/DeviceController/DeviceControllerImpl.cc src/FaceAuthenticator/Impl/FaceAuthenticatorCommon.cc src/FwUpdate/F45x/FwUpdaterCommF45x.cc src/FwUpdate/F50x/FwUpdaterCommF50x.cc - Readme.md: add macOS to the Platforms list and a macOS Notes subsection documenting the build flag (RSID_PREVIEW=OFF) and the discover_devices() limitation. Out of scope (separate PRs welcome): - Preview / libuvc support on macOS (libuvc is excluded for Apple upstream; AVFoundation would be the macOS-native replacement). - IOKit-based discover_devices() so applications can enumerate devices without hardcoding the serial port path. Tested on Apple Silicon (M-series, macOS 26, Apple Clang 21, Python 3.13) with an F455 over USB. Build: cmake -DRSID_PY=ON -DRSID_PREVIEW=OFF \ -DRSID_SAMPLES=OFF -DRSID_TOOLS=OFF .. make End-to-end face-auth verified: enroll, identify, query users, remove. F500 firmware update guard updated to match but not runtime-tested (no F500 hardware on hand). --- Readme.md | 11 +++++++++++ cmake/OS.cmake | 3 +++ src/DeviceController/DeviceControllerImpl.cc | 4 ++-- src/FaceAuthenticator/Impl/FaceAuthenticatorCommon.cc | 4 ++-- src/FwUpdate/F45x/FwUpdaterCommF45x.cc | 4 ++-- src/FwUpdate/F50x/FwUpdaterCommF50x.cc | 4 ++-- src/PacketManager/CMakeLists.txt | 5 ++++- 7 files changed, 26 insertions(+), 9 deletions(-) diff --git a/Readme.md b/Readme.md index 81ff95c..af7ec93 100644 --- a/Readme.md +++ b/Readme.md @@ -58,6 +58,7 @@ See [SKILL.md](./SKILL.md) for guidance when using this SDK with AI tools. - Linux (Ubuntu 18.04+, Raspberry Pi 4+, Jetson) - Windows (Windows 10+) +- macOS 12+ (Apple Silicon; face-auth path only — preview/libuvc unsupported) - Android 8-16 ## Bindings @@ -148,6 +149,16 @@ In order to be able to capture metadata for RAW format, open a `PowerShell` term .\scripts\realsenseid_metadata_win10-f500.ps1 ``` +### macOS Notes + +The face-auth path (FaceAuthenticator, DeviceController, FwUpdater) builds and runs on macOS using the existing POSIX `LinuxSerial` implementation. Build with `-DRSID_PREVIEW=OFF`; the preview pipeline (libuvc) is not yet supported on macOS. + +`discover_devices()` walks `/sys/bus/usb/` (Linux-only) and returns an empty list on macOS. Pass the F455's serial port directly to `FaceAuthenticator()`. Locate it with: + +```bash +ls /dev/cu.usbmodem* +``` + ## Sample Code This snippet shows the basic usage of our library. diff --git a/cmake/OS.cmake b/cmake/OS.cmake index b455664..4c0bd25 100644 --- a/cmake/OS.cmake +++ b/cmake/OS.cmake @@ -7,6 +7,9 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") message(STATUS "Linux platform") add_definitions(-DLINUX) +elseif(APPLE) + message(STATUS "macOS platform") + elseif(ANDROID) message(STATUS "Android platform") add_definitions(-DANDROID_STL=c++_shared) diff --git a/src/DeviceController/DeviceControllerImpl.cc b/src/DeviceController/DeviceControllerImpl.cc index 2bf2664..704d39b 100644 --- a/src/DeviceController/DeviceControllerImpl.cc +++ b/src/DeviceController/DeviceControllerImpl.cc @@ -20,7 +20,7 @@ #include "PacketManager/WindowsSerial.h" #elif defined(__ANDROID__) #include "PacketManager/AndroidSerial.h" -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include "PacketManager/LinuxSerial.h" #else #error "Platform not supported" @@ -60,7 +60,7 @@ Status DeviceControllerImpl::Connect(const SerialConfig& config) serial_config.readEndpoint = config.readEndpoint; serial_config.writeEndpoint = config.writeEndpoint; _serial = std::make_unique(serial_config); -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) _serial = std::make_unique(PacketManager::SerialConfig({config.port})); #else LOG_ERROR(LOG_TAG, "Serial connection method not supported for OS"); diff --git a/src/FaceAuthenticator/Impl/FaceAuthenticatorCommon.cc b/src/FaceAuthenticator/Impl/FaceAuthenticatorCommon.cc index 213b5da..3a34d6c 100644 --- a/src/FaceAuthenticator/Impl/FaceAuthenticatorCommon.cc +++ b/src/FaceAuthenticator/Impl/FaceAuthenticatorCommon.cc @@ -28,7 +28,7 @@ #include "PacketManager/WindowsSerial.h" #elif defined(__ANDROID__) #include "PacketManager/AndroidSerial.h" -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include "PacketManager/LinuxSerial.h" #else #error "Platform not supported" @@ -227,7 +227,7 @@ Status FaceAuthenticatorCommon::Connect(const SerialConfig& config) serial_config.readEndpoint = config.readEndpoint; serial_config.writeEndpoint = config.writeEndpoint; _serial = std::make_unique(serial_config); -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) _serial = std::make_unique(PacketManager::SerialConfig({config.port})); #else LOG_ERROR(LOG_TAG, "Serial connection method not supported for OS"); diff --git a/src/FwUpdate/F45x/FwUpdaterCommF45x.cc b/src/FwUpdate/F45x/FwUpdaterCommF45x.cc index 7de678a..91819a8 100644 --- a/src/FwUpdate/F45x/FwUpdaterCommF45x.cc +++ b/src/FwUpdate/F45x/FwUpdaterCommF45x.cc @@ -16,7 +16,7 @@ #include "PacketManager/WindowsSerial.h" #elif defined(__ANDROID__) #include "PacketManager/AndroidSerial.h" -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include "PacketManager/LinuxSerial.h" #else #error "Platform not supported" @@ -42,7 +42,7 @@ FwUpdaterCommF45x::FwUpdaterCommF45x(const SerialConfig& config) serial_config.readEndpoint = config.readEndpoint; serial_config.writeEndpoint = config.writeEndpoint; _serial = std::make_unique(serial_config); -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) _serial = std::make_unique(PacketManager::SerialConfig({config.port})); #else throw std::runtime_error("FwUpdaterComm not supported for this OS yet"); diff --git a/src/FwUpdate/F50x/FwUpdaterCommF50x.cc b/src/FwUpdate/F50x/FwUpdaterCommF50x.cc index d465ba0..a148482 100644 --- a/src/FwUpdate/F50x/FwUpdaterCommF50x.cc +++ b/src/FwUpdate/F50x/FwUpdaterCommF50x.cc @@ -15,7 +15,7 @@ #include "PacketManager/WindowsSerial.h" #elif defined(__ANDROID__) #include "PacketManager/AndroidSerial.h" -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include "PacketManager/LinuxSerial.h" #else #error "Platform not supported" @@ -41,7 +41,7 @@ FwUpdaterCommF50x::FwUpdaterCommF50x(const SerialConfig& config) serial_config.readEndpoint = config.readEndpoint; serial_config.writeEndpoint = config.writeEndpoint; _serial = std::make_unique(serial_config); -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) _serial = std::make_unique(PacketManager::SerialConfig({config.port})); #else throw std::runtime_error("FwUpdaterComm not supported for this OS yet"); diff --git a/src/PacketManager/CMakeLists.txt b/src/PacketManager/CMakeLists.txt index f9d474d..be2f5ac 100644 --- a/src/PacketManager/CMakeLists.txt +++ b/src/PacketManager/CMakeLists.txt @@ -4,7 +4,10 @@ set(HEADERS "${SRC_DIR}/Randomizer.h" "${SRC_DIR}/PacketSender.h" "${SRC_DIR}/Se set(SOURCES "${SRC_DIR}/Randomizer.cc" "${SRC_DIR}/PacketSender.cc" "${SRC_DIR}/SerialPacket.cc" "${SRC_DIR}/Timer.cc" ${SRC_DIR}/Crc16.cc ) -if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") +if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR APPLE) + # LinuxSerial uses only POSIX serial APIs (termios.h / unistd.h / + # fcntl.h) — no Linux-specific syscalls or headers — so the same + # implementation builds and runs on macOS unchanged. list(APPEND HEADERS "${SRC_DIR}/LinuxSerial.h") list(APPEND SOURCES "${SRC_DIR}/LinuxSerial.cc") elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")