Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 144 additions & 0 deletions .github/actions/build-config/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
name: Build Config
description: Read build toolchain versions from .github/build-config.json

outputs:
qt_version:
description: Qt version
value: ${{ steps.read.outputs.qt_version }}
qt_minimum_version:
description: Qt minimum supported version
value: ${{ steps.read.outputs.qt_minimum_version }}
qt_modules:
description: Qt modules (desktop)
value: ${{ steps.read.outputs.qt_modules }}
qt_modules_ios:
description: Qt modules (iOS, excludes qtserialport/qtscxml)
value: ${{ steps.read.outputs.qt_modules_ios }}
gstreamer_version:
description: GStreamer version (macOS/Linux)
value: ${{ steps.read.outputs.gstreamer_version }}
gstreamer_android_version:
description: GStreamer version (Android)
value: ${{ steps.read.outputs.gstreamer_android_version }}
gstreamer_windows_version:
description: GStreamer version (Windows)
value: ${{ steps.read.outputs.gstreamer_windows_version }}
ndk_version:
description: Android NDK version (short form)
value: ${{ steps.read.outputs.ndk_version }}
ndk_full_version:
description: Android NDK version (full form for sdkmanager)
value: ${{ steps.read.outputs.ndk_full_version }}
java_version:
description: Java version
value: ${{ steps.read.outputs.java_version }}
android_platform:
description: Android platform/API level
value: ${{ steps.read.outputs.android_platform }}
android_min_sdk:
description: Android minimum SDK version
value: ${{ steps.read.outputs.android_min_sdk }}
android_build_tools:
description: Android build tools version
value: ${{ steps.read.outputs.android_build_tools }}
android_cmdline_tools:
description: Android command line tools version
value: ${{ steps.read.outputs.android_cmdline_tools }}
xcode_version:
description: Xcode version (macOS)
value: ${{ steps.read.outputs.xcode_version }}
xcode_ios_version:
description: Xcode version (iOS)
value: ${{ steps.read.outputs.xcode_ios_version }}
cmake_minimum_version:
description: CMake minimum version
value: ${{ steps.read.outputs.cmake_minimum_version }}
ccache_version:
description: ccache version
value: ${{ steps.read.outputs.ccache_version }}
ccache_max_size:
description: ccache max cache size
value: ${{ steps.read.outputs.ccache_max_size }}
clang_format_version:
description: clang-format version
value: ${{ steps.read.outputs.clang_format_version }}
node_version:
description: Node.js version
value: ${{ steps.read.outputs.node_version }}
flatpak_gnome_version:
description: GNOME version for Flatpak
value: ${{ steps.read.outputs.flatpak_gnome_version }}

runs:
using: composite
steps:
- name: Validate and read build config
id: read
shell: bash
run: |
CONFIG_FILE="${GITHUB_WORKSPACE}/.github/build-config.json"
if [[ ! -f "$CONFIG_FILE" ]]; then
echo "::error::Build config not found: $CONFIG_FILE"
exit 1
fi
if ! jq empty "$CONFIG_FILE" 2>/dev/null; then
echo "::error::Invalid JSON in $CONFIG_FILE"
exit 1
fi

