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
+44 -229
View File
@@ -1,7 +1,7 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
. "$SCRIPT_DIR/build-common.sh"
. "$SCRIPT_DIR/build-common.sh"
SRCDIR=$1
OUTDIR=$2
@@ -14,23 +14,24 @@ if [[ -z ${OUTDIR} ]]; then
OUTDIR="$(pwd)/output"
fi
if [[ ! -d "${OUTDIR}" ]]; then
mkdir -p "${OUTDIR}"
fi
# Determine parallel jobs
determine_max_jobs
# Create a master log file for the entire build process
MASTER_LOG="build-summary.log"
QUIET_FLAGS=""
if [[ "$CMAKE_GENERATOR" == "Ninja" ]]; then
QUIET_FLAGS="-- --quiet"
QUIET_FLAGS="-- --quiet"
else
# Assume Makefile generator for non-Ninja builds
COMMON_OPTIONS="${COMMON_OPTIONS} -DCMAKE_RULE_MESSAGES=OFF"
# Assume Makefile generator for non-Ninja builds
COMMON_OPTIONS="${COMMON_OPTIONS} -DCMAKE_RULE_MESSAGES=OFF"
fi
COMMON_OPTIONS="${COMMON_OPTIONS} -DCMAKE_BUILD_TYPE=Release -DCMAKE_MESSAGE_LOG_LEVEL=WARNING -Wno-dev -DGVARS=YES -DHELI=YES -DLUA=YES"
COMMON_OPTIONS="${COMMON_OPTIONS} -DCMAKE_BUILD_TYPE=Release -DCMAKE_MESSAGE_LOG_LEVEL=WARNING -Wno-dev"
if [ "$(uname)" = "Darwin" ]; then
COMMON_OPTIONS="${COMMON_OPTIONS} -DCMAKE_OSX_DEPLOYMENT_TARGET='10.15'"
COMMON_OPTIONS="${COMMON_OPTIONS} -DCMAKE_OSX_DEPLOYMENT_TARGET='11.0'"
fi
# Generate EDGETX_VERSION_SUFFIX if not already set
@@ -53,103 +54,6 @@ fi
rm -rf build && mkdir build && cd build
# Function to output error logs (works in both GitHub Actions and terminal)
output_error_log() {
local log_file="$1"
local context="$2"
if [[ -f "$log_file" ]]; then
echo "------------------------------------------"
echo " Full error output from $log_file ($context):"
echo "------------------------------------------"
cat "$log_file"
echo "------------------------------------------"
# Also append to master log for aggregation
{
echo "=== Error from $log_file ($context) ==="
cat "$log_file"
echo "=== End of $log_file ==="
} >> "$MASTER_LOG"
else
echo "⚠️ Warning: Log file $log_file not found for $context"
echo "⚠️ Warning: Log file $log_file not found for $context" >> "$MASTER_LOG"
fi
}
# Function to show last N lines of a log file for warnings
show_log_summary() {
local log_file="$1"
local lines="${2:-50}"
local context="$3"
if [[ -f "$log_file" ]]; then
echo "------------------------------------------"
echo "Last $lines lines from $log_file:"
echo "------------------------------------------"
tail -n "$lines" "$log_file"
fi
}
run_pipeline() {
local pipeline_type="$1"
local log_file="${2:-/dev/null}"
local context="$3"
local show_details="${4:-false}"
local cmake_opts="${QUIET_FLAGS}"
case "$pipeline_type" in
"plugin")
clean_build
if ! execute_with_output "⚙️ Configuring" "cmake ${BUILD_OPTIONS} ${SRCDIR}" "$log_file" "$show_details"; then
output_error_log "$log_file" "$context (Configuration)"
return 1
fi
if ! execute_with_output "🔧 Native config" "cmake_build_parallel . --target native-configure ${cmake_opts}" "$log_file" "$show_details"; then
output_error_log "$log_file" "$context (Native Configure)"
return 1
fi
if ! execute_with_output "📦 Building lib" "cmake_build_parallel native --target libsimulator ${cmake_opts}" "$log_file" "$show_details"; then
output_error_log "$log_file" "$context (Library Build)"
return 1
fi
;;
"final")
if ! execute_with_output "🔧 Final config" "cmake_build_parallel . --target native-configure ${cmake_opts}" "$log_file" "$show_details"; then
output_error_log "$log_file" "Final Configuration"
return 1
fi
if ! execute_with_output "📦 Building companion" "cmake_build_parallel native --target companion ${cmake_opts}" "$log_file" "$show_details"; then
output_error_log "$log_file" "$context (Companion Build)"
return 1
fi
if ! execute_with_output "📦 Packaging" "cmake_build_parallel native --target ${PACKAGE_TARGET}" "$log_file" "true"; then
output_error_log "$log_file" "Final Packaging"
return 1
fi
;;
esac
return 0
}
execute_with_output() {
local description="$1"
local command="$2"
local log_file="$3"
local show_output="${4:-false}"
if [[ "$show_output" == "true" && "$log_file" != "/dev/null" ]]; then
echo " $description..."
fi
eval "$command" >> "$log_file" 2>&1
}
clean_build() {
rm -f CMakeCache.txt native/CMakeCache.txt
}
get_platform_config() {
local platform=$(uname)
case "$platform" in
@@ -174,139 +78,50 @@ get_platform_config() {
esac
}
# Enhanced plugin builder with better error handling
build_plugin() {
local plugin="$1"
local log_file="build_${plugin}.log"
local verbose="${2:-false}"
BUILD_OPTIONS="${COMMON_OPTIONS} "
if ! get_target_build_options "$plugin" >> "$log_file" 2>&1; then
if [[ -n "$GITHUB_ACTIONS" ]]; then
echo "::error::Failed to get build options for $plugin"
fi
output_error_log "$log_file" "$plugin (Build Options)"
return 1
fi
# Only show detailed output in GitHub Actions or if verbose is requested
local show_details="false"
if [[ -n "$GITHUB_ACTIONS" || "$verbose" == "true" ]]; then
show_details="true"
fi
if ! run_pipeline "plugin" "$log_file" "$plugin" "$show_details"; then
return 1
fi
# Check for warnings and show summary if found
if grep -q -i "warning" "$log_file"; then
echo " ⚠️ $plugin completed with warnings"
if [[ "$show_details" == "true" ]]; then
show_log_summary "$log_file" 50 "$plugin (Warnings)"
fi
return 0
fi
echo " ✅ $plugin completed successfully"
return 0
}
declare -a simulator_plugins=(
x9lite x9lites x9d x9dp x9dp2019 x9e
x7 x7access
t8 t12 t12max tx12 tx12mk2 t15 t15pro t16 t18 t20 t20v2
xlite xlites
x10 x10express x12s
zorro tx16s tx16smk3 tx15
commando8 boxer pocket mt12 gx12
tlite tpro tprov2 tpros bumblebee lr3pro t14
nv14 el18 pl18 pl18ev pl18u st16 pa01
f16 v14 v16
)
get_platform_config
TOTAL=${#simulator_plugins[@]}
FAILED_PLUGINS=()
echo "🔨 Building $TOTAL Plugins for $PACKAGE_NAME"
for i in "${!simulator_plugins[@]}"; do
plugin="${simulator_plugins[$i]}"
current=$((i + 1))
percent=$((current * 100 / TOTAL))
# For terminal output, put each plugin on its own line for cleaner display
if [[ -n "$GITHUB_ACTIONS" ]]; then
printf "::group::%s %-12s [%2d/%2d] %3d%%\n" "$PACKAGE_EMOJI" "$plugin" "$current" "$TOTAL" "$percent"
else
echo "🔨 [$current/$TOTAL] ($percent%) Building $plugin..."
fi
error_status=0
if ! build_plugin "$plugin"; then
FAILED_PLUGINS+=("$plugin")
error_status=1
fi
if [[ -n "$GITHUB_ACTIONS" ]]; then
echo "::endgroup::"
fi
if [ $error_status -ne 0 ]; then
# TODO: if not '--build-all' used
exit 1
fi
done
# Show summary of any failures (if using continue-on-error approach)
if [ ${#FAILED_PLUGINS[@]} -gt 0 ]; then
if [[ -n "$GITHUB_ACTIONS" ]]; then
echo "::group::❌ Build Failures Summary"
else
echo "❌ Build Failures Summary"
echo "=========================================="
fi
echo "The following plugins failed to build:"
for failed_plugin in "${FAILED_PLUGINS[@]}"; do
echo " ❌ $failed_plugin"
done
if [[ -n "$GITHUB_ACTIONS" ]]; then
echo "::endgroup::"
else
echo "=========================================="
fi
exit 1
fi
BUILD_OPTIONS="${COMMON_OPTIONS} -DEdgeTX_SUPERBUILD:BOOL=0 -DNATIVE_BUILD:BOOL=1"
LOG_FILE="build-companion.log"
if [[ -n "$GITHUB_ACTIONS" ]]; then
echo "::group::📦 Final $PACKAGE_NAME Package"
echo "::group::📦 Building $PACKAGE_NAME"
else
echo "📦 Final $PACKAGE_NAME Package"
echo "📦 Building $PACKAGE_NAME"
echo "=========================================="
fi
error_status=0
if run_pipeline "final" "final.log" "companion" "true"; then
if cp native/$PACKAGE_FILES "${OUTDIR}" 2>/dev/null; then
echo " ✅ All builds completed successfully!"
echo " 📁 Package saved to: ${OUTDIR}"
else
echo " ❌ Failed to copy package files to output directory"
echo " 📁 Directory Contents:"
echo " ----------------------"
clean_build() {
rm -f CMakeCache.txt native/CMakeCache.txt
}
echo "Contents of native/ directory:"
ls -la native/ || echo "native/ directory not found"
echo "Looking for files matching: $PACKAGE_FILES"
find native/ -name "$PACKAGE_FILES" 2>/dev/null || echo "No matching files found"
error_status=1
fi
clean_build && mkdir -p native/plugins
# Copy WASM simulator modules if available
if [[ -d "${SRCDIR}/wasm-modules" ]]; then
cp "${SRCDIR}"/wasm-modules/*.wasm native/plugins/ 2>/dev/null && \
echo " 🔌 Copied WASM modules to plugins/" || true
fi
error_status=0
if ! cmake -B native -S "${SRCDIR}" --toolchain cmake/toolchain/native.cmake ${BUILD_OPTIONS} >> "$LOG_FILE" 2>&1; then
echo " ❌ CMake configuration failed"
cat "$LOG_FILE"
error_status=1
elif ! cmake_build_parallel native --target companion ${QUIET_FLAGS} >> "$LOG_FILE" 2>&1; then
echo " ❌ Companion build failed"
cat "$LOG_FILE"
error_status=1
elif ! cmake_build_parallel native --target ${PACKAGE_TARGET} >> "$LOG_FILE" 2>&1; then
echo " ❌ Packaging failed"
cat "$LOG_FILE"
error_status=1
elif cp native/$PACKAGE_FILES "${OUTDIR}" 2>/dev/null; then
echo " ✅ Build completed successfully!"
echo " 📁 Package saved to: ${OUTDIR}"
else
echo " ❌ Final packaging failed"
echo " ❌ Failed to copy package files to output directory"
ls -la native/ || echo "native/ directory not found"
error_status=1
fi
+243
View File
@@ -0,0 +1,243 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
. "$SCRIPT_DIR/build-common.sh"
SRCDIR=$1
OUTDIR=$2
if [[ -z ${SRCDIR} ]]; then
SRCDIR="$(pwd)"
fi
if [[ -z ${OUTDIR} ]]; then
OUTDIR="$(pwd)/output"
fi
if [[ ! -d "${OUTDIR}" ]]; then
mkdir -p "${OUTDIR}"
fi
QUIET_FLAGS=""
if [[ "$CMAKE_GENERATOR" == "Ninja" ]]; then
QUIET_FLAGS="-- --quiet"
else
# Assume Makefile generator for non-Ninja builds
COMMON_OPTIONS="-DCMAKE_RULE_MESSAGES=OFF"
fi
COMMON_OPTIONS+=" -DCMAKE_BUILD_TYPE=Release -DCMAKE_MESSAGE_LOG_LEVEL=WARNING -Wno-dev"
COMMON_OPTIONS+=" -DCMAKE_MODULE_PATH=/opt/wasi-sdk/share/cmake/"
COMMON_OPTIONS+=" -DEdgeTX_SUPERBUILD:BOOL=0 -DNATIVE_BUILD:BOOL=1"
# Generate EDGETX_VERSION_SUFFIX if not already set
if [[ -z ${EDGETX_VERSION_SUFFIX} ]]; then
gh_type=$(echo "$GITHUB_REF" | awk -F / '{print $2}') #heads|tags|pull
if [[ $gh_type = "tags" ]]; then
# tags: refs/tags/<tag_name>
gh_tag=${GITHUB_REF##*/}
export EDGETX_VERSION_TAG=$gh_tag
elif [[ $gh_type = "pull" ]]; then
# pull: refs/pull/<pr_number>/merge
gh_pull_number=PR$(echo "$GITHUB_REF" | awk -F / '{print $3}')
export EDGETX_VERSION_SUFFIX=$gh_pull_number
elif [[ $gh_type = "heads" ]]; then
# heads: refs/heads/<branch_name>
gh_branch=${GITHUB_REF##*/}
export EDGETX_VERSION_SUFFIX=$gh_branch
fi
fi
if [[ -n "$GITHUB_ACTIONS" ]]; then
MAX_JOBS=${MAX_JOBS:-3}
fi
BUILD_DIR="build/wasm"
# Function to output error logs (works in both GitHub Actions and terminal)
output_error_log() {
local log_file="$1"
local context="$2"
if [[ -f "$log_file" ]]; then
echo "------------------------------------------"
echo " Full error output from $log_file:"
echo "------------------------------------------"
cat "$log_file"
else
echo "⚠️ Warning: Log file $log_file not found for $context"
fi
}
# Function to show last N lines of a log file for warnings
show_log_summary() {
local log_file="$1"
local lines="${2:-50}"
local context="$3"
if [[ -f "$log_file" ]]; then
echo "------------------------------------------"
echo "Last $lines lines from $log_file:"
echo "------------------------------------------"
tail -n "$lines" "$log_file"
fi
}
run_pipeline() {
local log_file="${1:-/dev/null}"
local context="$2"
local show_details="${3:-false}"
local cmake_opts="--parallel ${MAX_JOBS} ${QUIET_FLAGS}"
local wasi_toolchain="/opt/wasi-sdk/share/cmake/wasi-sdk-pthread.cmake"
clean_build
if ! execute_with_output "🔧 CMake config" "cmake -S ${SRCDIR} -B ${BUILD_DIR} --toolchain ${wasi_toolchain} ${BUILD_OPTIONS}" "$log_file" "$show_details"; then
output_error_log "$log_file" "$context (Configuration)"
return 1
fi
if ! execute_with_output "📦 Building WASM module" "cmake --build ${BUILD_DIR} --target wasi-module ${cmake_opts}" "$log_file" "$show_details"; then
output_error_log "$log_file" "$context (Library Build)"
return 1
fi
return 0
}
execute_with_output() {
local description="$1"
local command="$2"
local log_file="$3"
local show_output="${4:-false}"
if [[ "$show_output" == "true" && "$log_file" != "/dev/null" ]]; then
echo " $description..."
fi
eval "$command" >> "$log_file" 2>&1
}
clean_build() {
rm -f "${BUILD_DIR}/CMakeCache.txt"
}
# Enhanced plugin builder with better error handling
build_plugin() {
local plugin="$1"
local log_file="${OUTDIR}/build_${plugin}.log"
local verbose="${2:-false}"
BUILD_OPTIONS="${COMMON_OPTIONS} "
if ! get_target_build_options "$plugin" >> "$log_file" 2>&1; then
if [[ -n "$GITHUB_ACTIONS" ]]; then
echo "::error::Failed to get build options for $plugin"
fi
output_error_log "$log_file" "$plugin (Build Options)"
return 1
fi
# Only show detailed output in GitHub Actions or if verbose is requested
local show_details="false"
if [[ -n "$GITHUB_ACTIONS" || "$verbose" == "true" ]]; then
show_details="true"
fi
if ! run_pipeline "$log_file" "$plugin" "$show_details"; then
return 1
fi
# FLAVOUR may differ from target name (e.g. x9dp2019 -> x9d+2019),
# so copy whatever .wasm was produced.
cp ${BUILD_DIR}/edgetx-*-simulator.wasm "${OUTDIR}/" 2>/dev/null
# Check for warnings and show summary if found
if grep -q -i "warning" "$log_file"; then
echo " ⚠️ $plugin completed with warnings"
if [[ "$show_details" == "true" ]]; then
show_log_summary "$log_file" 50 "$plugin (Warnings)"
fi
return 0
fi
echo " ✅ $plugin completed successfully"
return 0
}
if [[ -n "$FLAVOR" ]]; then
# Convert semicolon-separated string to array
IFS=';' read -ra temp_array <<< "$FLAVOR"
plugins=()
for item in "${temp_array[@]}"; do
plugins+=($(echo "$item" | tr '[:upper:]' '[:lower:]'))
done
else
declare -a plugins=(
# monochrome
boxer bumblebee commando8
gx12 mt12 pocket t12max
t14 t20 t20v2 tpros tprov2
tx12mk2 zorro v12 v14
x7access x9dp2019 x9e
# colour
el18 nb4p nv14 st16 pa01
pl18 pl18ev pl18u
t15 t15pro t16 t18
tx15 tx16s tx16smk3 f16 v16
x10 x10express x12s
)
fi
TOTAL=${#plugins[@]}
FAILED_PLUGINS=()
echo "🔨 Building $TOTAL Plugins"
for i in "${!plugins[@]}"; do
plugin="${plugins[$i]}"
current=$((i + 1))
percent=$((current * 100 / TOTAL))
# For terminal output, put each plugin on its own line for cleaner display
if [[ -n "$GITHUB_ACTIONS" ]]; then
printf "::group::📦 %-12s [%2d/%2d] %3d%%\n" "$plugin" "$current" "$TOTAL" "$percent"
else
echo "🔨 [$current/$TOTAL] ($percent%) Building $plugin..."
fi
error_status=0
if ! build_plugin "$plugin"; then
FAILED_PLUGINS+=("$plugin")
error_status=1
fi
if [[ -n "$GITHUB_ACTIONS" ]]; then
echo "::endgroup::"
fi
if [ $error_status -ne 0 ]; then
# TODO: if not '--build-all' used
exit 1
fi
done
# Show summary of any failures (if using continue-on-error approach)
if [ ${#FAILED_PLUGINS[@]} -gt 0 ]; then
if [[ -n "$GITHUB_ACTIONS" ]]; then
echo "::group::❌ Build Failures Summary"
else
echo "❌ Build Failures Summary"
echo "=========================================="
fi
echo "The following plugins failed to build:"
for failed_plugin in "${FAILED_PLUGINS[@]}"; do
echo " ❌ $failed_plugin"
done
if [[ -n "$GITHUB_ACTIONS" ]]; then
echo "::endgroup::"
else
echo "=========================================="
fi
exit 1
fi
+1 -5
View File
@@ -59,12 +59,8 @@ do
cmake ${BUILD_OPTIONS} "${SRCDIR}"
cmake_build_parallel . --target arm-none-eabi-configure
cmake_build_parallel arm-none-eabi --target ${FIRMARE_TARGET}
cmake_build_parallel . --target native-configure
cmake_build_parallel native --target libsimulator
cmake_build_parallel native --target tests-radio
rm -f CMakeCache.txt native/CMakeCache.txt arm-none-eabi/CMakeCache.txt
rm -f CMakeCache.txt native/CMakeCache.txt
done