diff --git a/.github/workflows/push_pull.yml b/.github/workflows/push_pull.yml index ba66340..2d291c8 100644 --- a/.github/workflows/push_pull.yml +++ b/.github/workflows/push_pull.yml @@ -11,7 +11,7 @@ on: - '20[2-9][0-9]-[0-9][0-9]-[0-9][0-9]' pull_request: branches: - - 'master' + - 'main' jobs: diff --git a/.github/workflows/qt5_6.yml b/.github/workflows/qt5_6.yml index 1168ba4..9e6180c 100644 --- a/.github/workflows/qt5_6.yml +++ b/.github/workflows/qt5_6.yml @@ -28,14 +28,14 @@ jobs: fail-fast: false matrix: os: [ - { distribution: debian, codename: bullseye, description: Debian Bullseye (amd64), architecture: [ amd64, linux/amd64 ], platform: x11, qt_version: '6.4.2' }, - { distribution: debian, codename: bullseye, description: Debian Bullseye (Raspberry Pi 1 & Zero 1), architecture: [ armv6, linux/arm/v6 ], platform: rpi, qt_version: '5.15.2' }, # Qt6 not available on Debian Bullseye (armv6) - { distribution: debian, codename: bullseye, description: Debian Bullseye (Raspberry Pi 2), architecture: [ armv7, linux/arm/v7 ], platform: rpi, qt_version: '6.4.2' }, - { distribution: debian, codename: bullseye, description: Debian Bullseye (Raspberry Pi 3/4/5 & Zero 2), architecture: [ arm64, linux/arm64 ], platform: rpi, qt_version: '6.4.2' }, - { distribution: debian, codename: bookworm, description: Debian Bookworm (amd64), architecture: [ amd64, linux/amd64 ], platform: x11, qt_version: '6.4.2' }, - { distribution: debian, codename: bookworm, description: Debian Bookworm (Raspberry Pi 1 & Zero 1), architecture: [ armv6, linux/arm/v6 ], platform: rpi, qt_version: '6.4.2' }, - { distribution: debian, codename: bookworm, description: Debian Bookworm (Raspberry Pi 2), architecture: [ armv7, linux/arm/v7 ], platform: rpi, qt_version: '6.4.2' }, - { distribution: debian, codename: bookworm, description: Debian Bookworm (Raspberry Pi 3/4/5 & Zero 2), architecture: [ arm64, linux/arm64 ], platform: rpi, qt_version: '6.4.2' }, + { distribution: debian, codename: bullseye, description: Debian Bullseye (amd64), architecture: [ amd64, linux/amd64 ], platform: x11, qt_version: '6.8.2' }, + { distribution: debian, codename: bullseye, description: Debian Bullseye (Raspberry Pi 1 & Zero 1), architecture: [ armv6, linux/arm/v6 ], platform: rpi, qt_version: '5.15.2' }, # Qt5 for armv6 - Docker image bullseye-qt6 doesn't exist + { distribution: debian, codename: bullseye, description: Debian Bullseye (Raspberry Pi 2), architecture: [ armv7, linux/arm/v7 ], platform: rpi, qt_version: '6.8.2' }, + { distribution: debian, codename: bullseye, description: Debian Bullseye (Raspberry Pi 3/4/5 & Zero 2), architecture: [ arm64, linux/arm64 ], platform: rpi, qt_version: '6.8.2' }, + { distribution: debian, codename: bookworm, description: Debian Bookworm (amd64), architecture: [ amd64, linux/amd64 ], platform: x11, qt_version: '6.8.2' }, + { distribution: debian, codename: bookworm, description: Debian Bookworm (Raspberry Pi 1 & Zero 1), architecture: [ armv6, linux/arm/v6 ], platform: rpi, qt_version: '6.8.2' }, + { distribution: debian, codename: bookworm, description: Debian Bookworm (Raspberry Pi 2), architecture: [ armv7, linux/arm/v7 ], platform: rpi, qt_version: '6.8.2' }, + { distribution: debian, codename: bookworm, description: Debian Bookworm (Raspberry Pi 3/4/5 & Zero 2), architecture: [ arm64, linux/arm64 ], platform: rpi, qt_version: '6.8.2' }, { distribution: debian, codename: trixie, description: Debian Trixie (amd64), architecture: [ amd64, linux/amd64 ], platform: x11, qt_version: '6.8.2' }, { distribution: debian, codename: trixie, description: Debian Trixie (Raspberry Pi 1 & Zero 1), architecture: [ armv6, linux/arm/v6 ], platform: rpi, qt_version: '6.8.2' }, { distribution: debian, codename: trixie, description: Debian Trixie (Raspberry Pi 2), architecture: [ armv7, linux/arm/v7 ], platform: rpi, qt_version: '6.8.2' }, @@ -90,7 +90,7 @@ jobs: name: 🍏 macOS ${{ matrix.architecture }} runs-on: ${{ matrix.architecture == 'x64' && 'macos-15-intel' || 'macos-15' }} env: - QT_VERSION: '6.9.3' + QT_VERSION: '6.8.2' strategy: fail-fast: false matrix: @@ -110,13 +110,13 @@ jobs: fetch-depth: 0 # Ensures all tags are fetched path: hyperion - - name: 📥 Install Qt - uses: jurplel/install-qt-action@v4 + - name: 💾 Cache Qt6 build + uses: actions/cache@v4 with: - version: ${{ env.QT_VERSION }} - target: 'desktop' - cache: 'true' - cache-key-prefix: 'cache-qt-macos' + path: build/qt6 + key: qt6-${{ env.QT_VERSION }}-macos-${{ matrix.architecture }}-${{ inputs.build_type }} + restore-keys: | + qt6-${{ env.QT_VERSION }}-macos-${{ matrix.architecture }}- - name: 👷 Build shell: bash @@ -140,7 +140,7 @@ jobs: runs-on: ${{ matrix.architecture == 'arm64' && 'windows-11-arm' || 'windows-2025' }} env: BUILD_TYPE: ${{ inputs.build_type == 'debug' && 'relwithdebinfo' || inputs.build_type }} - QT_VERSION: '6.9.3' + QT_VERSION: '6.8.2' strategy: fail-fast: false matrix: @@ -167,15 +167,6 @@ jobs: python-version: '3.13.7' architecture: ${{ matrix.architecture }} - - name: 📥 Install Qt - uses: jurplel/install-qt-action@v4 - with: - version: ${{ env.QT_VERSION }} - target: 'desktop' - cache: 'true' - cache-key-prefix: 'cache-qt-windows' - setup-python: 'false' - - name: 📥 Install latest CMake and Ninja uses: lukka/get-cmake@latest @@ -188,6 +179,14 @@ jobs: if: matrix.architecture == 'x64' uses: ilammy/setup-nasm@v1 + - name: 💾 Cache Qt6 build + uses: actions/cache@v4 + with: + path: build/qt6 + key: qt6-${{ env.QT_VERSION }}-windows-${{ matrix.architecture }}-${{ env.BUILD_TYPE }} + restore-keys: | + qt6-${{ env.QT_VERSION }}-windows-${{ matrix.architecture }}- + - name: 👷 Build shell: cmd run: | diff --git a/.gitignore b/.gitignore index 8347166..ae04fd7 100644 --- a/.gitignore +++ b/.gitignore @@ -30,4 +30,5 @@ CMakeSettings.json !.vs/launch.vs.json # User defined CMake preset file. -CMakeUserPresets.json \ No newline at end of file +CMakeUserPresets.json +hyperion/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f3f910..37a7023 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -158,71 +158,117 @@ if(PLATFORM_MATCHES_RPI) endif() #============================================================================= -# QMdnsEngine +# Qt6 (Build statically from source) #============================================================================= -# Allow to overwrite QT base directory -# Either supply QTDIR as -DQTDIR= to cmake or set and environment variable QTDIR pointing to the Qt installation -# For Windows and macOS, the default Qt installation path are tried to resolved automatically -if(NOT DEFINED QTDIR) - if(DEFINED ENV{QTDIR}) - set(QTDIR $ENV{QTDIR}) - else() - if(MSVC) - FIRSTSUBDIR(SUBDIRQT "C:/Qt") - if(NOT ${SUBDIRQT} STREQUAL "") - set(QTDIR "${SUBDIRQT}/msvc2019_64") - endif() - elseif (APPLE) - foreach(QT_VERSION 6 5) - execute_process( - COMMAND brew --prefix qt@${QT_VERSION} - RESULT_VARIABLE DETECT_QT - OUTPUT_VARIABLE QT_LOCATION - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if(${DETECT_QT} EQUAL 0 AND EXISTS ${QT_LOCATION}) - set(QTDIR ${QT_LOCATION}) - break() - endif() - endforeach() - endif() - endif() -endif() +# Set Qt version to build +set(QT_VERSION_TO_BUILD "6.8.2" CACHE STRING "Qt version to build") + +# Qt6 CMake configure options for static build +# Building qtbase with required modules for Hyperion.NG: Core, Gui, Network, Sql, Widgets +set(QT_CMAKE_ARGS + -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}/qt6 + -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} + -DBUILD_SHARED_LIBS:BOOL=OFF + -DQT_BUILD_EXAMPLES:BOOL=OFF + -DQT_BUILD_TESTS:BOOL=OFF + -DFEATURE_sql:BOOL=ON + -DFEATURE_gui:BOOL=ON + -DFEATURE_widgets:BOOL=ON + -DFEATURE_testlib:BOOL=OFF + -DFEATURE_openssl:BOOL=OFF + -DFEATURE_icu:BOOL=OFF + -DFEATURE_system_zlib:BOOL=OFF + -DFEATURE_system_pcre2:BOOL=OFF + -DFEATURE_static:BOOL=ON + -DFEATURE_static_runtime:BOOL=OFF + ${APPLE_CONFIGURATION} +) -if(DEFINED QTDIR) - message(STATUS "Add QTDIR: ${QTDIR} to CMAKE_PREFIX_PATH") - list(PREPEND CMAKE_PREFIX_PATH - ${QTDIR} - ${QTDIR}/lib - ) -endif() +# Build Qt6 qtbase from source (static build with Core, Gui, Network, Sql, Widgets) +ExternalProject_Add(qt6-base + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/qt6-base + GIT_REPOSITORY https://code.qt.io/qt/qtbase.git + GIT_TAG v${QT_VERSION_TO_BUILD} + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + UPDATE_COMMAND "" + PATCH_COMMAND "" + CMAKE_ARGS ${QT_CMAKE_ARGS} + BUILD_COMMAND cmake --build --config ${CMAKE_BUILD_TYPE} --parallel + INSTALL_COMMAND cmake --install --config ${CMAKE_BUILD_TYPE} +) -# find Qt Network library for QMdnsEngine -find_package(QT NAMES Qt6 Qt5 COMPONENTS Network REQUIRED) -message(STATUS "Found Qt Version: ${QT_VERSION}") +# Build Qt6 SerialPort module (required by Hyperion.NG) +ExternalProject_Add(qt6-serialport + DEPENDS qt6-base + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/qt6-serialport + GIT_REPOSITORY https://code.qt.io/qt/qtserialport.git + GIT_TAG v${QT_VERSION_TO_BUILD} + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + UPDATE_COMMAND "" + CMAKE_ARGS -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}/qt6 + -DCMAKE_PREFIX_PATH:PATH=${CMAKE_INSTALL_PREFIX}/qt6 + -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} + -DBUILD_SHARED_LIBS:BOOL=OFF + ${APPLE_CONFIGURATION} + BUILD_COMMAND cmake --build --config ${CMAKE_BUILD_TYPE} --parallel + INSTALL_COMMAND cmake --install --config ${CMAKE_BUILD_TYPE} +) -if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) - set(QT_MIN_VERSION "6.2.2") -else() - set(QT_MIN_VERSION "5.9.0") -endif() +# Build Qt6 WebSockets module (required by Hyperion.NG) +ExternalProject_Add(qt6-websockets + DEPENDS qt6-base + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/qt6-websockets + GIT_REPOSITORY https://code.qt.io/qt/qtwebsockets.git + GIT_TAG v${QT_VERSION_TO_BUILD} + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + UPDATE_COMMAND "" + CMAKE_ARGS -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}/qt6 + -DCMAKE_PREFIX_PATH:PATH=${CMAKE_INSTALL_PREFIX}/qt6 + -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} + -DBUILD_SHARED_LIBS:BOOL=OFF + ${APPLE_CONFIGURATION} + BUILD_COMMAND cmake --build --config ${CMAKE_BUILD_TYPE} --parallel + INSTALL_COMMAND cmake --install --config ${CMAKE_BUILD_TYPE} +) -if("${QT_VERSION}" VERSION_LESS "${QT_MIN_VERSION}") - message(FATAL_ERROR "Your Qt version is to old! Minimum required ${QT_MIN_VERSION}") -endif() +# Convenience target to build all Qt6 modules +add_custom_target(qt6 DEPENDS qt6-base qt6-serialport qt6-websockets) -find_package(Qt${QT_VERSION_MAJOR} ${QT_VERSION} COMPONENTS Network REQUIRED) -message(STATUS "Qt version used: ${QT_VERSION}") +# Set Qt6_DIR to find the built Qt6 +set(Qt6_DIR "${CMAKE_INSTALL_PREFIX}/qt6/lib/cmake/Qt6" CACHE PATH "Qt6 CMake directory" FORCE) +list(PREPEND CMAKE_PREFIX_PATH ${CMAKE_INSTALL_PREFIX}/qt6) -cmake_path(SET QMdnsEngine ${HYPERION_DIR}/dependencies/external/qmdnsengine) -FetchContent_Declare(qmdns SOURCE_DIR ${QMdnsEngine}) +#============================================================================= +# QMdnsEngine (depends on Qt6) +#============================================================================= -# Suppress warnings about "Compatibility with CMake < 3.5 will be removed from a future version of CMake" -set(CMAKE_WARN_DEPRECATED OFF CACHE BOOL "" FORCE) +cmake_path(SET QMdnsEngine ${HYPERION_DIR}/dependencies/external/qmdnsengine) -FetchContent_MakeAvailable(qmdns) +# Convert QMdnsEngine to ExternalProject to properly handle Qt6 dependency +ExternalProject_Add(qmdnsengine + DEPENDS qt6 + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/qmdnsengine + SOURCE_DIR ${QMdnsEngine} + CMAKE_ARGS -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} + -DCMAKE_PREFIX_PATH:PATH=${CMAKE_INSTALL_PREFIX}/qt6 + -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} + -DBUILD_SHARED_LIBS:BOOL=OFF + ${APPLE_CONFIGURATION} + BUILD_COMMAND cmake --build --config ${CMAKE_BUILD_TYPE} + INSTALL_COMMAND cmake --install --config ${CMAKE_BUILD_TYPE} +) #============================================================================= # FlatBuffers diff --git a/README.md b/README.md index 863a692..655ea39 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,35 @@ This repository is responsible for creating Hyperion.NG dependencies for Linux, macOS and Windows. This allows us to speed up the creation process of our build artifacts. + +## Qt6 Static Build + +As of the latest update, this repository builds Qt6 (version 6.8.2) statically from source for all platforms. +This ensures: +- Consistent Qt version across all platforms +- Static linking for reduced runtime dependencies +- Portable binaries + +### Build Configuration + +- **Qt Version**: 6.8.2 +- **Build Type**: Static +- **Modules Built**: + - **qtbase**: Core, Gui, Network, Sql, Widgets + - **qtserialport**: SerialPort + - **qtwebsockets**: WebSockets +- **Disabled Features**: DBus (optional), OpenSSL, ICU + +### Build Time + +Building Qt6 from source is time-intensive: +- **First build**: 45-180 minutes depending on hardware (increased due to additional modules) +- **Cached builds**: Much faster due to GitHub Actions caching + +### Platform Support + +Qt6 6.8.2 static builds are created for: +- **Linux**: All Debian distributions (Bullseye, Bookworm, Trixie) and architectures (amd64, armv6, armv7, arm64) + - Note: Debian Bullseye armv6 uses Qt 5.15.2 due to Docker image availability +- **macOS**: arm64 and x64 architectures +- **Windows**: arm64 and x64 architectures