# Read all values (no fallbacks - config is authoritative)
QT_VERSION=$(jq -r '.qt_version' "$CONFIG_FILE")
QT_MIN_VERSION=$(jq -r '.qt_minimum_version' "$CONFIG_FILE")
QT_MODULES=$(jq -r '.qt_modules' "$CONFIG_FILE")
QT_MODULES_IOS=$(echo "$QT_MODULES" | sed 's/qtserialport//g; s/qtscxml//g; s/ */ /g; s/^ *//; s/ *$//')
GST_VERSION=$(jq -r '.gstreamer_version' "$CONFIG_FILE")
GST_ANDROID_VERSION=$(jq -r '.gstreamer_android_version' "$CONFIG_FILE")
GST_WIN_VERSION=$(jq -r '.gstreamer_windows_version' "$CONFIG_FILE")
NDK_VERSION=$(jq -r '.ndk_version' "$CONFIG_FILE")
NDK_FULL_VERSION=$(jq -r '.ndk_full_version' "$CONFIG_FILE")
JAVA_VERSION=$(jq -r '.java_version' "$CONFIG_FILE")
ANDROID_PLATFORM=$(jq -r '.android_platform' "$CONFIG_FILE")
ANDROID_MIN_SDK=$(jq -r '.android_min_sdk' "$CONFIG_FILE")
ANDROID_BUILD_TOOLS=$(jq -r '.android_build_tools' "$CONFIG_FILE")
ANDROID_CMDLINE_TOOLS=$(jq -r '.android_cmdline_tools' "$CONFIG_FILE")
XCODE_VERSION=$(jq -r '.xcode_version' "$CONFIG_FILE")
XCODE_IOS_VERSION=$(jq -r '.xcode_ios_version' "$CONFIG_FILE")
CMAKE_MIN_VERSION=$(jq -r '.cmake_minimum_version' "$CONFIG_FILE")
CCACHE_VERSION=$(jq -r '.ccache_version' "$CONFIG_FILE")
CCACHE_MAX_SIZE=$(jq -r '.ccache_max_size' "$CONFIG_FILE")
CLANG_FORMAT_VERSION=$(jq -r '.clang_format_version' "$CONFIG_FILE")
NODE_VERSION=$(jq -r '.node_version' "$CONFIG_FILE")
FLATPAK_GNOME_VERSION=$(jq -r '.flatpak_gnome_version' "$CONFIG_FILE")

{
echo "qt_version=$QT_VERSION"
echo "qt_minimum_version=$QT_MIN_VERSION"
echo "qt_modules=$QT_MODULES"
echo "qt_modules_ios=$QT_MODULES_IOS"
echo "gstreamer_version=$GST_VERSION"
echo "gstreamer_android_version=$GST_ANDROID_VERSION"
echo "gstreamer_windows_version=$GST_WIN_VERSION"
echo "ndk_version=$NDK_VERSION"
echo "ndk_full_version=$NDK_FULL_VERSION"
echo "java_version=$JAVA_VERSION"
echo "android_platform=$ANDROID_PLATFORM"
echo "android_min_sdk=$ANDROID_MIN_SDK"
echo "android_build_tools=$ANDROID_BUILD_TOOLS"
echo "android_cmdline_tools=$ANDROID_CMDLINE_TOOLS"
echo "xcode_version=$XCODE_VERSION"
echo "xcode_ios_version=$XCODE_IOS_VERSION"
echo "cmake_minimum_version=$CMAKE_MIN_VERSION"
echo "ccache_version=$CCACHE_VERSION"
echo "ccache_max_size=$CCACHE_MAX_SIZE"
echo "clang_format_version=$CLANG_FORMAT_VERSION"
echo "node_version=$NODE_VERSION"
echo "flatpak_gnome_version=$FLATPAK_GNOME_VERSION"
} >> "$GITHUB_OUTPUT"

# Only set commonly-used variables as environment variables to avoid polluting the env.
# All values are available as step outputs (e.g., steps.config.outputs.ndk_version).
- name: Set environment variables
shell: bash
run: |
echo "QT_VERSION=${{ steps.read.outputs.qt_version }}" >> "$GITHUB_ENV"
echo "GSTREAMER_VERSION=${{ steps.read.outputs.gstreamer_version }}" >> "$GITHUB_ENV"
Comment thread
HTRamsey marked this conversation as resolved.
29 changes: 29 additions & 0 deletions .github/build-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"qt_version": "6.10.1",
"qt_minimum_version": "6.10.0",
"qt_modules": "qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors qtscxml",

"gstreamer_version": "1.24.13",
"gstreamer_android_version": "1.22.12",
"gstreamer_windows_version": "1.22.12",

"ndk_version": "r27c",
"ndk_full_version": "27.2.12829759",
"java_version": "17",
"android_platform": "35",
"android_min_sdk": "28",
"android_build_tools": "35.0.0",
"android_cmdline_tools": "13114758",

"xcode_version": "16.x",
"xcode_ios_version": "latest-stable",

"cmake_minimum_version": "3.25",

"ccache_version": "4.11.3",
"ccache_max_size": "2G",
"clang_format_version": "17",
"node_version": "22",

