Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
676c0ce
[github] Move away from including sentry-native and winsparkle as sub…
christofmuc Feb 5, 2022
56260c0
[github] Instead, adding a conan recipe for winsparkle und using that…
christofmuc Feb 5, 2022
a07f5fc
[github] Even better, it seems conan create does already place the pa…
christofmuc Feb 5, 2022
637e246
[github] Fixing macOS build, adding publish step if tagged build.
christofmuc Feb 5, 2022
e6660fc
[github] Fixing sentry build flag, adding publish step if tagged build.
christofmuc Feb 5, 2022
2249a80
[github] Will it find the python executable in case I do not specify …
christofmuc Feb 5, 2022
f6658e4
[github] Fix the publish paths. That was done a wee too quickly.
christofmuc Feb 5, 2022
d3ac763
[macos installer] Trying to prevent the sequential python module to a…
christofmuc Feb 5, 2022
cea8814
[fix] You cannot remote the runtime statement from the install direct…
christofmuc Feb 15, 2022
7279a25
Trying to fix the DMG created by the github build machine.
christofmuc Feb 17, 2022
6513f9e
[mac sparkle] Figuring out how to use a macOS Framework from CMake. S…
christofmuc Feb 17, 2022
e4411c0
[Mac Sparkle] Next try at getting Sparkle to work on Mac. This at lea…
christofmuc Nov 11, 2022
16eeb1d
Merge branch 'master' into macSparkle
christofmuc Nov 11, 2022
b5babf0
Fix a couple of merge issues. It seems the MacSparkle branch was real…
christofmuc Nov 11, 2022
7660d23
Remove Winsparkle as submodule, will keep using fetch content
christofmuc Nov 11, 2022
3599014
Reverting more changes from the old branch
christofmuc Nov 11, 2022
29a38f5
More mistakes spotted
christofmuc Nov 11, 2022
bcfcaaf
This should do it
christofmuc Nov 11, 2022
9dfcac4
Fix: Should be able to build without Sparkle on Mac
christofmuc Nov 11, 2022
b0523e0
Why is the bundle broken?
christofmuc Nov 11, 2022
957049c
Adding rpath command
christofmuc Nov 11, 2022
491bfa6
Continuing to reduce the delta to the working version.
christofmuc Nov 11, 2022
8fe2b81
Good night
christofmuc Nov 11, 2022
d6df280
Less diff
christofmuc Nov 11, 2022
35da19c
Suddenly it works
christofmuc Nov 11, 2022
ce0375e
[Sparkle] Archive uncommitted Sparkle changes. Hope they were good.
christofmuc Jan 1, 2023
e0f32c5
Merge branch 'master' into features/mac_sparkle
christofmuc Jan 4, 2025
7f713f7
Fix merge things
christofmuc Jan 4, 2025
d7f14b2
Fix merge error
christofmuc Jan 4, 2025
9eb594d
Make the Sparkle compile again, updated to release 2.6.4
christofmuc Jan 4, 2025
c3abd91
Merge branch 'master' into features/mac_sparkle
christofmuc Nov 2, 2025
bbcae79
Review results
christofmuc Nov 2, 2025
1f39cb7
Fix top level CMake version requirement
christofmuc Nov 2, 2025
dd5a081
Fix RPATH setup which should be only for Mac
christofmuc Nov 2, 2025
cdcd2b6
Trying to fix sparkle build
christofmuc Nov 2, 2025
3836b3d
Implement review feedback
christofmuc Nov 2, 2025
cb5be6e
Rollback one suggestion which potentially prevents code signing to work
christofmuc Nov 3, 2025
47aaf82
Adding appcast creation for macOS
christofmuc Nov 3, 2025
1c8bb10
Put in the public key for the macOS update
christofmuc Nov 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion .github/workflows/builds-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ jobs:
with:
python-version: '3.12'

- name: Install Python dependencies for tooling
if: startsWith(github.ref, 'refs/tags/')
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Import Developer Certificate
run: |
echo "$MACOS_CERTIFICATE_BASE64" | base64 --decode > certificate.p12
Expand All @@ -51,7 +57,7 @@ jobs:
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
MACOS_CERTIFICATE_BASE64: ${{ secrets.MACOS_CERTIFICATE_BASE64 }}
MACOS_TEMPORARY_KEYCHAIN_PASSWORD: $ {{ secrets.MACOS_TEMPORARY_KEYCHAIN_PASSWORD }}

