feat: WASM modules based simulation in Companion (#6435)

This commit is contained in:
Raphael Coeffic
2026-03-20 12:19:17 +10:00
committed by GitHub
parent 5f8a38bb18
commit 04a2231aee
80 changed files with 3126 additions and 2220 deletions
@@ -0,0 +1,64 @@
name: 'Build Companion'
inputs:
os:
description: 'OS / Architecture'
required: true
qt-version:
description: 'Qt version'
default: '6.9.3'
qt-arch:
description: 'Qt architecture'
required: runner.os != 'Linux'
sdl2-version:
description: 'SDL2 version'
default: '2.32.8'
runs:
using: "composite"
steps:
- name: Install Qt
if: runner.os != 'Linux'
uses: jdpurcell/install-qt-action@v5
env:
AQT_CONFIG: ${{ github.workspace }}/tools/aqt-settings.ini
with:
version: ${{ inputs.qt-version }}
modules: 'qtmultimedia qtserialport'
arch: ${{ inputs.qt-arch }}
cache: true
cache-key-prefix: 'install-qt-action-${{ inputs.qt-arch }}'
- name: Setup SDL2
if: runner.os != 'Linux'
shell: bash
env:
ACTION_PATH: ${{ github.action_path }}
SDL2_VERSION: ${{ inputs.sdl2-version }}
run: |
"${ACTION_PATH}/setup-sdl2.sh" ${SDL2_VERSION}
- name: Setup MSVC
if: runner.os == 'Windows'
shell: pwsh
run: ${{ github.action_path }}/setup-msvc.ps1
- name: Build
shell: bash
env:
CMAKE_BUILD_TYPE: 'Release'
run: |
mkdir output && \
CMAKE_PREFIX_PATH="$QT_ROOT_DIR;$SDL2_ROOT" \
tools/build-companion.sh "$(pwd)" "$(pwd)/output/"
- name: Compose release filename
run: echo "artifact_name=edgetx-cpn-${{ inputs.os }}-${GITHUB_REF##*/}" >> $GITHUB_ENV
shell: bash
- name: Archive production artifacts
uses: actions/upload-artifact@v7
with:
name: "${{ env.artifact_name }}"
path: ${{github.workspace}}/output
retention-days: 15
@@ -0,0 +1,39 @@
# setup-msvc.ps1
# Runs vcvarsall.bat and exports only the new/changed environment
# variables to GitHub Actions, avoiding clobbering existing ones.
param(
[string]$Arch = "x64"
)
# Find VS installation
$vsWhere = "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"
$vsPath = & $vsWhere -latest -property installationPath
$vcvars = Join-Path $vsPath "VC\Auxiliary\Build\vcvarsall.bat"
if (-not (Test-Path $vcvars)) {
Write-Error "vcvarsall.bat not found at: $vcvars"
exit 1
}
# Snapshot environment before
$before = @{}
Get-ChildItem env: | ForEach-Object { $before[$_.Name] = $_.Value }
# Run vcvarsall.bat and import its environment into this process
cmd /c "`"$vcvars`" $Arch && set" | ForEach-Object {
if ($_ -match '^([^=]+)=(.*)$') {
[System.Environment]::SetEnvironmentVariable($Matches[1], $Matches[2])
}
}
# Export only changed/new variables to GitHub Actions
$count = 0
Get-ChildItem env: | ForEach-Object {
if ($before[$_.Name] -ne $_.Value) {
"$($_.Name)=$($_.Value)" | Out-File -Append -Encoding utf8 $env:GITHUB_ENV
$count++
}
}
Write-Host "Exported $count environment variables to GITHUB_ENV"
+46
View File
@@ -0,0 +1,46 @@
#!/usr/bin/env bash
# setup-sdl2.sh
# Downloads/installs SDL2 for Windows and macOS.
# Linux is handled separately via a Docker container.
set -euo pipefail
VERSION="${1:?Usage: setup-sdl2.sh <version>}"
case "$RUNNER_OS" in
Windows)
ARCHIVE="SDL2-devel-${VERSION}-VC.zip"
URL="https://github.com/libsdl-org/SDL/releases/download/release-${VERSION}/${ARCHIVE}"
DEST="${RUNNER_TEMP}/SDL2"
echo "Downloading SDL2 ${VERSION} (Windows/MSVC)..."
curl -fsSL -o "${RUNNER_TEMP}/${ARCHIVE}" "${URL}"
unzip -q "${RUNNER_TEMP}/${ARCHIVE}" -d "${DEST}"
SDL2_ROOT="${DEST}/SDL2-${VERSION}"
echo "SDL2_ROOT=${SDL2_ROOT}" >> "${GITHUB_ENV}"
;;
macOS)
ARCHIVE="SDL2-${VERSION}.dmg"
URL="https://github.com/libsdl-org/SDL/releases/download/release-${VERSION}/${ARCHIVE}"
echo "Downloading SDL2 ${VERSION} (macOS framework)..."
curl -fsSL -o "${RUNNER_TEMP}/${ARCHIVE}" "${URL}"
hdiutil attach "${RUNNER_TEMP}/${ARCHIVE}" -quiet -mountpoint "${RUNNER_TEMP}/sdl2-mnt"
sudo cp -R "${RUNNER_TEMP}/sdl2-mnt/SDL2.framework" /Library/Frameworks/
hdiutil detach "${RUNNER_TEMP}/sdl2-mnt" -quiet
;;
Linux)
echo "Skipping — SDL2 is provided by the Docker container"
;;
*)
echo "::error::Unsupported RUNNER_OS: ${RUNNER_OS}"
exit 1
;;
esac
echo "SDL2 ${VERSION} setup complete for ${RUNNER_OS}"
@@ -0,0 +1,17 @@
name: 'Setup WASI SDK'
inputs:
python-version:
description: 'Python version'
default: '3.13'
runs:
using: "composite"
steps:
- uses: actions/setup-python@v6
with:
python-version: ${{ inputs.python-version }}
cache: 'pip' # caching pip dependencies
- run: python3 -m pip install -r requirements.txt
shell: bash
+20
View File
@@ -0,0 +1,20 @@
name: 'Setup WASI SDK'
inputs:
arch:
description: 'OS / Architecture (ex: arm64-macos)'
default: 'arm64-macos'
version:
description: 'SDK version'
default: '25'
runs:
using: "composite"
steps:
- name: Install WASI SDK
if: steps.cache-wasi-sdk.outputs.cache-hit != 'true'
shell: bash
run: |
mkdir /tmp/wasi-sdk
curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${{ inputs.version }}/wasi-sdk-${{ inputs.version }}.0-${{ inputs.arch }}.tar.gz | tar xz --strip-components 1 -C /tmp/wasi-sdk
sudo mv /tmp/wasi-sdk /opt/wasi-sdk
+16 -34
View File
@@ -15,9 +15,6 @@ on:
- '.gitmodules'
- 'CMakeLists.txt'
pull_request:
branches:
- 'main'
- '[0-9]+.[0-9]+'
paths: *trigger-paths
jobs:
@@ -30,7 +27,7 @@ jobs:
strategy:
matrix:
target:
- x9dp2019
- x9dp2019;x9e
- tx15
- tx16s
- tx16smk3
@@ -38,20 +35,14 @@ jobs:
- el18
- pl18
- pl18ev
- t12max
- t12max;t14
- t15
- t16
- t18
- tlite #STM32F2
- t20
- t14
- t20v2
- tx12 #STM32F2
- t20;t20v2
- x10
- x12s
- x9e
- mt12
- gx12
- mt12;gx12
- nb4p
- st16
- t15pro
@@ -65,7 +56,6 @@ jobs:
uses: actions/checkout@v6
with:
submodules: recursive
# fetch-depth: 0 # https://github.com/actions/checkout#Fetch-all-history-for-all-tags-and-branches
- name: Test ${{ matrix.target }}
env:
@@ -86,28 +76,21 @@ jobs:
matrix:
target:
- nv14;el18
- pl18;pl18ev;pl18u
- pa01
- t12max
- t15;t16;t18
- zorro;pocket;mt12;commando8
- pl18;pl18ev
- pl18u;pa01
- t15;t16
- t14;t18;mt12
- zorro;pocket;commando8
- tprov2;tpros;bumblebee
- t20;t20v2;t14
- tx12mk2;boxer;gx12
- tx15
- tx16s
- tx16smk3
- f16
- mt12;gx12;t20;t20v2
- t12max;tx12mk2;boxer
- tx15;tx16s
- x12s;f16
- v12;v14;v16
- x10;x10express
- x12s
- x7access
- x9dp2019
- x9e;x9e-hall
- mt12;gx12
- nb4p
- st16
- t15pro
- x7access;x9dp2019;x9e;x9e-hall
- nb4p;st16
- tx16smk3;t14;t15pro
container:
image: ghcr.io/edgetx/edgetx-dev:latest
volumes:
@@ -144,7 +127,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Compose release filename
# https://stackoverflow.com/questions/58033366/how-to-get-current-branch-within-github-actions
run: echo "artifact_name=edgetx-firmware-${GITHUB_REF##*/}" >> $GITHUB_ENV
- name: Merge firmware artifact packages
+164
View File
@@ -0,0 +1,164 @@
name: Companion
on:
push:
branches:
- 'main'
tags:
- v*
paths:
- '.github/workflows/companion.yml'
- 'companion/**'
- 'tools/build-companion.sh'
pull_request:
paths:
- '.github/workflows/companion.yml'
- 'companion/**'
- 'tools/build-companion.sh'
workflow_dispatch:
jobs:
modules:
name: WASM Modules (${{ matrix.group.id }})
runs-on: macos-15
strategy:
matrix:
group:
- id: color-1
target: [nv14, el18, pl18, pl18ev]
- id: color-2
target: [pl18u, t15, t16, t18]
- id: bw-1
target: [zorro, pocket, mt12, commando8, tprov2, tpros, bumblebee, t14]
- id: bw-2
target: [mt12, gx12, t20, t20v2, t12max, tx12mk2, boxer]
- id: color-3
target: [tx15, tx16s, x12s, f16]
- id: mixed-1
target: [v12, v14, v16, x10, x10express]
- id: bw-3
target: [x7access, x9dp2019, x9e, x9e-hall]
- id: color-4
target: [nb4p, st16, pa01]
- id: color-5
target: [t15pro, tx16smk3]
steps:
- name: Check out the repo
uses: actions/checkout@v5
with:
submodules: true
- name: Setup Python Dependencies
uses: ./.github/actions/python_dependencies
- name: Setup WASI SDK
uses: ./.github/actions/wasi_sdk
- name: Build modules
shell: bash
env:
FLAVOR: ${{ join(matrix.group.target, ';') }}
CMAKE_BUILD_TYPE: 'Release'
run: |
mkdir output && \
tools/build-wasm-modules.sh "$(pwd)" "$(pwd)/output/"
- name: Archive production artifacts
uses: actions/upload-artifact@v7
with:
name: wasm-modules-${{ matrix.group.id }}
path: ${{github.workspace}}/output
if-no-files-found: error
retention-days: 15
build-linux:
name: Linux Companion
runs-on: ubuntu-latest
needs: modules
container:
image: ghcr.io/edgetx/edgetx-dev:latest
volumes:
- ${{ github.workspace }}:/src
steps:
- name: Check out the repo
uses: actions/checkout@v5
with:
submodules: recursive
- name: Download WASM modules
uses: actions/download-artifact@v7
with:
pattern: wasm-modules-*
path: wasm-modules
merge-multiple: true
- name: Setup and Build
uses: ./.github/actions/build_companion
with:
os: 'linux'
build-macos:
name: macOS Companion
runs-on: macos-15
needs: modules
env:
CMAKE_OSX_ARCHITECTURES: 'x86_64;arm64'
CMAKE_OSX_DEPLOYMENT_TARGET: '11.0'
steps:
- name: Check out the repo
uses: actions/checkout@v5
with:
submodules: recursive
- name: Download WASM modules
uses: actions/download-artifact@v7
with:
pattern: wasm-modules-*
path: wasm-modules
merge-multiple: true
- name: Setup and Build
uses: ./.github/actions/build_companion
with:
os: 'macos'
qt-arch: 'clang_64'
build-win64:
name: Windows Companion
runs-on: windows-2022
needs: modules
env:
CMAKE_GENERATOR: 'Ninja'
CXX: 'clang++'
CC: 'clang'
defaults:
run:
shell: bash
steps:
- name: Check out the repo
uses: actions/checkout@v5
with:
submodules: recursive
- name: Download WASM modules
uses: actions/download-artifact@v7
with:
pattern: wasm-modules-*
path: wasm-modules
merge-multiple: true
- name: Setup and Build
uses: ./.github/actions/build_companion
with:
os: 'win64'
qt-arch: 'win64_msvc2022_64'
-86
View File
@@ -1,86 +0,0 @@
name: Linux Companion
on:
push:
branches:
- 'main'
- '[0-9]+.[0-9]+'
tags:
- v*
paths: &trigger-paths
- '.github/workflows/linux_cpn.yml'
- 'companion/**'
- 'tools/build-companion.sh'
pull_request:
branches:
- 'main'
- '[0-9]+.[0-9]+'
paths: *trigger-paths
workflow_dispatch:
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
jobs:
build:
runs-on: ubuntu-latest
if: |
github.event_name != 'pull_request' ||
!contains(github.event.pull_request.labels.*.name, 'ci: skip-cpn-linux')
container:
image: ghcr.io/edgetx/edgetx-dev:latest
volumes:
- ${{ github.workspace }}:/src
steps:
- name: Check out the repo
uses: actions/checkout@v6
with:
submodules: recursive
- name: Build
working-directory: ${{github.workspace}}
shell: bash
env:
CMAKE_BUILD_PARALLEL_LEVEL: 4
run: |
mkdir output && mkdir logs && \
tools/build-companion.sh "$(pwd)" "$(pwd)/output/" 2>&1 | tee logs/build-main.log
- name: Collect build logs
if: always()
shell: bash
run: |
# Create logs directory if it doesn't exist
mkdir -p logs
# Copy all build logs from the build directory
if [ -d "build" ]; then
find build -name "*.log" -type f -exec cp {} logs/ \; 2>/dev/null || true
find build -name "CMakeOutput.log" -type f -exec cp {} logs/ \; 2>/dev/null || true
find build -name "CMakeError.log" -type f -exec cp {} logs/ \; 2>/dev/null || true
fi
- name: Compose release filename
if: always()
# https://stackoverflow.com/questions/58033366/how-to-get-current-branch-within-github-actions
run: echo "artifact_name=edgetx-cpn-linux-${GITHUB_REF##*/}" >> $GITHUB_ENV
- name: Archive production artifacts
if: success()
uses: actions/upload-artifact@v7
with:
name: "${{ env.artifact_name }}"
path: ${{github.workspace}}/output
retention-days: 15
- name: Archive build logs
if: always()
uses: actions/upload-artifact@v7
with:
name: "${{ env.artifact_name }}-logs"
path: ${{github.workspace}}/logs
retention-days: 30
-114
View File
@@ -1,114 +0,0 @@
name: MacOSX Companion
on:
push:
branches:
- 'main'
- '[0-9]+.[0-9]+'
tags:
- v*
paths: &trigger-paths
- '.github/workflows/macosx_cpn.yml'
- 'companion/**'
- 'tools/build-companion.sh'
pull_request:
branches:
- 'main'
- '[0-9]+.[0-9]+'
paths: *trigger-paths
workflow_dispatch:
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
QT_VERSION: "6.9.3"
jobs:
build:
runs-on: macos-15-intel
if: |
github.event_name != 'pull_request' ||
!contains(github.event.pull_request.labels.*.name, 'ci: skip-cpn-macos')
steps:
- name: Select XCode version
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '16.0'
- name: Check out the repo
uses: actions/checkout@v6
with:
submodules: recursive
- name: Setup Python 3.12
uses: actions/setup-python@v6
with:
python-version: '3.12'
- name: Create Build Environment
# Some projects don't allow in-source building, so create a separate build directory
# We'll use this as our working directory for all subsequent commands
run: cmake -E make_directory ${{github.workspace}}/build
- name: Install Qt
uses: jdpurcell/install-qt-action@v5
env:
AQT_CONFIG: ${{ github.workspace }}/tools/aqt-settings.ini
with:
version: ${{ env.QT_VERSION }}
modules: 'qtmultimedia qtserialport'
setup-python: 'false'
cache: true
cache-key-prefix: 'install-qt-action-macOS'
- name: Install dependencies
run: python3 -m pip install --upgrade pip Pillow lz4 clang jinja2 pydantic
- name: Install SDL2
run: brew install SDL2
- name: Build
working-directory: ${{github.workspace}}
shell: bash
env:
CMAKE_BUILD_PARALLEL_LEVEL: 3
run: |
mkdir output && mkdir logs && \
tools/build-companion.sh "$(pwd)" "$(pwd)/output/" 2>&1 | tee logs/build-main.log
- name: Collect build logs
if: always()
shell: bash
run: |
# Create logs directory if it doesn't exist
mkdir -p logs
# Copy all build logs from the build directory
if [ -d "build" ]; then
find build -name "*.log" -type f -exec cp {} logs/ \; 2>/dev/null || true
find build -name "CMakeOutput.log" -type f -exec cp {} logs/ \; 2>/dev/null || true
find build -name "CMakeError.log" -type f -exec cp {} logs/ \; 2>/dev/null || true
fi
- name: Compose release filename
if: always()
# https://stackoverflow.com/questions/58033366/how-to-get-current-branch-within-github-actions
run: echo "artifact_name=edgetx-cpn-osx-${GITHUB_REF##*/}" >> $GITHUB_ENV
- name: Archive production artifacts
if: success()
uses: actions/upload-artifact@v7
with:
name: "${{ env.artifact_name }}"
path: ${{github.workspace}}/output
retention-days: 15
- name: Archive build logs
if: always()
uses: actions/upload-artifact@v7
with:
name: "${{ env.artifact_name }}-logs"
path: ${{github.workspace}}/logs
retention-days: 30
-116
View File
@@ -1,116 +0,0 @@
name: Windows Companion 64-bit
on:
push:
branches:
- 'main'
- '[0-9]+.[0-9]+'
tags:
- v*
paths: &trigger-paths
- '.github/workflows/win_cpn-64.yml'
- 'companion/**'
- 'tools/build-companion.sh'
pull_request:
branches:
- 'main'
- '[0-9]+.[0-9]+'
paths: *trigger-paths
workflow_dispatch:
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
CMAKE_BUILD_TYPE: "Release"
CMAKE_GENERATOR: "Ninja"
QT_VERSION: "6.9.0"
QT_ARCH: "win64_msvc2022_64"
SDL_VERSION: "2.32.8"
CXX: "clang++"
CC: "clang"
jobs:
build:
runs-on: windows-2022
if: |
github.event_name != 'pull_request' ||
!contains(github.event.pull_request.labels.*.name, 'ci: skip-cpn-win')
defaults:
run:
shell: bash
steps:
- name: Check out the repo
uses: actions/checkout@v6
with:
submodules: recursive
- name: Install Qt
uses: jdpurcell/install-qt-action@v5
env:
AQT_CONFIG: ${{ github.workspace }}/tools/aqt-settings.ini
with:
cache: true
cache-key-prefix: 'install-qt-action-${{ env.QT_ARCH }}'
version: ${{ env.QT_VERSION }}
arch: ${{ env.QT_ARCH }}
modules: 'qtmultimedia qtserialport'
- name: Setup SDL2
id: setup-sdl2
uses: libsdl-org/setup-sdl@v1
with:
version: ${{ env.SDL_VERSION }}
build-type: "Release"
- name: Install Python Dependencies
run: |
echo $PATH
$Python3_ROOT_DIR/python3.exe -m pip install clang jinja2 lz4 pillow pydantic
- name: Setup MSVC
uses: ilammy/msvc-dev-cmd@v1
- name: Build
env:
CMAKE_BUILD_PARALLEL_LEVEL: 4
run: |
mkdir output && mkdir logs && \
CMAKE_PREFIX_PATH="$QT_ROOT_DIR;$SDL2_ROOT" \
tools/build-companion.sh "$(pwd)" "$(pwd)/output/" 2>&1 | tee logs/build-main.log
- name: Collect build logs
if: always()
shell: bash
run: |
# Create logs directory if it doesn't exist
mkdir -p logs
# Copy all build logs from the build directory
if [ -d "build" ]; then
find build -name "*.log" -type f -exec cp {} logs/ \; 2>/dev/null || true
find build -name "CMakeOutput.log" -type f -exec cp {} logs/ \; 2>/dev/null || true
find build -name "CMakeError.log" -type f -exec cp {} logs/ \; 2>/dev/null || true
fi
- name: Compose release filename
if: always()
# https://stackoverflow.com/questions/58033366/how-to-get-current-branch-within-github-actions
run: echo "artifact_name=edgetx-cpn-win64-${GITHUB_REF##*/}" >> $GITHUB_ENV
- name: Archive production artifacts
if: success()
uses: actions/upload-artifact@v7
with:
name: "${{ env.artifact_name }}"
path: ${{github.workspace}}/output
retention-days: 15
- name: Archive build logs
if: always()
uses: actions/upload-artifact@v7
with:
name: "${{ env.artifact_name }}-logs"
path: ${{github.workspace}}/logs
retention-days: 30