Skip to content

Commit 897ac59

Browse files
committed
Add centralized build configuration
Create single source of truth for build toolchain versions in .github/build-config.json, eliminating hardcoded versions across CI workflows, setup scripts, CMake, and Docker files. New files: - .github/build-config.json - Centralized version configuration - .github/actions/build-config/action.yml - GitHub Action to read config - cmake/BuildConfig.cmake - CMake module to parse JSON config - tools/setup/read-config.sh - Bash helper (jq + Python fallback) - tools/setup/read-config.ps1 - PowerShell helper Updated to use centralized config: - CMake: CustomOptions, FindGStreamer, Android platform, gstqml6gl - Docker: Dockerfile-build-ubuntu, Dockerfile-build-android - Deploy: appimagecraft.yml, Vagrantfile, .vagrantconfig.yml - Scripts: install-dependencies-*, install-qt-* Key improvements: - No hardcoded fallback defaults in action.yml (config is authoritative) - Added ndk_full_version for simplified Docker builds - Simplified Dockerfile NDK version handling - Version-agnostic comments throughout
1 parent a808b15 commit 897ac59

File tree

20 files changed

+675
-93
lines changed

20 files changed

+675
-93
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
name: Build Config
2+
description: Read build toolchain versions from .github/build-config.json
3+
4+
outputs:
5+
qt_version:
6+
description: Qt version
7+
value: ${{ steps.read.outputs.qt_version }}
8+
qt_minimum_version:
9+
description: Qt minimum supported version
10+
value: ${{ steps.read.outputs.qt_minimum_version }}
11+
qt_modules:
12+
description: Qt modules (desktop)
13+
value: ${{ steps.read.outputs.qt_modules }}
14+
qt_modules_ios:
15+
description: Qt modules (iOS, excludes qtserialport/qtscxml)
16+
value: ${{ steps.read.outputs.qt_modules_ios }}
17+
gstreamer_version:
18+
description: GStreamer version (macOS/Linux)
19+
value: ${{ steps.read.outputs.gstreamer_version }}
20+
gstreamer_windows_version:
21+
description: GStreamer version (Windows)
22+
value: ${{ steps.read.outputs.gstreamer_windows_version }}
23+
ndk_version:
24+
description: Android NDK version (short form)
25+
value: ${{ steps.read.outputs.ndk_version }}
26+
ndk_full_version:
27+
description: Android NDK version (full form for sdkmanager)
28+
value: ${{ steps.read.outputs.ndk_full_version }}
29+
java_version:
30+
description: Java version
31+
value: ${{ steps.read.outputs.java_version }}
32+
android_platform:
33+
description: Android platform/API level
34+
value: ${{ steps.read.outputs.android_platform }}
35+
android_min_sdk:
36+
description: Android minimum SDK version
37+
value: ${{ steps.read.outputs.android_min_sdk }}
38+
android_build_tools:
39+
description: Android build tools version
40+
value: ${{ steps.read.outputs.android_build_tools }}
41+
android_cmdline_tools:
42+
description: Android command line tools version
43+
value: ${{ steps.read.outputs.android_cmdline_tools }}
44+
xcode_version:
45+
description: Xcode version (macOS)
46+
value: ${{ steps.read.outputs.xcode_version }}
47+
xcode_ios_version:
48+
description: Xcode version (iOS)
49+
value: ${{ steps.read.outputs.xcode_ios_version }}
50+
cmake_minimum_version:
51+
description: CMake minimum version
52+
value: ${{ steps.read.outputs.cmake_minimum_version }}
53+
ccache_version:
54+
description: ccache version
55+
value: ${{ steps.read.outputs.ccache_version }}
56+
ccache_max_size:
57+
description: ccache max cache size
58+
value: ${{ steps.read.outputs.ccache_max_size }}
59+
clang_format_version:
60+
description: clang-format version
61+
value: ${{ steps.read.outputs.clang_format_version }}
62+
node_version:
63+
description: Node.js version
64+
value: ${{ steps.read.outputs.node_version }}
65+
flatpak_gnome_version:
66+
description: GNOME version for Flatpak
67+
value: ${{ steps.read.outputs.flatpak_gnome_version }}
68+
69+
runs:
70+
using: composite
71+
steps:
72+
- name: Validate and read build config
73+
id: read
74+
shell: bash
75+
run: |
76+
CONFIG_FILE="${GITHUB_WORKSPACE}/.github/build-config.json"
77+
if [[ ! -f "$CONFIG_FILE" ]]; then
78+
echo "::error::Build config not found: $CONFIG_FILE"
79+
exit 1
80+
fi
81+
if ! jq empty "$CONFIG_FILE" 2>/dev/null; then
82+
echo "::error::Invalid JSON in $CONFIG_FILE"
83+
exit 1
84+
fi
85+
86+
# Read all values (no fallbacks - config is authoritative)
87+
QT_VERSION=$(jq -r '.qt_version' "$CONFIG_FILE")
88+
QT_MIN_VERSION=$(jq -r '.qt_minimum_version' "$CONFIG_FILE")
89+
QT_MODULES=$(jq -r '.qt_modules' "$CONFIG_FILE")
90+
QT_MODULES_IOS=$(echo "$QT_MODULES" | sed 's/qtserialport//g; s/qtscxml//g; s/ */ /g; s/^ *//; s/ *$//')
91+
GST_VERSION=$(jq -r '.gstreamer_version' "$CONFIG_FILE")
92+
GST_WIN_VERSION=$(jq -r '.gstreamer_windows_version' "$CONFIG_FILE")
93+
NDK_VERSION=$(jq -r '.ndk_version' "$CONFIG_FILE")
94+
NDK_FULL_VERSION=$(jq -r '.ndk_full_version' "$CONFIG_FILE")
95+
JAVA_VERSION=$(jq -r '.java_version' "$CONFIG_FILE")
96+
ANDROID_PLATFORM=$(jq -r '.android_platform' "$CONFIG_FILE")
97+
ANDROID_MIN_SDK=$(jq -r '.android_min_sdk' "$CONFIG_FILE")
98+
ANDROID_BUILD_TOOLS=$(jq -r '.android_build_tools' "$CONFIG_FILE")
99+
ANDROID_CMDLINE_TOOLS=$(jq -r '.android_cmdline_tools' "$CONFIG_FILE")
100+
XCODE_VERSION=$(jq -r '.xcode_version' "$CONFIG_FILE")
101+
XCODE_IOS_VERSION=$(jq -r '.xcode_ios_version' "$CONFIG_FILE")
102+
CMAKE_MIN_VERSION=$(jq -r '.cmake_minimum_version' "$CONFIG_FILE")
103+
CCACHE_VERSION=$(jq -r '.ccache_version' "$CONFIG_FILE")
104+
CCACHE_MAX_SIZE=$(jq -r '.ccache_max_size' "$CONFIG_FILE")
105+
CLANG_FORMAT_VERSION=$(jq -r '.clang_format_version' "$CONFIG_FILE")
106+
NODE_VERSION=$(jq -r '.node_version' "$CONFIG_FILE")
107+
FLATPAK_GNOME_VERSION=$(jq -r '.flatpak_gnome_version' "$CONFIG_FILE")
108+
109+
{
110+
echo "qt_version=$QT_VERSION"
111+
echo "qt_minimum_version=$QT_MIN_VERSION"
112+
echo "qt_modules=$QT_MODULES"
113+
echo "qt_modules_ios=$QT_MODULES_IOS"
114+
echo "gstreamer_version=$GST_VERSION"
115+
echo "gstreamer_windows_version=$GST_WIN_VERSION"
116+
echo "ndk_version=$NDK_VERSION"
117+
echo "ndk_full_version=$NDK_FULL_VERSION"
118+
echo "java_version=$JAVA_VERSION"
119+
echo "android_platform=$ANDROID_PLATFORM"
120+
echo "android_min_sdk=$ANDROID_MIN_SDK"
121+
echo "android_build_tools=$ANDROID_BUILD_TOOLS"
122+
echo "android_cmdline_tools=$ANDROID_CMDLINE_TOOLS"
123+
echo "xcode_version=$XCODE_VERSION"
124+
echo "xcode_ios_version=$XCODE_IOS_VERSION"
125+
echo "cmake_minimum_version=$CMAKE_MIN_VERSION"
126+
echo "ccache_version=$CCACHE_VERSION"
127+
echo "ccache_max_size=$CCACHE_MAX_SIZE"
128+
echo "clang_format_version=$CLANG_FORMAT_VERSION"
129+
echo "node_version=$NODE_VERSION"
130+
echo "flatpak_gnome_version=$FLATPAK_GNOME_VERSION"
131+
} >> "$GITHUB_OUTPUT"
132+
133+
# Only set commonly-used variables as environment variables to avoid polluting the env.
134+
# All values are available as step outputs (e.g., steps.config.outputs.ndk_version).
135+
- name: Set environment variables
136+
shell: bash
137+
run: |
138+
echo "QT_VERSION=${{ steps.read.outputs.qt_version }}" >> "$GITHUB_ENV"
139+
echo "GSTREAMER_VERSION=${{ steps.read.outputs.gstreamer_version }}" >> "$GITHUB_ENV"

