# host/CMakeLists.txt cmake_minimum_required(VERSION 3.18) project(EISConfigurator 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) # --- FOR WINDOWS MSVC ERRORS --- if(MSVC) add_compile_options($<$:/std:clatest>) add_compile_definitions(_CRT_SECURE_NO_WARNINGS) endif() include(FetchContent) option(BUILD_ANDROID "Build for Android" OFF) option(BUILD_IOS "Build for iOS" OFF) find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets SerialPort PrintSupport) if(ANDROID) find_package(Qt6 REQUIRED COMPONENTS AndroidExtras) endif() # ========================================== # --- FFTW3 CONFIGURATION --- # ========================================== if(WIN32) # Windows: Expects FFTW3 to be installed/found via Config find_package(FFTW3 CONFIG REQUIRED) if(TARGET FFTW3::fftw3) add_library(fftw3 ALIAS FFTW3::fftw3) endif() elseif(APPLE AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64" AND NOT BUILD_IOS) message(STATUS "Detected Apple Silicon Desktop. Using Homebrew FFTW3 (Double).") find_library(FFTW3_LIB NAMES fftw3 libfftw3 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 "FFTW3 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 (Double Precision)...") set(ENABLE_FLOAT OFF CACHE BOOL "Build double 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) # Enable NEON for Android ARM64 / iOS 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() # Patch for older CMake versions inside the tarball if needed if(UNIX) set(PATCH_CMD sed -i.bak "s/cmake_minimum_required.*/cmake_minimum_required(VERSION 3.16)/" /CMakeLists.txt) else() set(PATCH_CMD "") endif() 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() # ========================================== # --- QCUSTOMPLOT --- # ========================================== FetchContent_Declare( QCustomPlot URL https://www.qcustomplot.com/release/2.1.1/QCustomPlot.tar.gz ) FetchContent_MakeAvailable(QCustomPlot) # ========================================== # --- ICON GENERATION --- # ========================================== set(ICON_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/assets/icon_source.png") 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) if(WIN32) set(WINDOWS_ICON "${CMAKE_CURRENT_BINARY_DIR}/app_icon.ico") set(WINDOWS_RC "${CMAKE_CURRENT_BINARY_DIR}/app_icon.rc") set(ICON_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_icons.bat") file(WRITE "${WINDOWS_RC}" "IDI_ICON1 ICON \"app_icon.ico\"\n") add_custom_command( OUTPUT "${WINDOWS_ICON}" COMMAND "${ICON_SCRIPT}" "${MAGICK_EXECUTABLE}" "${ICON_SOURCE}" "${WINDOWS_ICON}" WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" DEPENDS "${ICON_SOURCE}" "${ICON_SCRIPT}" COMMENT "Generating Windows Icon..." VERBATIM ) add_custom_target(GenerateIcons DEPENDS "${WINDOWS_ICON}") else() set(MACOS_ICON "${CMAKE_CURRENT_SOURCE_DIR}/assets/icons/app_icon.icns") 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") set(ICON_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_icons.sh") execute_process(COMMAND chmod +x "${ICON_SCRIPT}") add_custom_command( OUTPUT "${MACOS_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 Cross-Platform Icons..." VERBATIM ) add_custom_target(GenerateIcons DEPENDS "${MACOS_ICON}" "${IOS_CONTENTS_JSON}" "${ANDROID_RES_PATH}") endif() endif() # --- Sources --- set(PROJECT_SOURCES src/main.cpp src/MainWindow.cpp src/MainWindow_UI.cpp src/MainWindow_Actions.cpp src/MainWindow_Serial.cpp src/GraphWidget.cpp ${qcustomplot_SOURCE_DIR}/qcustomplot.cpp ) if(EXISTS "${ICON_SOURCE}") if(WIN32) list(APPEND PROJECT_SOURCES ${WINDOWS_RC} ${WINDOWS_ICON}) elseif(APPLE AND NOT BUILD_IOS) list(APPEND PROJECT_SOURCES ${MACOS_ICON}) endif() endif() set(PROJECT_HEADERS src/MainWindow.h src/GraphWidget.h ${qcustomplot_SOURCE_DIR}/qcustomplot.h ) # Use qt_add_executable for proper Android/iOS handling qt_add_executable(EISConfigurator MANUAL_FINALIZATION ${PROJECT_SOURCES} ${PROJECT_HEADERS}) if(EXISTS "${ICON_SOURCE}" AND MAGICK_EXECUTABLE) add_dependencies(EISConfigurator GenerateIcons) endif() # --- Mobile Definitions --- if(BUILD_ANDROID OR BUILD_IOS) target_compile_definitions(EISConfigurator PRIVATE IS_MOBILE) endif() # --- Linking --- # Handle FFTW3 Linking and Include Paths if(TARGET fftw3) set(FFTW_TARGET fftw3) # If built from source via FetchContent, we need to manually add include dirs if(DEFINED fftw3_source_SOURCE_DIR) target_include_directories(EISConfigurator PRIVATE "${fftw3_source_SOURCE_DIR}/api" "${fftw3_source_BINARY_DIR}" ) endif() else() # Fallback if target isn't defined (shouldn't happen with above logic) set(FFTW_TARGET fftw3) endif() target_include_directories(EISConfigurator PRIVATE ${qcustomplot_SOURCE_DIR}) if(BUILD_ANDROID) target_link_libraries(EISConfigurator PRIVATE log m) set_property(TARGET EISConfigurator PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/android) target_link_libraries(EISConfigurator PRIVATE Qt6::Widgets Qt6::SerialPort Qt6::AndroidExtras) else() add_executable(EISConfigurator ${PROJECT_SOURCES}) target_link_libraries(EISConfigurator PRIVATE Qt6::Widgets Qt6::SerialPort) 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_target_properties(EISConfigurator PROPERTIES MACOSX_BUNDLE TRUE MACOSX_BUNDLE_BUNDLE_NAME "EIS Configurator" MACOSX_BUNDLE_GUI_IDENTIFIER "com.eis.configurator" 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}") file(MAKE_DIRECTORY "${IOS_ASSETS_PATH}") target_sources(EISConfigurator PRIVATE "${IOS_ASSETS_PATH}") endif() endif() if(APPLE AND NOT BUILD_IOS) set_target_properties(EISConfigurator PROPERTIES MACOSX_BUNDLE TRUE MACOSX_BUNDLE_BUNDLE_NAME "EIS Configurator" MACOSX_BUNDLE_GUI_IDENTIFIER "com.eis.configurator" MACOSX_BUNDLE_ICON_FILE "app_icon.icns" RESOURCE "${MACOS_ICON}" ) elseif(WIN32) set_target_properties(EISConfigurator PROPERTIES WIN32_EXECUTABLE TRUE ) target_link_libraries(EISConfigurator PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets Qt6::SerialPort Qt6::PrintSupport ${FFTW_TARGET} ) endif() # CRITICAL: Triggers androiddeployqt to build the APK qt_finalize_executable(EISConfigurator)