From c20671f1db5e942a71d45a76eeba16e16113b9d0 Mon Sep 17 00:00:00 2001 From: Luiz Sardinha Date: Thu, 5 Mar 2026 19:13:34 +0100 Subject: [PATCH] build: ensuring macOS codesign is triggered for changes in core --- CMakeLists.txt | 4 +++ cmake/MacCodesign.cmake | 49 +++++++++++++++++++++++++++ src/apps/deskflow-core/CMakeLists.txt | 3 ++ src/apps/deskflow-gui/CMakeLists.txt | 28 ++------------- 4 files changed, 58 insertions(+), 26 deletions(-) create mode 100644 cmake/MacCodesign.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b0ae6507..5b686e6e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -162,6 +162,10 @@ endif() include(cmake/Libraries.cmake) configure_libs() +if(BUILD_OSX_BUNDLE AND APPLE_CODESIGN_DEV) + include(cmake/MacCodesign.cmake) +endif() + # setup install paths include(GNUInstallDirs) if (WIN32) diff --git a/cmake/MacCodesign.cmake b/cmake/MacCodesign.cmake new file mode 100644 index 000000000..87e8a6250 --- /dev/null +++ b/cmake/MacCodesign.cmake @@ -0,0 +1,49 @@ +# SPDX-FileCopyrightText: (C) 2025-2026 Deskflow Contributors +# SPDX-License-Identifier: MIT + +# Warning: Do not use for CI/production, as the `entitlements-dev.plist` file adds special +# entitlements that are only appropriate for local development. +# +# macOS made TCC stricter so that if you don't sign your local dev builds properly, macOS will +# nag you to remove and re-approve the app every time you make a change to the binary which is +# extremely annoying during development. +# +# If you were to use ad-hoc signing (i.e. not specify a certificate), TCC would still nag you +# because the binary identity is anchored not on the app ID, but on the CD hash (which changes +# based on the binary contents). +# +# To use, simply generate a personal certificate for free with Xcode and pass the ID to CMake. +# Full instructions are in the docs. + +function(configure_mac_codesign target) + set_property(GLOBAL APPEND PROPERTY _MAC_CODESIGN_DEPENDS $) + + if(NOT _MAC_CODESIGN_DEFERRED) + set(_MAC_CODESIGN_DEFERRED TRUE CACHE INTERNAL "") + message(STATUS "Apple codesign ID for development only: ${APPLE_CODESIGN_DEV}") + cmake_language(DEFER DIRECTORY ${CMAKE_SOURCE_DIR} CALL _finalize_mac_codesign) + endif() +endfunction() + +function(_finalize_mac_codesign) + get_property(depends GLOBAL PROPERTY _MAC_CODESIGN_DEPENDS) + + set(stamp_file "${CMAKE_BINARY_DIR}/CMakeFiles/codesign-dev.stamp") + + # Use a stamp file because codesign modifies the binaries it signs. + add_custom_command( + OUTPUT ${stamp_file} + COMMAND /usr/bin/codesign + --force + --options runtime + --entitlements "${CMAKE_SOURCE_DIR}/src/apps/res/entitlements-dev.plist" + --sign "${APPLE_CODESIGN_DEV}" + "$" + COMMAND ${CMAKE_COMMAND} -E touch ${stamp_file} + DEPENDS ${depends} + COMMENT "Codesigning ${CMAKE_PROJECT_PROPER_NAME}" + VERBATIM + ) + + add_custom_target(codesign-dev ALL DEPENDS ${stamp_file}) +endfunction() diff --git a/src/apps/deskflow-core/CMakeLists.txt b/src/apps/deskflow-core/CMakeLists.txt index 9d6f3502c..eac71bd08 100644 --- a/src/apps/deskflow-core/CMakeLists.txt +++ b/src/apps/deskflow-core/CMakeLists.txt @@ -50,6 +50,9 @@ if(BUILD_OSX_BUNDLE) INSTALL_RPATH "@loader_path/../Libraries;@loader_path/../Frameworks" RUNTIME_OUTPUT_DIRECTORY $/MacOS ) + if (APPLE_CODESIGN_DEV) + configure_mac_codesign(${target}) + endif() elseif (WIN32) install(RUNTIME_DEPENDENCY_SET coreDeps PRE_EXCLUDE_REGEXES ${WIN32_PRE_EXCLUDE_REGEXES} diff --git a/src/apps/deskflow-gui/CMakeLists.txt b/src/apps/deskflow-gui/CMakeLists.txt index 1bb3cda62..c485f84a3 100644 --- a/src/apps/deskflow-gui/CMakeLists.txt +++ b/src/apps/deskflow-gui/CMakeLists.txt @@ -95,32 +95,8 @@ elseif(APPLE) INSTALL_RPATH "@loader_path/../Libraries;@loader_path/../Frameworks" MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_BINARY_DIR}/deskflow.plist" ) - - # Warning: Do not use for CI/production, as the `entitlements-dev.plist` file adds special - # entitlements that are only appropriate for local development. - # - # macOS made TCC stricter so that if you don't sign your local dev builds properly, macOS will - # nag you to remove and re-approve the app every time you make a change to the binary which is - # extremely annoying during development. - # - # If you were to use ad-hoc signing (i.e. not specify a certificate), TCC would still nag you - # because the binary identity is anchored not on the app ID, but on the CD hash (which changes - # based on the binary contents). - # - # To use, simply generate a personal certificate for free with Xcode and pass the ID to CMake. - # Full instructions are in the docs. - if (NOT "${APPLE_CODESIGN_DEV}" STREQUAL "") - message(STATUS "Apple codesign ID for development only: ${APPLE_CODESIGN_DEV}") - add_custom_command( - TARGET ${target} POST_BUILD - COMMAND /usr/bin/codesign - --force - --options runtime - --entitlements "$" - --sign "${APPLE_CODESIGN_DEV}" - "$" - VERBATIM - ) + if (APPLE_CODESIGN_DEV) + configure_mac_codesign(${target}) endif() else() set_target_properties(${target} PROPERTIES MACOSX_BUNDLE FALSE)