.github/build-config.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"qt_version": "6.10.1",
3+
"qt_minimum_version": "6.10.0",
4+
"qt_modules": "qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors qtscxml",
5+
6+
"gstreamer_version": "1.24.13",
7+
"gstreamer_windows_version": "1.22.12",
8+
9+
"ndk_version": "r27c",
10+
"ndk_full_version": "27.2.12829759",
11+
"java_version": "17",
12+
"android_platform": "35",
13+
"android_min_sdk": "28",
14+
"android_build_tools": "35.0.0",
15+
"android_cmdline_tools": "13114758",
16+
17+
"xcode_version": "16.x",
18+
"xcode_ios_version": "latest-stable",
19+
20+
"cmake_minimum_version": "3.25",
21+
22+
"ccache_version": "4.11.3",
23+
"ccache_max_size": "2G",
24+
"clang_format_version": "17",
25+
"node_version": "22",
26+
27+
"flatpak_gnome_version": "47"
28+
}

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ repos:
4747
rev: v0.11.0.1
4848
hooks:
4949
- id: shellcheck
50+
args: ['-e', 'SC1091'] # Don't warn about not following sourced files
5051

5152
# YAML validation
5253
- repo: https://github.com/adrienverge/yamllint

cmake/BuildConfig.cmake

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# ============================================================================
2+
# BuildConfig.cmake - Read .github/build-config.json
3+
# ============================================================================
4+
5+
set(QGC_BUILD_CONFIG_FILE "${CMAKE_SOURCE_DIR}/.github/build-config.json")
6+
7+
if(NOT EXISTS "${QGC_BUILD_CONFIG_FILE}")
8+
message(FATAL_ERROR "BuildConfig: Config file not found: ${QGC_BUILD_CONFIG_FILE}")
9+
endif()
10+
11+
# Read the JSON file
12+
file(READ "${QGC_BUILD_CONFIG_FILE}" QGC_BUILD_CONFIG_CONTENT)
13+
14+
# Extract value from JSON (simple regex for flat JSON)
15+
# NOTE: All values in build-config.json must be quoted strings for this parser
16+
macro(qgc_config_get_value VAR_NAME JSON_KEY)
17+
string(REGEX MATCH "\"${JSON_KEY}\"[ \t\n]*:[ \t\n]*\"([^\"]*)\"" _match "${QGC_BUILD_CONFIG_CONTENT}")
18+
if(CMAKE_MATCH_1)
19+
set(${VAR_NAME} "${CMAKE_MATCH_1}" CACHE STRING "${JSON_KEY}")
20+
else()
21+
message(FATAL_ERROR "BuildConfig: Key '${JSON_KEY}' not found in ${QGC_BUILD_CONFIG_FILE}")
22+
endif()
23+
endmacro()
24+
25+
qgc_config_get_value(QGC_CONFIG_QT_VERSION "qt_version")
26+
qgc_config_get_value(QGC_CONFIG_QT_MINIMUM_VERSION "qt_minimum_version")
27+
qgc_config_get_value(QGC_CONFIG_GSTREAMER_VERSION "gstreamer_version")
28+
qgc_config_get_value(QGC_CONFIG_GSTREAMER_WIN_VERSION "gstreamer_windows_version")
29+
qgc_config_get_value(QGC_CONFIG_NDK_VERSION "ndk_version")
30+
qgc_config_get_value(QGC_CONFIG_NDK_FULL_VERSION "ndk_full_version")
31+
qgc_config_get_value(QGC_CONFIG_JAVA_VERSION "java_version")
32+
qgc_config_get_value(QGC_CONFIG_ANDROID_PLATFORM "android_platform")
33+
qgc_config_get_value(QGC_CONFIG_ANDROID_MIN_SDK "android_min_sdk")
34+
qgc_config_get_value(QGC_CONFIG_CMAKE_MINIMUM "cmake_minimum_version")
35+
36+
message(STATUS "BuildConfig: Qt ${QGC_CONFIG_QT_VERSION}, GStreamer ${QGC_CONFIG_GSTREAMER_VERSION}, NDK ${QGC_CONFIG_NDK_VERSION}")