- name: Build the MacOS DMG
shell: bash
run: |
Expand All @@ -69,6 +75,35 @@ jobs:
TEAM_ID: ${{ secrets.TEAM_ID }}
MACOS_TEMPORARY_KEYCHAIN_PASSWORD: $ {{ secrets.MACOS_TEMPORARY_KEYCHAIN_PASSWORD }}

- name: Download Sparkle signing tools
if: startsWith(github.ref, 'refs/tags/')
run: |
curl -L https://github.com/sparkle-project/Sparkle/releases/download/2.6.4/Sparkle-2.6.4.tar.xz -o Sparkle.tar.xz
tar -xJf Sparkle.tar.xz Sparkle-2.6.4/bin/sign_update
chmod +x Sparkle-2.6.4/bin/sign_update

- name: Extract Sparkle private key
if: startsWith(github.ref, 'refs/tags/')
env:
MAC_SPARKLE_PRIVATE_KEY: ${{ secrets.MAC_SPARKLE_PRIVATE_KEY }}
run: |
echo "$MAC_SPARKLE_PRIVATE_KEY" | base64 --decode > sparkle_private_key_ed25519.pem
chmod 600 sparkle_private_key_ed25519.pem

- name: Sign macOS update
if: startsWith(github.ref, 'refs/tags/')
run: |
Sparkle-2.6.4/bin/sign_update sparkle_private_key_ed25519.pem build/KnobKraft_Orm-${{env.ORM_VERSION}}-Darwin.dmg | tail -1 | awk '{print $NF}' > mac_update.sig

