cmake_minimum_required(VERSION 3.19) project(ApartConcept1Controller VERSION 1.0.0 DESCRIPTION "RS232 controller for the Apart Concept 1 amplifier" LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) endif() # Required Qt6 component find_package(Qt6 REQUIRED COMPONENTS Widgets) # Optional Qt6 SerialPort: real hardware support is compiled in when available. # Without it the app still builds and runs in simulator mode. find_package(Qt6 QUIET OPTIONAL_COMPONENTS SerialPort) set(SOURCES src/main.cpp src/protocol/Concept1Protocol.cpp src/transport/SimulatorTransport.cpp src/core/Concept1Controller.cpp src/ui/ThemeManager.cpp src/ui/MainWindow.cpp ) set(HEADERS src/protocol/Concept1Protocol.h src/protocol/Concept1State.h src/transport/ITransport.h src/transport/SimulatorTransport.h src/core/Concept1Controller.h src/ui/ThemeManager.h src/ui/MainWindow.h ) if(Qt6SerialPort_FOUND) list(APPEND SOURCES src/transport/SerialTransport.cpp) list(APPEND HEADERS src/transport/SerialTransport.h) message(STATUS "Qt6 SerialPort found -> real RS232 hardware support ENABLED") else() message(WARNING "Qt6 SerialPort NOT found -> building with SIMULATOR only. " "Install it (e.g. 'sudo pacman -S qt6-serialport') for hardware support.") endif() qt_add_resources(SOURCES resources/app.qrc) # WIN32 makes this a GUI app on Windows (no console window). Ignored elsewhere. add_executable(apart-controller WIN32 ${SOURCES} ${HEADERS}) target_include_directories(apart-controller PRIVATE src) target_link_libraries(apart-controller PRIVATE Qt6::Widgets) if(Qt6SerialPort_FOUND) target_link_libraries(apart-controller PRIVATE Qt6::SerialPort) target_compile_definitions(apart-controller PRIVATE HAVE_QT_SERIALPORT) endif() # --------------------------------------------------------------------------- # Installation + packaging (Windows installer via CPack/NSIS) # --------------------------------------------------------------------------- install(TARGETS apart-controller RUNTIME DESTINATION .) if(WIN32) # Run windeployqt at install time to gather Qt DLLs + plugins next to the exe. find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${Qt6_DIR}/../../../bin" "${Qt6_DIR}/../../../../bin") if(WINDEPLOYQT_EXECUTABLE) install(CODE " execute_process(COMMAND \"${WINDEPLOYQT_EXECUTABLE}\" --release --no-translations --compiler-runtime --dir \"\${CMAKE_INSTALL_PREFIX}\" \"\${CMAKE_INSTALL_PREFIX}/apart-controller.exe\") ") else() message(WARNING "windeployqt not found - Qt DLLs will not be auto-deployed.") endif() # MinGW runtime DLLs (windeployqt's --compiler-runtime often skips these). get_filename_component(_mingw_bin "${CMAKE_CXX_COMPILER}" DIRECTORY) foreach(_dll libgcc_s_seh-1.dll libstdc++-6.dll libwinpthread-1.dll) if(EXISTS "${_mingw_bin}/${_dll}") install(FILES "${_mingw_bin}/${_dll}" DESTINATION .) endif() endforeach() endif() set(CPACK_PACKAGE_NAME "Apart Concept 1 Controller") set(CPACK_PACKAGE_VENDOR "ApartController") set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_DESCRIPTION}") set(CPACK_PACKAGE_INSTALL_DIRECTORY "Apart Concept 1 Controller") if(WIN32) set(CPACK_GENERATOR "NSIS") set(CPACK_NSIS_DISPLAY_NAME "Apart Concept 1 Controller") set(CPACK_NSIS_PACKAGE_NAME "Apart Concept 1 Controller") set(CPACK_NSIS_INSTALLED_ICON_NAME "apart-controller.exe") set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON) set(CPACK_NSIS_MODIFY_PATH OFF) # Start-menu + desktop shortcut pointing at the exe. set(CPACK_PACKAGE_EXECUTABLES "apart-controller" "Apart Concept 1 Controller") set(CPACK_NSIS_CREATE_DESKTOP_LINKS "apart-controller") endif() include(CPack)