From a69024c0bec5f22ad7242a9c18dc6294b83b7c58 Mon Sep 17 00:00:00 2001 From: David Helkowski Date: Thu, 22 Jan 2026 14:19:33 +0900 Subject: [PATCH] Add optional dependencies to Brewfile and improve CMake configuration This commit updates the Brewfile to include additional optional dependencies such as Vulkan headers, RapidJSON, and various libraries for enhanced functionality. It also modifies CMake files to make the handling of optional components more user-friendly, allowing missing dependencies to disable features without causing build failures on macOS. Additionally, it refines the search paths for the Sparkle framework and adjusts the linking of the discord-rpc library based on the availability of RapidJSON. --- 3rdparty/discord-rpc/CMakeLists.txt | 6 +++- Brewfile | 13 +++++++++ CMakeLists.txt | 15 ++++++++-- Formula/qtsparkle-qt6.rb | 45 +++++++++++++++++++++++++++++ Formula/qtsparkle-qt6/README.md | 10 +++++++ Formula/sparkle-framework.rb | 19 ++++++++++++ Formula/sparkle-framework/README.md | 9 ++++++ cmake/Dmg.cmake | 10 ++++--- cmake/FindRapidJSON.cmake | 31 ++++++++++++++++++++ cmake/OptionalComponent.cmake | 26 +++++++++++++++-- 10 files changed, 175 insertions(+), 9 deletions(-) create mode 100644 Formula/qtsparkle-qt6.rb create mode 100644 Formula/qtsparkle-qt6/README.md create mode 100644 Formula/sparkle-framework.rb create mode 100644 Formula/sparkle-framework/README.md create mode 100644 cmake/FindRapidJSON.cmake diff --git a/3rdparty/discord-rpc/CMakeLists.txt b/3rdparty/discord-rpc/CMakeLists.txt index b86973762..1877bb61d 100644 --- a/3rdparty/discord-rpc/CMakeLists.txt +++ b/3rdparty/discord-rpc/CMakeLists.txt @@ -37,5 +37,9 @@ if(WIN32) target_link_libraries(discord-rpc PRIVATE psapi advapi32) endif() -target_include_directories(discord-rpc SYSTEM PRIVATE ${RapidJSON_INCLUDE_DIRS}) +if(TARGET RapidJSON::RapidJSON) + target_link_libraries(discord-rpc PRIVATE RapidJSON::RapidJSON) +elseif(RapidJSON_INCLUDE_DIRS) + target_include_directories(discord-rpc SYSTEM PRIVATE ${RapidJSON_INCLUDE_DIRS}) +endif() target_include_directories(discord-rpc PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/Brewfile b/Brewfile index 289630a2b..74fcd8648 100644 --- a/Brewfile +++ b/Brewfile @@ -14,6 +14,7 @@ brew "ninja" # Core runtime/build dependencies (required by CMakeLists.txt) brew "qt" # Qt 6 (Core/Gui/Widgets/Network/Sql/Concurrent) +brew "vulkan-headers" # helps Qt6Gui's WrapVulkanHeaders dependency on some setups brew "boost" brew "icu4c" brew "glib" # provides glib-2.0 + gobject-2.0 (via pkg-config) @@ -30,6 +31,8 @@ brew "gstreamer" # brew untap strawberry/local && brew tap strawberry/local "file://$PWD" tap "strawberry/local", "file://#{Dir.pwd}" brew "strawberry/local/kdsingleapplication-qt6" +brew "strawberry/local/qtsparkle-qt6" # optional: QtSparkle integration +brew "strawberry/local/sparkle-framework" # optional: Sparkle integration (framework) # Recommended GStreamer plugin sets for broad codec support (matches README guidance) brew "gst-plugins-base" @@ -38,6 +41,16 @@ brew "gst-plugins-bad" brew "gst-plugins-ugly" brew "gst-libav" +# Optional features (silences CMake warnings / enables extra functionality) +brew "rapidjson" # enables Discord Rich Presence (DISCORD_RPC) +brew "google-sparsehash" # enables stream tagreader (STREAMTAGREADER / libsparsehash) +brew "chromaprint" # enables MusicBrainz + song fingerprinting +brew "fftw" # enables Moodbar (fftw3) +brew "libebur128" # enables EBU R 128 loudness normalization +brew "libcdio" # enables Audio CD support +brew "libmtp" # enables MTP device support +brew "libgpod" # enables iPod classic support + # Helpful for Strawberry's macOS "deploy" target (GStreamer dynamically loads libsoup) brew "libsoup" diff --git a/CMakeLists.txt b/CMakeLists.txt index db3dadaad..a5fa98170 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -252,7 +252,18 @@ endif() find_package(KDSingleApplication-qt${QT_VERSION_MAJOR} 1.1.0 REQUIRED) if(APPLE) - find_library(SPARKLE Sparkle) + # Sparkle may be installed as a developer framework (e.g. via a package manager). + # Help CMake find it by searching typical Homebrew prefix locations as well. + find_library(SPARKLE Sparkle + PATHS + /Library/Frameworks + /System/Library/Frameworks + /opt/homebrew/Frameworks + /opt/homebrew/opt/sparkle-framework/Frameworks + /usr/local/Frameworks + /usr/local/opt/sparkle-framework/Frameworks + PATH_SUFFIXES Frameworks + ) endif() if(WIN32) @@ -271,7 +282,7 @@ if(WIN32) endif() if(APPLE OR WIN32) - find_package(qtsparkle-qt${QT_VERSION_MAJOR}) + find_package(qtsparkle-qt${QT_VERSION_MAJOR} QUIET) if(TARGET "qtsparkle-qt${QT_VERSION_MAJOR}::qtsparkle") set(QTSPARKLE_FOUND ON) endif() diff --git a/Formula/qtsparkle-qt6.rb b/Formula/qtsparkle-qt6.rb new file mode 100644 index 000000000..286887403 --- /dev/null +++ b/Formula/qtsparkle-qt6.rb @@ -0,0 +1,45 @@ +class QtsparkleQt6 < Formula + desc "Qt wrapper library for in-app updates (Qt 6 build)" + homepage "https://github.com/strawberrymusicplayer/qtsparkle" + url "https://github.com/strawberrymusicplayer/qtsparkle/archive/95ca3b77a79540d632b29e9a4df9aed30af5f901.tar.gz" + sha256 "945c9e96d2f6175b134a8ccfd6ec1acd268266d31969b5870d4037e8e5877834" + license "GPL-3.0-or-later" + + depends_on "cmake" => :build + depends_on "ninja" => :build + depends_on "qt" + + def install + args = std_cmake_args + %W[ + -GNinja + -DBUILD_WITH_QT6=ON + -DBUILD_WITH_QT5=OFF + -DBUILD_SHARED_LIBS=ON + -DBUILD_STATIC_LIBS=OFF + ] + + system "cmake", "-S", ".", "-B", "build", *args + system "cmake", "--build", "build" + system "cmake", "--install", "build" + end + + test do + # Strawberry expects: find_package(qtsparkle-qt6) and target qtsparkle-qt6::qtsparkle + (testpath/"CMakeLists.txt").write <<~CMAKE + cmake_minimum_required(VERSION 3.16) + project(qtsparkle_test LANGUAGES CXX) + find_package(qtsparkle-qt6 CONFIG REQUIRED) + add_library(dummy STATIC dummy.cpp) + target_link_libraries(dummy PRIVATE qtsparkle-qt6::qtsparkle) + CMAKE + + (testpath/"dummy.cpp").write <<~CPP + int dummy() { return 0; } + CPP + + system "cmake", "-S", ".", "-B", "build", + "-DCMAKE_PREFIX_PATH=#{opt_prefix}" + system "cmake", "--build", "build" + end +end + diff --git a/Formula/qtsparkle-qt6/README.md b/Formula/qtsparkle-qt6/README.md new file mode 100644 index 000000000..c6732cec1 --- /dev/null +++ b/Formula/qtsparkle-qt6/README.md @@ -0,0 +1,10 @@ +# qtsparkle-qt6 (local Homebrew formula) + +This installs Strawberry’s Qt updater helper library as a CMake package: + +- `find_package(qtsparkle-qt6 CONFIG REQUIRED)` +- target: `qtsparkle-qt6::qtsparkle` + +Strawberry will pick it up automatically when present and enable the optional +**QtSparkle integration**. + diff --git a/Formula/sparkle-framework.rb b/Formula/sparkle-framework.rb new file mode 100644 index 000000000..37dba97c5 --- /dev/null +++ b/Formula/sparkle-framework.rb @@ -0,0 +1,19 @@ +class SparkleFramework < Formula + desc "Sparkle.framework for macOS app updates (framework-only packaging)" + homepage "https://sparkle-project.org/" + url "https://github.com/sparkle-project/Sparkle/releases/download/2.8.1/Sparkle-2.8.1.tar.xz" + sha256 "5cddb7695674ef7704268f38eccaee80e3accbf19e61c1689efff5b6116d85be" + license "MIT" + + depends_on :macos + + def install + frameworks = prefix/"Frameworks" + frameworks.install "Sparkle.framework" + end + + test do + assert_predicate prefix/"Frameworks/Sparkle.framework", :exist? + end +end + diff --git a/Formula/sparkle-framework/README.md b/Formula/sparkle-framework/README.md new file mode 100644 index 000000000..5a37d5c07 --- /dev/null +++ b/Formula/sparkle-framework/README.md @@ -0,0 +1,9 @@ +# sparkle-framework (local Homebrew formula) + +Installs the upstream `Sparkle.framework` into: + +- `$(brew --prefix sparkle-framework)/Frameworks/Sparkle.framework` + +This is used to enable Strawberry’s optional **Sparkle integration** on macOS +(`find_library(SPARKLE Sparkle)` in the main `CMakeLists.txt`). + diff --git a/cmake/Dmg.cmake b/cmake/Dmg.cmake index 7967d60ca..837a83f72 100644 --- a/cmake/Dmg.cmake +++ b/cmake/Dmg.cmake @@ -1,18 +1,20 @@ -find_program(MACDEPLOYQT_EXECUTABLE NAMES macdeployqt PATHS /usr/bin /usr/local/bin /opt/local/bin /usr/local/opt/qt6/bin REQUIRED) +# NOTE: Packaging helpers should not be REQUIRED at configure time. +# Missing tools should simply disable the related custom targets. +find_program(MACDEPLOYQT_EXECUTABLE NAMES macdeployqt PATHS /usr/bin /usr/local/bin /opt/local/bin /usr/local/opt/qt6/bin) if(MACDEPLOYQT_EXECUTABLE) message(STATUS "Found macdeployqt: ${MACDEPLOYQT_EXECUTABLE}") else() message(WARNING "Missing macdeployqt executable.") endif() -find_program(MACDEPLOYCHECK_EXECUTABLE NAMES macdeploycheck PATHS /usr/bin /usr/local/bin /opt/local/bin /usr/local/opt/qt6/bin REQUIRED) +find_program(MACDEPLOYCHECK_EXECUTABLE NAMES macdeploycheck PATHS /usr/bin /usr/local/bin /opt/local/bin /usr/local/opt/qt6/bin) if(MACDEPLOYCHECK_EXECUTABLE) message(STATUS "Found macdeploycheck: ${MACDEPLOYCHECK_EXECUTABLE}") else() - message(WARNING "Missing macdeploycheck executable.") + message(STATUS "macdeploycheck not found (optional): 'deploycheck' target will be unavailable.") endif() -find_program(CREATEDMG_EXECUTABLE NAMES create-dmg REQUIRED) +find_program(CREATEDMG_EXECUTABLE NAMES create-dmg) if(CREATEDMG_EXECUTABLE) message(STATUS "Found create-dmg: ${CREATEDMG_EXECUTABLE}") else() diff --git a/cmake/FindRapidJSON.cmake b/cmake/FindRapidJSON.cmake new file mode 100644 index 000000000..084f76e3e --- /dev/null +++ b/cmake/FindRapidJSON.cmake @@ -0,0 +1,31 @@ +# Try to find RapidJSON (header-only). +# +# This project uses `find_package(RapidJSON)` and expects: +# - RapidJSON_FOUND +# - RapidJSON_INCLUDE_DIRS +# +# Homebrew's `rapidjson` formula commonly installs headers to: +# /opt/homebrew/include/rapidjson +# but does not always ship a `RapidJSONConfig.cmake`, so we provide this +# Find-module fallback. + +find_path(RapidJSON_INCLUDE_DIR + NAMES rapidjson/document.h +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(RapidJSON + REQUIRED_VARS RapidJSON_INCLUDE_DIR +) + +if(RapidJSON_FOUND) + set(RapidJSON_INCLUDE_DIRS "${RapidJSON_INCLUDE_DIR}") +endif() + +if(RapidJSON_FOUND AND NOT TARGET RapidJSON::RapidJSON) + add_library(RapidJSON::RapidJSON INTERFACE IMPORTED) + set_target_properties(RapidJSON::RapidJSON PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${RapidJSON_INCLUDE_DIR}" + ) +endif() + diff --git a/cmake/OptionalComponent.cmake b/cmake/OptionalComponent.cmake index 843176bc6..882597801 100644 --- a/cmake/OptionalComponent.cmake +++ b/cmake/OptionalComponent.cmake @@ -1,6 +1,23 @@ set(summary_willbuild "") set(summary_willnotbuild "") +# On some platforms (notably macOS via Homebrew), many "optional" dependencies are +# not installed by default. Historically, Strawberry treated missing optional deps +# as a hard error when the option defaulted to ON, which makes first-time builds +# frustrating. +# +# This toggle controls that behavior: +# - ON => missing optional deps abort the configure (packager/CI-friendly) +# - OFF => missing optional deps auto-disable the component (dev-friendly) +set(_optional_components_fatal_default ON) +if(APPLE) + set(_optional_components_fatal_default OFF) +endif() +option(OPTIONAL_COMPONENTS_MISSING_DEPS_ARE_FATAL + "If ON, missing optional component dependencies are fatal (otherwise components auto-disable)" + ${_optional_components_fatal_default} +) + macro(optional_component_summary_add name test) if (${test}) list(APPEND summary_willbuild ${name}) @@ -80,8 +97,13 @@ function(optional_component name default description) set(text "${description} (missing ${deplist_text})") set(summary_willnotbuild "${summary_willnotbuild};${text}" PARENT_SCOPE) - - message(FATAL_ERROR "${text}, to disable this optional feature, pass -D${option_variable}=OFF to CMake") + if(OPTIONAL_COMPONENTS_MISSING_DEPS_ARE_FATAL) + message(FATAL_ERROR "${text}, to disable this optional feature, pass -D${option_variable}=OFF to CMake") + else() + message(STATUS "${text} - disabling ${option_variable}") + set(${option_variable} OFF CACHE BOOL "${description}" FORCE) + return() + endif() else() set(${have_variable} ON PARENT_SCOPE)