# CMakeLists.txt cmake_minimum_required(VERSION 3.18) project(YrCrystals VERSION 1.0 LANGUAGES CXX C) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) include(FetchContent) option(BUILD_ANDROID "Build for Android" OFF) option(BUILD_IOS "Build for iOS" OFF) find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Multimedia OpenGLWidgets) # --- FFTW3 Configuration --- if(APPLE AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64" AND NOT BUILD_IOS) message(STATUS "Detected Apple Silicon Desktop. Using Homebrew FFTW3F.") find_library(FFTW3_LIB NAMES fftw3f libfftw3f PATHS /opt/homebrew/lib NO_DEFAULT_PATH) find_path(FFTW3_INCLUDE_DIR fftw3.h PATHS /opt/homebrew/include NO_DEFAULT_PATH) if(NOT FFTW3_LIB OR NOT FFTW3_INCLUDE_DIR) message(FATAL_ERROR "FFTW3F not found in /opt/homebrew. Please run: brew install fftw") endif() add_library(fftw3 STATIC IMPORTED) set_target_properties(fftw3 PROPERTIES IMPORTED_LOCATION "${FFTW3_LIB}" INTERFACE_INCLUDE_DIRECTORIES "${FFTW3_INCLUDE_DIR}" ) else() message(STATUS "Building FFTW3 from source...") set(ENABLE_FLOAT ON CACHE BOOL "Build single precision" FORCE) set(ENABLE_SSE OFF CACHE BOOL "Disable SSE" FORCE) set(ENABLE_SSE2 OFF CACHE BOOL "Disable SSE2" FORCE) set(ENABLE_AVX OFF CACHE BOOL "Disable AVX" FORCE) set(ENABLE_AVX2 OFF CACHE BOOL "Disable AVX2" FORCE) set(ENABLE_THREADS OFF CACHE BOOL "Disable Threads" FORCE) set(ENABLE_OPENMP OFF CACHE BOOL "Disable OpenMP" FORCE) set(ENABLE_MPI OFF CACHE BOOL "Disable MPI" FORCE) set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build Static Libs" FORCE) set(BUILD_TESTS OFF CACHE BOOL "Disable Tests" FORCE) if(ANDROID_ABI STREQUAL "arm64-v8a") message(STATUS "Enabling NEON for Android ARM64") set(ENABLE_NEON ON CACHE BOOL "Enable NEON" FORCE) elseif(BUILD_IOS) set(ENABLE_NEON ON CACHE BOOL "Enable NEON" FORCE) endif() set(PATCH_CMD sed -i.bak "s/cmake_minimum_required.*/cmake_minimum_required(VERSION 3.16)/" /CMakeLists.txt) FetchContent_Declare( fftw3_source URL https://www.fftw.org/fftw-3.3.10.tar.gz DOWNLOAD_EXTRACT_TIMESTAMP TRUE PATCH_COMMAND ${PATCH_CMD} ) FetchContent_MakeAvailable(fftw3_source) endif() # --- Loop Tempo Estimator --- # Disable tests and vamp plugin for the library to speed up build and reduce deps set(BUILD_TESTS OFF CACHE BOOL "Build tests" FORCE) set(BUILD_VAMP_PLUGIN OFF CACHE BOOL "Build Vamp plugin" FORCE) add_subdirectory(libraries/loop-tempo-estimator) # --- Icon Generation --- set(ICON_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/assets/icon_source.png") set(ICON_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_icons.sh") set(MACOS_ICON "${CMAKE_CURRENT_SOURCE_DIR}/assets/icons/app_icon.icns") set(WINDOWS_ICON "${CMAKE_CURRENT_SOURCE_DIR}/assets/icons/app_icon.ico") set(IOS_ASSETS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/ios/Assets.xcassets") set(IOS_CONTENTS_JSON "${IOS_ASSETS_PATH}/Contents.json") set(ANDROID_RES_PATH "${CMAKE_CURRENT_SOURCE_DIR}/android/res/mipmap-mdpi/ic_launcher.png") # Find ImageMagick 'magick' executable find_program(MAGICK_EXECUTABLE NAMES magick) if(NOT MAGICK_EXECUTABLE) message(WARNING "ImageMagick 'magick' not found. Icons will not be generated.") endif() if(EXISTS "${ICON_SOURCE}" AND MAGICK_EXECUTABLE) execute_process(COMMAND chmod +x "${ICON_SCRIPT}") add_custom_command( OUTPUT "${MACOS_ICON}" "${WINDOWS_ICON}" "${IOS_CONTENTS_JSON}" "${ANDROID_RES_PATH}" COMMAND "${ICON_SCRIPT}" "${MAGICK_EXECUTABLE}" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" DEPENDS "${ICON_SOURCE}" "${ICON_SCRIPT}" COMMENT "Generating icons from source using ${MAGICK_EXECUTABLE}..." VERBATIM ) add_custom_target(GenerateIcons DEPENDS "${MACOS_ICON}" "${WINDOWS_ICON}" "${IOS_CONTENTS_JSON}" "${ANDROID_RES_PATH}") endif() # --- Sources --- set(PROJECT_SOURCES src/main.cpp src/Utils.cpp src/Processor.cpp src/AudioEngine.cpp src/VisualizerWidget.cpp src/CommonWidgets.cpp src/PlayerControls.cpp src/MainWindow.cpp ) if(EXISTS "${ICON_SOURCE}") list(APPEND PROJECT_SOURCES ${MACOS_ICON} ${WINDOWS_ICON}) endif() set(PROJECT_HEADERS src/Utils.h src/Processor.h src/AudioEngine.h src/VisualizerWidget.h src/CommonWidgets.h src/PlayerControls.h src/MainWindow.h ) qt_add_executable(YrCrystals MANUAL_FINALIZATION ${PROJECT_SOURCES} ${PROJECT_HEADERS}) if(EXISTS "${ICON_SOURCE}" AND MAGICK_EXECUTABLE) add_dependencies(YrCrystals GenerateIcons) endif() # --- Mobile Definitions --- if(BUILD_ANDROID OR BUILD_IOS) target_compile_definitions(YrCrystals PRIVATE IS_MOBILE) endif() # --- Linking --- if(TARGET fftw3f) set(FFTW_TARGET fftw3f) target_include_directories(YrCrystals PRIVATE "${fftw3_source_SOURCE_DIR}/api" "${fftw3_source_BINARY_DIR}" ) else() set(FFTW_TARGET fftw3) endif() target_link_libraries(YrCrystals PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets Qt6::Multimedia Qt6::OpenGLWidgets ${FFTW_TARGET} loop-tempo-estimator ) if(BUILD_ANDROID) target_link_libraries(YrCrystals PRIVATE log m) set_property(TARGET YrCrystals PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android") endif() if(BUILD_IOS) if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/ios/Info.plist") message(FATAL_ERROR "Missing ios/Info.plist. Please create it before building.") endif() set_source_files_properties(src/Utils.cpp PROPERTIES LANGUAGE OBJCXX) set_target_properties(YrCrystals PROPERTIES MACOSX_BUNDLE TRUE MACOSX_BUNDLE_BUNDLE_NAME "Yr Crystals" MACOSX_BUNDLE_GUI_IDENTIFIER "com.yrcrystals.app" MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/ios/Info.plist" XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon" RESOURCE "${IOS_ASSETS_PATH}" ) if(EXISTS "${ICON_SOURCE}") message(STATUS "Adding iOS Assets from: ${IOS_ASSETS_PATH}") file(MAKE_DIRECTORY "${IOS_ASSETS_PATH}") target_sources(YrCrystals PRIVATE "${IOS_ASSETS_PATH}") endif() qt_import_plugins(YrCrystals EXCLUDE Qt6::FFmpegMediaPlugin Qt6::QFFmpegMediaPlugin ) target_link_libraries(YrCrystals PRIVATE "-framework AudioToolbox" "-framework AVFoundation" "-framework CoreMedia" "-framework VideoToolbox" "-framework CoreVideo" "-framework CoreFoundation" "-framework UIKit" "-framework UniformTypeIdentifiers" "-lz" "-lbz2" "-liconv" ) endif() if(APPLE AND NOT BUILD_IOS) set_target_properties(YrCrystals PROPERTIES MACOSX_BUNDLE TRUE MACOSX_BUNDLE_BUNDLE_NAME "Yr Crystals" MACOSX_BUNDLE_GUI_IDENTIFIER "com.yrcrystals.app" MACOSX_BUNDLE_ICON_FILE "app_icon.icns" RESOURCE "${MACOS_ICON}" ) elseif(WIN32) set_target_properties(YrCrystals PROPERTIES WIN32_EXECUTABLE TRUE ) endif() qt_finalize_executable(YrCrystals)