- name: Update macOS appcast feed
if: startsWith(github.ref, 'refs/tags/')
env:
APPCAST_ACCESS_TOKEN: ${{ secrets.APPCAST_ACCESS_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
python write_appcast.py --platform mac --signature-file mac_update.sig
python make_github_release.py

- name: Archive DMG artifact
uses: actions/upload-artifact@v4
if: always()
Expand All @@ -86,3 +121,9 @@ jobs:
tags: true
draft: false

- name: Delete Sparkle signing materials
if: startsWith(github.ref, 'refs/tags/')
run: |
rm -f sparkle_private_key_ed25519.pem mac_update.sig Sparkle.tar.xz
rm -rf Sparkle-2.6.4

2 changes: 1 addition & 1 deletion .github/workflows/builds-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
working-directory: Builds/The-Orm/RelWithDebInfo
run: |
sentry-cli upload-dif . --log-level=debug

# Thanks to https://svrooij.io/2021/08/17/github-actions-secret-file/
- name: Extract update private key from secret
if: startsWith(github.ref, 'refs/tags/')
Expand Down
28 changes: 21 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#
# Copyright (c) 2020 Christof Ruch. All rights reserved.
# Copyright (c) 2020-2025 Christof Ruch. All rights reserved.
#
# Dual licensed: Distributed under Affero GPL license by default, an MIT license is available for purchase
#

cmake_minimum_required(VERSION 3.14)
cmake_minimum_required(VERSION 3.20)

# Target a specific MacOS version.
# JUCE 8 refuses to build for anything older than 10.11, so let's try that.
Expand All @@ -28,10 +28,16 @@ IF(APPLE)

# For old Apple < macOS 10.15 and Linux, do not allow C++ 17 because it won't work. With the newer nlohmann::json, we can specify the C++ version to use
add_compile_definitions(JSON_HAS_CPP_14)

# Required for Sparkle
set(BUILD_WITH_INSTALL_RPATH YES)
ENDIF()


project(KnobKraft_Orm)

OPTION(SPARKLE_UPDATES "Turn on Sparkle/WinSparkle update service")

#set(USE_ASIO true)
option(ASAN "Use Address Sanitization for Debug version (Windows only for now)" OFF)

Expand Down Expand Up @@ -72,11 +78,12 @@ else()
set(PYTHON_VERSION_TO_EMBED "3.12" CACHE STRING "Specify which version of Python should be used for embedding.")
endif()

# Include useful scripts for CMake
cmake_policy(SET CMP0135 NEW)
include(FetchContent REQUIRED)

# On Windows, we need to download external dependencies
IF (WIN32)
# Include useful scripts for CMake, and opt in for the new fetch content timestamp behavior
cmake_policy(SET CMP0135 NEW)
include(FetchContent REQUIRED)

FetchContent_Declare(
icu URL https://github.com/unicode-org/icu/releases/download/release-74-2/icu4c-74_2-Win64-MSVC2019.zip
Expand Down Expand Up @@ -138,8 +145,15 @@ ELSEIF(APPLE)
if (NOT CMAKE_BUILD_TYPE MATCHES Release)
add_compile_definitions(DEBUG)
endif()



IF(SPARKLE_UPDATES)
FetchContent_Declare(
sparkleframework
URL https://github.com/sparkle-project/Sparkle/releases/download/2.6.4/Sparkle-2.6.4.tar.xz
)
FetchContent_MakeAvailable(sparkleframework)
ENDIF()

# The JUCE font rendering is really fat on macOS, let us try to disable this flag
add_definitions(-DJUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING)
ELSEIF(UNIX)
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ apple: notarize staple verify-notarization

configure:
@echo "Configuring build for type $(BUILD_TYPE) in directory $(BUILD_DIR), using Python from $(PYTHON_TO_USE)"
cmake -S . -B $(BUILD_DIR) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DPYTHON_EXECUTABLE=$(PYTHON_TO_USE) -DCODESIGN_CERTIFICATE_NAME="$(APPLE_DEVELOPER_IDENTITY)"
cmake -S . -B $(BUILD_DIR) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DPYTHON_EXECUTABLE=$(PYTHON_TO_USE) -DCODESIGN_CERTIFICATE_NAME="$(APPLE_DEVELOPER_IDENTITY)" -DSPARKLE_UPDATES=ON

.PHONY: build
build $(KNOBKRAFT_DMG):
Expand Down
14 changes: 14 additions & 0 deletions The-Orm/AutoUpdaterInterface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
Copyright (c) 2022 Christof Ruch. All rights reserved.

Dual licensed: Distributed under Affero GPL license by default, an MIT license is available for purchase
*/

#pragma once

class AutoUpdaterInterface
{
public:
virtual ~AutoUpdaterInterface() = default;
virtual void checkForUpdates() = 0;
};
63 changes: 51 additions & 12 deletions The-Orm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Dual licensed: Distributed under Affero GPL license by default, an MIT license is available for purchase
#

cmake_minimum_required(VERSION 3.14)
cmake_minimum_required(VERSION 3.20)
Comment thread
coderabbitai[bot] marked this conversation as resolved.

# Get the version from our sub cmakefile
execute_process(
Expand All @@ -26,6 +26,7 @@ if(PROJECT_DEV_TAG STREQUAL "-dev")
add_definitions(-DPROJECT_DEV)
endif()


# Export this variable to be use by the Azure
# Append the version number to the github action environment file to be used by subsequent steps
if(DEFINED ENV{GITHUB_ENV})
Expand All @@ -36,7 +37,6 @@ OPTION(CRASH_REPORTING "Turn on crash reporting via Internet/Sentry")
OPTION(SENTRY_LOGGING "Turn on logging of sentry events into the log window")
set(SENTRY_DSN "Sentry DSN URL" CACHE STRING "https://YYYYYYYYYYYYYYYYYY@ZZZZZ.ingest.sentry.io/XXXX")
set(D_LOG_SENTRY "")
OPTION(SPARKLE_UPDATES "Turn on WinSparkle update service")

configure_file("version.cpp.in" "version.cpp")

Expand All @@ -49,9 +49,17 @@ IF(CRASH_REPORTING)
ENDIF()

IF(SPARKLE_UPDATES)
message("Sparkle and WinSparkle updates are turned on, the executable will be linked against WinSparkle")
juce_add_binary_data(CodeSigning SOURCES "${CMAKE_CURRENT_LIST_DIR}/../codesigning/dsa_pub.pem")
if(WIN32)
juce_add_binary_data(CodeSigning SOURCES "${CMAKE_CURRENT_LIST_DIR}/../codesigning/dsa_pub.pem")
SET(WINSPARKLE_DISTRIBUTION_FILES "${WINSPARKLE_LIBDIR}/WinSparkle.dll")
elseif(APPLE)
set(SPARKLE_FRAMEWORK_PATH ${sparkleframework_SOURCE_DIR})
message("Using Sparkle Framework from ${SPARKLE_FRAMEWORK_PATH}")
set(SPARKLE_LINK "-F${SPARKLE_FRAMEWORK_PATH}" "-framework Sparkle")
else()
message(FATAL_ERROR "SPARKLE_UPDATES is only supported on Windows and macOS")
endif()
message("Sparkle and WinSparkle updates are turned on")
ENDIF()

set(SOURCES
Expand Down Expand Up @@ -102,11 +110,18 @@ set(SOURCES
redist/agpl-3.0.txt
)

# Mac Icon Magic
if(APPLE)
set(KnobKraftOrm_ICON ${CMAKE_CURRENT_SOURCE_DIR}/resources/icon_orm.icns)
set_source_files_properties(${KnobKraftOrm_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")

IF(SPARKLE_UPDATES)
# Sparkle framework
message("Adding Mac Objective-C files for Sparkle")
set(SPARKLE_SOURCES MacSparkle.mm MacSparkle.h)
else()
set(SPARKLE_SOURCES "")
endif()
# Limit skip-build-rpath to macOS to match top-level install RPATH handling
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(KnobKraftOrm_ICON ${CMAKE_CURRENT_SOURCE_DIR}/resources/icon_orm.icns)
set_source_files_properties(${KnobKraftOrm_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
ENDIF()

set(MIDIKRAFT_LIBRARIES
Expand All @@ -126,8 +141,7 @@ set(MIDIKRAFT_LIBRARIES
knobkraft-generic-adaptation
pytschirp_embedded
)

add_executable(KnobKraftOrm MACOSX_BUNDLE WIN32 ${KnobKraftOrm_ICON} ${SOURCES})
add_executable(KnobKraftOrm MACOSX_BUNDLE WIN32 ${KnobKraftOrm_ICON} ${SOURCES} ${SPARKLE_SOURCES})
target_include_directories(KnobKraftOrm INTERFACE ${CMAKE_CURRENT_LIST_DIR})
if (CRASH_REPORTING)
target_include_directories(KnobKraftOrm SYSTEM PRIVATE "${SENTRY_INSTALL_PATH}/include")
Expand Down Expand Up @@ -171,6 +185,9 @@ IF(WIN32)
${SPARKLE_DEPENDENCY}
)
ELSEIF(APPLE)
if(SPARKLE_UPDATES)
target_compile_options(KnobKraftOrm PRIVATE -F${SPARKLE_FRAMEWORK_PATH} -DUSE_SPARKLE)
endif()
target_link_libraries(KnobKraftOrm PRIVATE
${JUCE_LIBRARIES}
ICU::data ICU::uc
Expand All @@ -180,13 +197,30 @@ ELSEIF(APPLE)
gin
spdlog::spdlog
pybind11::embed
$<$<BOOL:${SPARKLE_UPDATES}>:${SPARKLE_LINK}>
)
SET_TARGET_PROPERTIES(KnobKraftOrm PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KnobKraft Orm ${KnobKraftOrm_VERSION}"
SET_TARGET_PROPERTIES(KnobKraftOrm PROPERTIES
MACOSX_BUNDLE_BUNDLE_NAME "KnobKraft Orm ${KnobKraftOrm_VERSION}"
MACOSX_BUNDLE_ICON_FILE icon_orm.icns
MACOSX_BUNDLE_BUNDLE_VERSION ${KnobKraftOrm_VERSION}
MACOSX_BUNDLE_GUI_IDENTIFIER "com.knobkraft.orm"
MACOSX_BUNDLE_IDENTIFIER "com.knobkraft.orm"
)
MACOSX_BUNDLE_EXECUTABLE_NAME KnobKraftOrm
#MACOSX_BUNDLE_BUNDLE_VERSION ${KnobKraftOrm_VERSION}
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist
#XCODE_EMBED_FRAMEWORKS Sparkle
#XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY TRUE
#XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY TRUE
)
# https://stackoverflow.com/questions/68310342/how-to-get-cmake-to-embed-a-private-framework-into-a-macos-app-bundle
set(APP_BUNDLE_CONTENTS_DIR "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.app/Contents")
set(APP_BUNDLE_FRAMEWORKS_DIR "${APP_BUNDLE_CONTENTS_DIR}/Frameworks")
configure_file("Info.plist.in" "Info.plist")

add_custom_command(TARGET ${PROJECT_NAME}
POST_BUILD COMMAND
install_name_tool -add_rpath "@executable_path/../Frameworks/"
"${APP_BUNDLE_CONTENTS_DIR}/MacOS/${PROJECT_NAME}")
ELSEIF(UNIX)
target_link_libraries(KnobKraftOrm PRIVATE
${JUCE_LIBRARIES}
Expand Down Expand Up @@ -328,6 +362,11 @@ ENDIF()
IF(APPLE)
# This section is supposed to build a relocatable macOS DMG installer when you specify the
# --target package
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR})
IF(SPARKLE_UPDATES)
# Make sure the private frameworks are in out binary directory
file(COPY ${SPARKLE_FRAMEWORK_PATH}/Sparkle.framework DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/KnobKraftOrm.app/Contents/Frameworks)
ENDIF()

IF(CODESIGN_CERTIFICATE_NAME)
# We need to sign the files as a post build step. Doing this as install step doesn't help because
Expand Down
33 changes: 33 additions & 0 deletions The-Orm/Info.plist.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist>
<dict>
<key>SUFeedURL</key>
<string>https://raw.githubusercontent.com/christofmuc/appcasts/master/KnobKraft-Orm/appcast.xml</string>
<key>SUPublicEDKey</key>
<string>MCowBQYDK2VwAyEAWtvaPXtAM9WMjFoaE6i5ZWBTZE929CUMlCB3NiXTo0g=</string>
<key>CFBundleExecutable</key>
<string>KnobKraftOrm</string>
<key>CFBundleIconFile</key>
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>CFBundleVersion</key>
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
<!-- Minimum System Version (macOS version) -->
<key>LSMinimumSystemVersion</key>
<string>10.11</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array> </dict>
</plist>
21 changes: 21 additions & 0 deletions The-Orm/MacSparkle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
Copyright (c) 2022 Christof Ruch. All rights reserved.

Dual licensed: Distributed under Affero GPL license by default, an MIT license is available for purchase
*/

#pragma once

#include "AutoUpdaterInterface.h"

class SparkleAutoUpdate : public AutoUpdaterInterface
{
public:
SparkleAutoUpdate ();
virtual ~SparkleAutoUpdate ();
virtual void checkForUpdates();

private:
class Impl;
Impl *d;
};
42 changes: 42 additions & 0 deletions The-Orm/MacSparkle.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
Copyright (c) 2022 Christof Ruch. All rights reserved.

Dual licensed: Distributed under Affero GPL license by default, an MIT license is available for purchase
*/

#include "MacSparkle.h"

#import <Foundation/Foundation.h>
#import <Sparkle/Sparkle.h>

// This does not follow the new procedure at https://sparkle-project.org/documentation/programmatic-setup/ yet

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"

class SparkleAutoUpdate::Impl
{
public:
SUUpdater *updater;
};

SparkleAutoUpdate::SparkleAutoUpdate()
{
d = new SparkleAutoUpdate::Impl;
d->updater = [[SUUpdater sharedUpdater] retain];
[d->updater setAutomaticallyChecksForUpdates: YES];
[d->updater setUpdateCheckInterval: 3600];
}

SparkleAutoUpdate::~SparkleAutoUpdate()
{
[d->updater release];
delete d;
}

void SparkleAutoUpdate::checkForUpdates()
{
[d->updater checkForUpdates : nil];
}

#pragma clang diagnostic pop
Loading