"flatpak_gnome_version": "47"
}
2 changes: 2 additions & 0 deletions .github/workflows/docker-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ on:
pull_request:
paths:
- '.github/workflows/docker-linux.yml'
- '.github/build-config.json'
- 'deploy/docker/**'
- 'deploy/linux/**'
- 'tools/setup/**'
- 'src/**'
- 'CMakeLists.txt'
- 'cmake/**'
Expand Down
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ repos:
rev: v0.11.0.1
hooks:
- id: shellcheck
args: ['-e', 'SC1091'] # Don't warn about not following sourced files

# YAML validation
- repo: https://github.com/adrienverge/yamllint
Expand Down
37 changes: 37 additions & 0 deletions cmake/BuildConfig.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# ============================================================================
# BuildConfig.cmake - Read .github/build-config.json
# ============================================================================

set(QGC_BUILD_CONFIG_FILE "${CMAKE_SOURCE_DIR}/.github/build-config.json")

if(NOT EXISTS "${QGC_BUILD_CONFIG_FILE}")
message(FATAL_ERROR "BuildConfig: Config file not found: ${QGC_BUILD_CONFIG_FILE}")
endif()

# Read the JSON file
file(READ "${QGC_BUILD_CONFIG_FILE}" QGC_BUILD_CONFIG_CONTENT)

# Extract value from JSON (simple regex for flat JSON)
# NOTE: All values in build-config.json must be quoted strings for this parser
macro(qgc_config_get_value VAR_NAME JSON_KEY)
string(REGEX MATCH "\"${JSON_KEY}\"[ \t\n]*:[ \t\n]*\"([^\"]*)\"" _match "${QGC_BUILD_CONFIG_CONTENT}")