cmake/CustomOptions.cmake

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
include(CMakeDependentOption)
77

8+
# Load centralized build configuration from .github/build-config.json
9+
include(BuildConfig)
10+
811
# ============================================================================
912
# Application Metadata
1013
# ============================================================================
@@ -138,8 +141,8 @@ set(QGC_WINDOWS_RESOURCE_FILE_PATH "${CMAKE_SOURCE_DIR}/deploy/windows/QGroundCo
138141
# Qt Configuration
139142
# ============================================================================
140143

141-
set(QGC_QT_MINIMUM_VERSION "6.10.0" CACHE STRING "Minimum supported Qt version")
142-
set(QGC_QT_MAXIMUM_VERSION "6.10.1" CACHE STRING "Maximum supported Qt version")
144+
set(QGC_QT_MINIMUM_VERSION "${QGC_CONFIG_QT_MINIMUM_VERSION}" CACHE STRING "Minimum supported Qt version")
145+
set(QGC_QT_MAXIMUM_VERSION "${QGC_CONFIG_QT_VERSION}" CACHE STRING "Maximum supported Qt version")
143146

144147
set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qml" CACHE PATH "QML output directory")
145148
set(QML_IMPORT_PATH "${QT_QML_OUTPUT_DIRECTORY}" CACHE STRING "Additional QML import paths")

cmake/find-modules/FindGStreamer.cmake

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@
1010
# Default Configuration
1111
# ----------------------------------------------------------------------------
1212

13-
# Set default version based on platform
13+
# Set default version based on platform (from build-config.json)
1414
if(NOT DEFINED GStreamer_FIND_VERSION)
1515
if(LINUX)
1616
set(GStreamer_FIND_VERSION 1.20)
17+
elseif(WIN32)
18+
set(GStreamer_FIND_VERSION ${QGC_CONFIG_GSTREAMER_WIN_VERSION})
1719
else()
18-
set(GStreamer_FIND_VERSION 1.22.12)
20+
set(GStreamer_FIND_VERSION ${QGC_CONFIG_GSTREAMER_VERSION})
1921
endif()
2022
endif()
2123

cmake/platform/Android.cmake

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,42 @@ endif()
99
# ----------------------------------------------------------------------------
1010
# Android NDK Version Validation
1111
# ----------------------------------------------------------------------------
12-
if(Qt6_VERSION VERSION_EQUAL "6.10.1")
13-
if(NOT CMAKE_ANDROID_NDK_VERSION VERSION_EQUAL "27.2")
14-
message(FATAL_ERROR "QGC: Invalid NDK Version: ${CMAKE_ANDROID_NDK_VERSION}. Qt 6.10.1 requires NDK 27.2")
12+
# Convert NDK version from build-config.json (rXXy format) to CMake version (XX.Y)
13+
# Maps suffix letter to minor version: a->0, b->1, c->2, etc.
14+
if(DEFINED QGC_CONFIG_NDK_VERSION)
15+
string(REGEX MATCH "r([0-9]+)([a-z]?)" _ndk_match "${QGC_CONFIG_NDK_VERSION}")
16+
if(CMAKE_MATCH_1)
17+
set(_ndk_major "${CMAKE_MATCH_1}")
18+
if(CMAKE_MATCH_2 STREQUAL "")
19+
set(_ndk_minor "0")
20+
else()
21+
string(ASCII 97 _letter_a) # ASCII 'a' = 97
22+
string(TOLOWER "${CMAKE_MATCH_2}" _ndk_suffix)
23+
string(FIND "abcdefghijklmnopqrstuvwxyz" "${_ndk_suffix}" _ndk_minor)
24+
if(_ndk_minor EQUAL -1)
25+
message(WARNING "QGC: Unrecognized NDK suffix '${CMAKE_MATCH_2}', defaulting to 0")
26+
set(_ndk_minor "0")
27+
endif()
28+
endif()
29+
set(_required_ndk_version "${_ndk_major}.${_ndk_minor}")
1530
endif()
1631
endif()
1732

33+
if(NOT DEFINED _required_ndk_version)
34+
message(WARNING "QGC: Could not parse NDK version from config, skipping validation")
35+
else()
36+
if(Qt6_VERSION VERSION_GREATER_EQUAL "${QGC_CONFIG_QT_MINIMUM_VERSION}")
37+
if(NOT CMAKE_ANDROID_NDK_VERSION VERSION_GREATER_EQUAL "${_required_ndk_version}")
38+
message(FATAL_ERROR "QGC: NDK ${CMAKE_ANDROID_NDK_VERSION} is too old. Qt ${Qt6_VERSION} requires NDK ${_required_ndk_version}+ (${QGC_CONFIG_NDK_VERSION})")
39+
endif()
40+
endif()
41+
endif()
42+
43+
unset(_required_ndk_version)
44+
unset(_ndk_major)
45+
unset(_ndk_minor)
46+
unset(_ndk_match)
47+
1848
# ----------------------------------------------------------------------------
1949
# Android Version Number Validation
2050
# ----------------------------------------------------------------------------

0 commit comments

Comments
 (0)