EIS/host/CMakeLists.txt

257 lines
8.7 KiB
CMake

# 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($<$<COMPILE_LANGUAGE:C>:/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)/" <SOURCE_DIR>/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)