Copilot AI Dec 9, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern only matches string values in the JSON (\"([^\"]*)\") and will fail for numeric values without quotes. While the current build-config.json has all values as strings, this is fragile. Fields like java_version, android_platform, android_min_sdk, and node_version represent numbers and could legitimately be unquoted in JSON.

Consider either:

  1. Adding support for unquoted numeric values: \"${JSON_KEY}\"[ \t\n]*:[ \t\n]*\"?([^,\"}]*)\"?
  2. Documenting that all config values must be quoted strings
  3. Using CMake's file(READ ... CONFIGURE_DEPENDS) with a proper JSON parser if available in the minimum CMake version
Suggested change
string(REGEX MATCH "\"${JSON_KEY}\"[ \t\n]*:[ \t\n]*\"([^\"]*)\"" _match "${QGC_BUILD_CONFIG_CONTENT}")
string(REGEX MATCH "\"${JSON_KEY}\"[ \t\n]*:[ \t\n]*\"?([^\",}]*)\"?" _match "${QGC_BUILD_CONFIG_CONTENT}")

Copilot uses AI. Check for mistakes.
if(_match)
set(${VAR_NAME} "${CMAKE_MATCH_1}" CACHE STRING "${JSON_KEY}")
else()
message(FATAL_ERROR "BuildConfig: Key '${JSON_KEY}' not found in ${QGC_BUILD_CONFIG_FILE}")
endif()
endmacro()

qgc_config_get_value(QGC_CONFIG_QT_VERSION "qt_version")
qgc_config_get_value(QGC_CONFIG_QT_MINIMUM_VERSION "qt_minimum_version")
qgc_config_get_value(QGC_CONFIG_GSTREAMER_VERSION "gstreamer_version")
qgc_config_get_value(QGC_CONFIG_GSTREAMER_ANDROID_VERSION "gstreamer_android_version")
qgc_config_get_value(QGC_CONFIG_GSTREAMER_WIN_VERSION "gstreamer_windows_version")
qgc_config_get_value(QGC_CONFIG_NDK_VERSION "ndk_version")
qgc_config_get_value(QGC_CONFIG_NDK_FULL_VERSION "ndk_full_version")
qgc_config_get_value(QGC_CONFIG_JAVA_VERSION "java_version")
qgc_config_get_value(QGC_CONFIG_ANDROID_PLATFORM "android_platform")
qgc_config_get_value(QGC_CONFIG_ANDROID_MIN_SDK "android_min_sdk")
qgc_config_get_value(QGC_CONFIG_CMAKE_MINIMUM "cmake_minimum_version")

message(STATUS "BuildConfig: Qt ${QGC_CONFIG_QT_VERSION}, GStreamer ${QGC_CONFIG_GSTREAMER_VERSION}, NDK ${QGC_CONFIG_NDK_VERSION}")
7 changes: 5 additions & 2 deletions cmake/CustomOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

include(CMakeDependentOption)

# Load centralized build configuration from .github/build-config.json
include(BuildConfig)

# ============================================================================
# Application Metadata
# ============================================================================
Expand Down Expand Up @@ -138,8 +141,8 @@ set(QGC_WINDOWS_RESOURCE_FILE_PATH "${CMAKE_SOURCE_DIR}/deploy/windows/QGroundCo
# Qt Configuration
# ============================================================================

set(QGC_QT_MINIMUM_VERSION "6.10.0" CACHE STRING "Minimum supported Qt version")
set(QGC_QT_MAXIMUM_VERSION "6.10.1" CACHE STRING "Maximum supported Qt version")
set(QGC_QT_MINIMUM_VERSION "${QGC_CONFIG_QT_MINIMUM_VERSION}" CACHE STRING "Minimum supported Qt version")
set(QGC_QT_MAXIMUM_VERSION "${QGC_CONFIG_QT_VERSION}" CACHE STRING "Maximum supported Qt version")

set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qml" CACHE PATH "QML output directory")
set(QML_IMPORT_PATH "${QT_QML_OUTPUT_DIRECTORY}" CACHE STRING "Additional QML import paths")
Expand Down
8 changes: 6 additions & 2 deletions cmake/find-modules/FindGStreamer.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@
# Default Configuration
# ----------------------------------------------------------------------------

# Set default version based on platform
# Set default version based on platform (from build-config.json)
if(NOT DEFINED GStreamer_FIND_VERSION)
if(LINUX)
set(GStreamer_FIND_VERSION 1.20)
elseif(WIN32)
set(GStreamer_FIND_VERSION ${QGC_CONFIG_GSTREAMER_WIN_VERSION})
elseif(ANDROID)
set(GStreamer_FIND_VERSION ${QGC_CONFIG_GSTREAMER_ANDROID_VERSION})
else()
set(GStreamer_FIND_VERSION 1.22.12)
set(GStreamer_FIND_VERSION ${QGC_CONFIG_GSTREAMER_VERSION})
endif()
endif()

Expand Down
10 changes: 7 additions & 3 deletions cmake/platform/Android.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@ endif()
# ----------------------------------------------------------------------------
# Android NDK Version Validation
# ----------------------------------------------------------------------------
if(Qt6_VERSION VERSION_EQUAL "6.10.1")
if(NOT CMAKE_ANDROID_NDK_VERSION VERSION_EQUAL "27.2")
message(FATAL_ERROR "QGC: Invalid NDK Version: ${CMAKE_ANDROID_NDK_VERSION}. Qt 6.10.1 requires NDK 27.2")
# CMAKE_ANDROID_NDK_VERSION format varies: "27.2" or "27.2.12829759"
# Extract major.minor from ndk_full_version for reliable comparison
if(DEFINED QGC_CONFIG_NDK_FULL_VERSION AND Qt6_VERSION VERSION_GREATER_EQUAL "${QGC_CONFIG_QT_MINIMUM_VERSION}")
string(REGEX MATCH "^([0-9]+\\.[0-9]+)" _ndk_major_minor "${QGC_CONFIG_NDK_FULL_VERSION}")
if(_ndk_major_minor AND NOT CMAKE_ANDROID_NDK_VERSION VERSION_GREATER_EQUAL "${_ndk_major_minor}")
message(FATAL_ERROR "QGC: NDK ${CMAKE_ANDROID_NDK_VERSION} is too old. Qt ${Qt6_VERSION} requires NDK ${_ndk_major_minor}+ (${QGC_CONFIG_NDK_VERSION})")
endif()
unset(_ndk_major_minor)
endif()

# ----------------------------------------------------------------------------
Expand Down
Loading
Loading