From 914e25adfc89d1254671022297426621fe2cd787 Mon Sep 17 00:00:00 2001 From: Mischa Date: Wed, 21 Jan 2026 21:45:50 -0800 Subject: [PATCH 1/4] Add macOS Framework build support Adds ENABLE_MACOS_FRAMEWORK cmake option to build projectM-4.framework and projectM-4-playlist.framework bundles instead of plain dylibs. Only available on macOS with shared library builds. The frameworks include all public headers in the Headers/ directory and use standard macOS framework versioning (Version A). Fixes #924 --- CMakeLists.txt | 2 ++ src/api/CMakeLists.txt | 27 +++++++++++++++------------ src/libprojectM/CMakeLists.txt | 14 +++++++++++++- src/playlist/CMakeLists.txt | 11 +++++++++++ 4 files changed, 41 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b0268b90af..32c47e71ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,6 +97,7 @@ endif() cmake_dependent_option(BUILD_SHARED_LIBS "Build and install libprojectM as a shared libraries. If OFF, builds as static libraries." ON "NOT ENABLE_EMSCRIPTEN" OFF) cmake_dependent_option(ENABLE_GLES "Enable OpenGL ES support" OFF "NOT ENABLE_EMSCRIPTEN AND NOT CMAKE_SYSTEM_NAME STREQUAL Android" ON) cmake_dependent_option(ENABLE_INSTALL "Enable installing projectM libraries and headers." OFF "NOT PROJECT_IS_TOP_LEVEL" ON) +cmake_dependent_option(ENABLE_MACOS_FRAMEWORK "Build as macOS Framework bundles instead of plain shared libraries." OFF "CMAKE_SYSTEM_NAME STREQUAL Darwin AND BUILD_SHARED_LIBS" OFF) # Experimental/unsupported features option(ENABLE_CXX_INTERFACE "Enable exporting C++ symbols for ProjectM and PCM classes, not only the C API. Warning: This is not very portable." OFF) @@ -268,6 +269,7 @@ if(ENABLE_SDL_UI) message(STATUS " SDL2 version: ${SDL2_VERSION}") endif() message(STATUS " OpenGL ES: ${ENABLE_GLES}") +message(STATUS " macOS Framework: ${ENABLE_MACOS_FRAMEWORK}") message(STATUS " Emscripten: ${ENABLE_EMSCRIPTEN}") if(CMAKE_SYSTEM_NAME STREQUAL Emscripten) message(STATUS " - PThreads: ${USE_PTHREADS}") diff --git a/src/api/CMakeLists.txt b/src/api/CMakeLists.txt index 0a94bfffd8..5443d6e401 100644 --- a/src/api/CMakeLists.txt +++ b/src/api/CMakeLists.txt @@ -22,24 +22,27 @@ generate_export_header(projectM_api set(PROJECTM_PUBLIC_HEADERS "${PROJECTM_EXPORT_HEADER}" "${CMAKE_CURRENT_BINARY_DIR}/include/projectM-4/version.h" - include/projectM-4/audio.h - include/projectM-4/callbacks.h - include/projectM-4/core.h - include/projectM-4/debug.h - include/projectM-4/logging.h - include/projectM-4/memory.h - include/projectM-4/parameters.h - include/projectM-4/projectM.h - include/projectM-4/render_opengl.h - include/projectM-4/touch.h - include/projectM-4/types.h - include/projectM-4/user_sprites.h + "${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/audio.h" + "${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/callbacks.h" + "${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/core.h" + "${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/debug.h" + "${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/logging.h" + "${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/memory.h" + "${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/parameters.h" + "${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/projectM.h" + "${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/render_opengl.h" + "${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/touch.h" + "${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/types.h" + "${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/user_sprites.h" ) if(ENABLE_CXX_INTERFACE) list(APPEND PROJECTM_PUBLIC_HEADERS ${PROJECTM_CXX_EXPORT_HEADER}) endif() +# Make available to parent scope for framework builds +set(PROJECTM_PUBLIC_HEADERS "${PROJECTM_PUBLIC_HEADERS}" PARENT_SCOPE) + target_sources(projectM_api PRIVATE ${PROJECTM_PUBLIC_HEADERS} diff --git a/src/libprojectM/CMakeLists.txt b/src/libprojectM/CMakeLists.txt index 63b11c2c81..bebd24c49b 100644 --- a/src/libprojectM/CMakeLists.txt +++ b/src/libprojectM/CMakeLists.txt @@ -130,6 +130,17 @@ if(BUILD_SHARED_LIBS) PUBLIC ${CMAKE_DL_LIBS} ) + + if(ENABLE_MACOS_FRAMEWORK) + set_target_properties(projectM PROPERTIES + FRAMEWORK TRUE + FRAMEWORK_VERSION A + MACOSX_FRAMEWORK_IDENTIFIER com.github.projectm-visualizer.projectM + MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${PROJECT_VERSION}" + MACOSX_FRAMEWORK_BUNDLE_VERSION "${PROJECT_VERSION}" + PUBLIC_HEADER "${PROJECTM_PUBLIC_HEADERS}" + ) + endif() else() target_compile_definitions(projectM_main PUBLIC @@ -158,7 +169,8 @@ if(ENABLE_INSTALL) LIBRARY DESTINATION "${PROJECTM_LIB_DIR}" COMPONENT Runtime RUNTIME DESTINATION "${PROJECTM_RUNTIME_DIR}" COMPONENT Runtime ARCHIVE DESTINATION "${PROJECTM_LIB_DIR}" COMPONENT Devel - PUBLIC_HEADER DESTINATION "${PROJECTM_INCLUDE_DIR}/libprojectM" COMPONENT Devel + PUBLIC_HEADER DESTINATION "${PROJECTM_INCLUDE_DIR}/projectM-4" COMPONENT Devel + FRAMEWORK DESTINATION "${PROJECTM_LIB_DIR}" COMPONENT Runtime ) if(ENABLE_CXX_INTERFACE) diff --git a/src/playlist/CMakeLists.txt b/src/playlist/CMakeLists.txt index bcd50540a3..03f1d6ed0a 100644 --- a/src/playlist/CMakeLists.txt +++ b/src/playlist/CMakeLists.txt @@ -78,6 +78,16 @@ if(BUILD_SHARED_LIBS) PUBLIC ${CMAKE_DL_LIBS} ) + + if(ENABLE_MACOS_FRAMEWORK) + set_target_properties(projectM_playlist PROPERTIES + FRAMEWORK TRUE + FRAMEWORK_VERSION A + MACOSX_FRAMEWORK_IDENTIFIER com.github.projectm-visualizer.projectM-playlist + MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${PROJECT_VERSION}" + MACOSX_FRAMEWORK_BUNDLE_VERSION "${PROJECT_VERSION}" + ) + endif() else() target_compile_definitions(projectM_playlist_main PUBLIC @@ -111,6 +121,7 @@ if(ENABLE_INSTALL) RUNTIME DESTINATION "${PROJECTM_RUNTIME_DIR}" COMPONENT Runtime ARCHIVE DESTINATION "${PROJECTM_LIB_DIR}" COMPONENT Devel PUBLIC_HEADER DESTINATION "${PROJECTM_INCLUDE_DIR}/projectM-4" COMPONENT Devel + FRAMEWORK DESTINATION "${PROJECTM_LIB_DIR}" COMPONENT Runtime ) From 65bdc7e9129d0bccc0349b12dfc1b4ef7e769b9c Mon Sep 17 00:00:00 2001 From: Mischa Date: Sat, 24 Jan 2026 22:18:19 -0800 Subject: [PATCH 2/4] Address Copilot review feedback - Use absolute paths for headers exported to parent scope - Include C++ headers in framework when ENABLE_CXX_INTERFACE is on --- src/libprojectM/CMakeLists.txt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/libprojectM/CMakeLists.txt b/src/libprojectM/CMakeLists.txt index bebd24c49b..60074c8dff 100644 --- a/src/libprojectM/CMakeLists.txt +++ b/src/libprojectM/CMakeLists.txt @@ -132,13 +132,24 @@ if(BUILD_SHARED_LIBS) ) if(ENABLE_MACOS_FRAMEWORK) + # Start with C API headers + set(_framework_public_headers ${PROJECTM_PUBLIC_HEADERS}) + + # Add C++ headers when the C++ interface is enabled + if(ENABLE_CXX_INTERFACE) + list(APPEND _framework_public_headers + "${CMAKE_CURRENT_SOURCE_DIR}/Audio/PCM.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/ProjectM.hpp" + ) + endif() + set_target_properties(projectM PROPERTIES FRAMEWORK TRUE FRAMEWORK_VERSION A MACOSX_FRAMEWORK_IDENTIFIER com.github.projectm-visualizer.projectM MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${PROJECT_VERSION}" MACOSX_FRAMEWORK_BUNDLE_VERSION "${PROJECT_VERSION}" - PUBLIC_HEADER "${PROJECTM_PUBLIC_HEADERS}" + PUBLIC_HEADER "${_framework_public_headers}" ) endif() else() From 1413be49ec4014cbc1da2713edb9569c66e329ae Mon Sep 17 00:00:00 2001 From: Mischa Date: Sat, 24 Jan 2026 22:19:20 -0800 Subject: [PATCH 3/4] Trigger CI From c8ab097f51775a90a73f30aaba9b8c3d53db0e9c Mon Sep 17 00:00:00 2001 From: Mischa Date: Sat, 24 Jan 2026 22:21:46 -0800 Subject: [PATCH 4/4] chore: sync --- src/api/CMakeLists.txt | 3 --- src/libprojectM/CMakeLists.txt | 11 +++++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/api/CMakeLists.txt b/src/api/CMakeLists.txt index 5443d6e401..3228e85b32 100644 --- a/src/api/CMakeLists.txt +++ b/src/api/CMakeLists.txt @@ -40,9 +40,6 @@ if(ENABLE_CXX_INTERFACE) list(APPEND PROJECTM_PUBLIC_HEADERS ${PROJECTM_CXX_EXPORT_HEADER}) endif() -# Make available to parent scope for framework builds -set(PROJECTM_PUBLIC_HEADERS "${PROJECTM_PUBLIC_HEADERS}" PARENT_SCOPE) - target_sources(projectM_api PRIVATE ${PROJECTM_PUBLIC_HEADERS} diff --git a/src/libprojectM/CMakeLists.txt b/src/libprojectM/CMakeLists.txt index 60074c8dff..8819e76809 100644 --- a/src/libprojectM/CMakeLists.txt +++ b/src/libprojectM/CMakeLists.txt @@ -132,13 +132,20 @@ if(BUILD_SHARED_LIBS) ) if(ENABLE_MACOS_FRAMEWORK) - # Start with C API headers - set(_framework_public_headers ${PROJECTM_PUBLIC_HEADERS}) + # Get C API headers from the API target + get_target_property(_framework_public_headers projectM_api PUBLIC_HEADER) # Add C++ headers when the C++ interface is enabled if(ENABLE_CXX_INTERFACE) list(APPEND _framework_public_headers + "${CMAKE_CURRENT_SOURCE_DIR}/Audio/AudioConstants.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/Audio/FrameAudioData.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/Audio/Loudness.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/Audio/MilkdropFFT.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/Audio/PCM.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/Audio/WaveformAligner.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/Renderer/RenderContext.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/Logging.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/ProjectM.hpp" ) endif()