chore: cleanup WASM builds (#7196)

This commit is contained in:
Raphael Coeffic
2026-03-21 20:30:58 +10:00
committed by GitHub
parent 769e559837
commit 4c4cb2c31b
11 changed files with 184 additions and 83 deletions
+4
View File
@@ -10,12 +10,16 @@ on:
- '.github/workflows/companion.yml'
- 'companion/**'
- 'tools/build-companion.sh'
- 'tools/build-wasm-modules.sh'
- 'cmake/wasm/CMakeLists.txt'
pull_request:
paths:
- '.github/workflows/companion.yml'
- 'companion/**'
- 'tools/build-companion.sh'
- 'tools/build-wasm-modules.sh'
- 'cmake/wasm/CMakeLists.txt'
workflow_dispatch:
+2
View File
@@ -18,3 +18,5 @@ compile_commands.json
/.vs
CMakeUserPresets.json
.DS_Store
_deps
_wasi_sdk_fetch
+21 -63
View File
@@ -36,20 +36,8 @@ option(EdgeTX_SUPERBUILD "Cross-compile EdgeTX for each toolchain" ON)
include(ExternalProject)
if(EdgeTX_SUPERBUILD)
# Fetch all command line args into CMAKE_ARGS
get_cmake_property(CACHE_VARS CACHE_VARIABLES)
foreach(CACHE_VAR ${CACHE_VARS})
get_property(CACHE_VAR_HELPSTRING CACHE ${CACHE_VAR} PROPERTY HELPSTRING)
if(CACHE_VAR_HELPSTRING STREQUAL "No help, variable specified on the command line.")
get_property(CACHE_VAR_TYPE CACHE ${CACHE_VAR} PROPERTY TYPE)
if(CACHE_VAR_TYPE STREQUAL "UNINITIALIZED")
set(CACHE_VAR_TYPE)
else()
set(CACHE_VAR_TYPE :${CACHE_VAR_TYPE})
endif()
list(APPEND CMAKE_ARGS "-D${CACHE_VAR}${CACHE_VAR_TYPE}=${${CACHE_VAR}}")
endif()
endforeach()
include(Macros)
CollectCommandLineArgs(CMAKE_ARGS)
message("-- CMAKE_ARGS: ${CMAKE_ARGS}")
message("-- CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
@@ -82,85 +70,58 @@ if(EdgeTX_SUPERBUILD)
EXCLUDE_FROM_ALL TRUE
)
if(DEFINED CMAKE_BUILD_PARALLEL_LEVEL)
set(PARALLEL_FLAG --parallel ${CMAKE_BUILD_PARALLEL_LEVEL})
else()
set(PARALLEL_FLAG --parallel)
endif()
# Webasm targets
if(ENABLE_WASM)
include(FetchWasiSDK)
find_package(WasiSDK REQUIRED)
ExternalProject_Add(wasm
SOURCE_DIR ${CMAKE_SOURCE_DIR}
BINARY_DIR ${CMAKE_BINARY_DIR}/wasm
CMAKE_ARGS
${CMAKE_ARGS}
-Wno-dev
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DCMAKE_TOOLCHAIN_FILE=${WASI_SDK_PATH}/share/cmake/wasi-sdk-pthread.cmake
CMAKE_CACHE_ARGS
-DEdgeTX_SUPERBUILD:BOOL=0
-DNATIVE_BUILD:BOOL=1
-DDISABLE_COMPANION:BOOL=1
INSTALL_COMMAND ""
EXCLUDE_FROM_ALL TRUE
)
endif()
# Webasm targets — deferred to a separate CMake project so that
# the WASI SDK is only fetched when wasi-module is actually built.
add_custom_target(configure
DEPENDS native-configure arm-none-eabi-configure)
add_custom_target(libsimulator
COMMAND ${CMAKE_COMMAND} --build native --target libsimulator ${PARALLEL_FLAG}
DEPENDS native-configure
)
add_custom_target(simulator
COMMAND ${CMAKE_COMMAND} --build native --target simulator ${PARALLEL_FLAG}
COMMAND ${CMAKE_COMMAND} --build native --target simulator
DEPENDS native-configure
)
add_custom_target(simu
COMMAND ${CMAKE_COMMAND} --build native --target simu ${PARALLEL_FLAG}
COMMAND ${CMAKE_COMMAND} --build native --target simu
)
if(ENABLE_WASM)
add_custom_target(wasi-module
COMMAND ${CMAKE_COMMAND} --build wasm --target wasi-module --parallel
DEPENDS wasm-configure
)
endif()
add_custom_target(wasi-module
COMMAND ${CMAKE_COMMAND}
-S ${CMAKE_SOURCE_DIR}/cmake/wasm
-B ${CMAKE_BINARY_DIR}/wasm
-DEDGETX_SOURCE_DIR=${CMAKE_SOURCE_DIR}
-DEDGETX_BUILD_TYPE=${CMAKE_BUILD_TYPE}
${CMAKE_ARGS}
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/wasm
)
add_custom_target(companion
COMMAND ${CMAKE_COMMAND} --build native --target companion ${PARALLEL_FLAG}
COMMAND ${CMAKE_COMMAND} --build native --target companion
DEPENDS native-configure
)
add_custom_target(gtests-radio
COMMAND ${CMAKE_COMMAND} --build native --target gtests-radio ${PARALLEL_FLAG}
COMMAND ${CMAKE_COMMAND} --build native --target gtests-radio
DEPENDS native-configure
)
add_custom_target(tests-radio
COMMAND ${CMAKE_COMMAND} --build native --target tests-radio ${PARALLEL_FLAG}
COMMAND ${CMAKE_COMMAND} --build native --target tests-radio
DEPENDS native-configure
)
add_custom_target(bootloader
COMMAND ${CMAKE_COMMAND} --build arm-none-eabi --target bootloader ${PARALLEL_FLAG}
COMMAND ${CMAKE_COMMAND} --build arm-none-eabi --target bootloader
DEPENDS arm-none-eabi-configure
)
add_custom_target(firmware
COMMAND ${CMAKE_COMMAND} --build arm-none-eabi --target firmware ${PARALLEL_FLAG}
COMMAND ${CMAKE_COMMAND} --build arm-none-eabi --target firmware
DEPENDS arm-none-eabi-configure
)
add_custom_target(firmware-size
COMMAND ${CMAKE_COMMAND} --build arm-none-eabi --target firmware-size ${PARALLEL_FLAG}
COMMAND ${CMAKE_COMMAND} --build arm-none-eabi --target firmware-size
DEPENDS arm-none-eabi-configure
)
@@ -184,7 +145,4 @@ else()
set(IGNORE "${LIBUSB1_ROOT_DIR}" "${OPENSSL_ROOT_DIR}")
endif()
# Prevent CMake warnings
set(IGNORE "${ENABLE_WASM}")
add_subdirectory(${RADIO_SRC_DIR})
+2 -2
View File
@@ -1,5 +1,5 @@
# Copy all WASM simulator modules from SRC_DIR to DST_DIR at build time.
# Invoked via cmake -P so the pattern is evaluated on every build.
file(INSTALL "${SRC_DIR}/" DESTINATION "${DST_DIR}"
FILES_MATCHING PATTERN "edgetx-*-simulator.wasm"
MESSAGE_NEVER)
MESSAGE_NEVER
FILES_MATCHING PATTERN "edgetx-*-simulator.wasm")
+28 -2
View File
@@ -80,7 +80,7 @@ function(GenerateDatacopy source output)
add_custom_command(
OUTPUT ${output}
COMMAND ${GEN_DATACOPY_CMD} > ${output}
DEPENDS ${GEN_DATACOPY_DEPEND}
DEPENDS ${GEN_DATACOPY_DEPEND} ${CMAKE_BINARY_DIR}/CMakeCache.txt
)
endfunction()
@@ -128,7 +128,8 @@ function(AddHWGenTarget input template output)
add_custom_command(OUTPUT ${output}
COMMAND ${GEN_JSON} > ${output}
DEPENDS ${INPUT_JSON} ${TEMPLATE} ${GEN_PY_DEPS})
DEPENDS ${INPUT_JSON} ${TEMPLATE} ${GEN_PY_DEPS} ${CMAKE_BINARY_DIR}/CMakeCache.txt
)
endfunction()
macro(AddHeadersSources)
@@ -146,3 +147,28 @@ macro(AddHeadersSources)
)
endforeach()
endmacro()
# Collect all user-specified command-line cache variables into a list
# suitable for forwarding to ExternalProject or sub-project cmake invocations.
# Optional EXCLUDE parameter: regex to skip matching variable names.
function(CollectCommandLineArgs out_var)
cmake_parse_arguments(_cla "" "EXCLUDE" "" ${ARGN})
set(_args "")
get_cmake_property(_cache_vars CACHE_VARIABLES)
foreach(_var ${_cache_vars})
if(_cla_EXCLUDE AND _var MATCHES "${_cla_EXCLUDE}")
continue()
endif()
get_property(_help CACHE ${_var} PROPERTY HELPSTRING)
if(_help STREQUAL "No help, variable specified on the command line.")
get_property(_type CACHE ${_var} PROPERTY TYPE)
if(_type STREQUAL "UNINITIALIZED")
set(_type)
else()
set(_type :${_type})
endif()
list(APPEND _args "-D${_var}${_type}=${${_var}}")
endif()
endforeach()
set(${out_var} ${_args} PARENT_SCOPE)
endfunction()
+1 -1
View File
@@ -48,7 +48,7 @@ if(Qt6_FOUND)
list(APPEND APP_COMMON_DEFINES -D__STDC_LIMIT_MACROS)
endif()
if(APP_CUSTOM_DBG_HANDLER)
# provide full qDebug log context to our custom handler. This may also affect libsimulator, which is why it is here
# provide full qDebug log context to our custom handler.
list(APPEND APP_COMMON_DEFINES -DQT_MESSAGELOGCONTEXT)
list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_ENABLE=1)
if(APP_CUSTOM_DBG_LEVEL GREATER -1 AND APP_CUSTOM_DBG_LEVEL LESS 5)
+20
View File
@@ -0,0 +1,20 @@
# Wrapper around wasi-sdk's pthread toolchain that uses the non-deprecated
# wasm32-wasip1-threads triple (compatible with SDK 25+).
# Propagate WASI_SDK_PREFIX into try_compile sub-projects (used during ABI detection)
list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES WASI_SDK_PREFIX)
if(NOT WASI_SDK_PREFIX)
if(DEFINED ENV{WASI_SDK_PATH})
set(WASI_SDK_PREFIX $ENV{WASI_SDK_PATH})
elseif(EXISTS "/opt/wasi-sdk")
set(WASI_SDK_PREFIX "/opt/wasi-sdk")
endif()
endif()
include(${WASI_SDK_PREFIX}/share/cmake/wasi-sdk-pthread.cmake)
set(triple wasm32-wasip1-threads)
set(CMAKE_C_COMPILER_TARGET ${triple})
set(CMAKE_CXX_COMPILER_TARGET ${triple})
set(CMAKE_ASM_COMPILER_TARGET ${triple})
+48
View File
@@ -0,0 +1,48 @@
# Standalone CMake project for building WASM simulator modules.
# Invoked on-demand by the superbuild's wasi-module target so that
# the WASI SDK is only fetched when WASM targets are actually built.
#
# Usage from superbuild:
# cmake -S . -B build -DPCB=X10 -DPCBREV=TX16S
# cmake --build build --target wasi-module
cmake_minimum_required(VERSION 3.21)
project(EdgeTX-WASM NONE) # NONE = no compiler check (we set a toolchain below)
# Inherit the module path from the main project
list(APPEND CMAKE_MODULE_PATH "${EDGETX_SOURCE_DIR}/cmake")
# Collect command-line args to forward, excluding EDGETX_* (consumed here)
include(Macros)
CollectCommandLineArgs(_forwarded_args EXCLUDE "^EDGETX_")
# Fetch / find WASI SDK
include(FetchWasiSDK)
find_package(WasiSDK REQUIRED)
include(ExternalProject)
ExternalProject_Add(wasm
SOURCE_DIR ${EDGETX_SOURCE_DIR}
BINARY_DIR ${CMAKE_BINARY_DIR}/wasm-build
CMAKE_ARGS
${_forwarded_args}
-Wno-dev
-DCMAKE_BUILD_TYPE=${EDGETX_BUILD_TYPE}
-DWASI_SDK_PREFIX=${WASI_SDK_PATH}
-DCMAKE_TOOLCHAIN_FILE=${EDGETX_SOURCE_DIR}/cmake/toolchain/wasi-threads.cmake
CMAKE_CACHE_ARGS
-DEdgeTX_SUPERBUILD:BOOL=0
-DNATIVE_BUILD:BOOL=1
-DDISABLE_COMPANION:BOOL=1
BUILD_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --target wasi-module
INSTALL_COMMAND ""
)
# Copy .wasm files up after build
ExternalProject_Add_Step(wasm copy-wasm
DEPENDEES build
COMMAND ${CMAKE_COMMAND}
-DSRC_DIR=${CMAKE_BINARY_DIR}/wasm-build -DDST_DIR=${CMAKE_BINARY_DIR}
-P ${EDGETX_SOURCE_DIR}/cmake/CopyWasmModules.cmake
)
+2 -2
View File
@@ -1,7 +1,7 @@
option(SIMU_TARGET "Configure libsimulator/simu targets" ON)
option(SIMU_TARGET "Configure simu target" ON)
if(NOT SIMU_TARGET)
message(STATUS "libsimulator/simu targets disabled")
message(STATUS "simu target disabled")
return()
endif()
-4
View File
@@ -221,10 +221,6 @@ def main():
binary = "firmware.bin"
ext = ".bin"
filename = "opentx"
elif target == "libsimulator":
binary = "libopentx-" + board_name + "-simulator.so"
ext = ".so"
filename = "libopentx"
else:
return INVALID_BOARD
+56 -9
View File
@@ -27,7 +27,6 @@ else
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
@@ -54,6 +53,58 @@ fi
BUILD_DIR="build/wasm"
# Resolve WASI SDK: use WASI_SDK_PATH env, /opt/wasi-sdk, or auto-fetch
resolve_wasi_sdk() {
if [[ -n "$WASI_SDK_PATH" ]] && [[ -d "$WASI_SDK_PATH" ]]; then
echo "Using WASI SDK from WASI_SDK_PATH=$WASI_SDK_PATH"
return 0
fi
if [[ -d "/opt/wasi-sdk" ]]; then
WASI_SDK_PATH="/opt/wasi-sdk"
echo "Using WASI SDK from /opt/wasi-sdk"
return 0
fi
echo "WASI SDK not found, fetching via cmake/FetchWasiSDK.cmake..."
# Run a minimal cmake project that reuses FetchWasiSDK.cmake to download
# the SDK. Downloads go into _deps/ which persists across plugin builds.
local fetch_dir="_wasi_sdk_fetch"
mkdir -p "$fetch_dir"
cat > "$fetch_dir/CMakeLists.txt" << CMAKEOF
cmake_minimum_required(VERSION 3.14)
project(wasi_sdk_fetch NONE)
list(APPEND CMAKE_MODULE_PATH "${SRCDIR}/cmake")
include(FetchWasiSDK)
file(WRITE "\${CMAKE_CURRENT_BINARY_DIR}/wasi_sdk_path.txt" "\${WASI_SDK_PATH}")
CMAKEOF
if ! cmake -S "$fetch_dir" -B "$fetch_dir/build" \
-DFETCHCONTENT_BASE_DIR="$PWD/_deps" 2>&1; then
echo "❌ Failed to fetch WASI SDK"
return 1
fi
WASI_SDK_PATH=$(cat "$fetch_dir/build/wasi_sdk_path.txt")
if [[ -z "$WASI_SDK_PATH" ]] || [[ ! -d "$WASI_SDK_PATH" ]]; then
echo "❌ WASI SDK path not resolved"
return 1
fi
echo "Using auto-fetched WASI SDK at $WASI_SDK_PATH"
return 0
}
if ! resolve_wasi_sdk; then
echo "❌ Cannot proceed without WASI SDK"
exit 1
fi
export WASI_SDK_PATH
COMMON_OPTIONS+=" -DCMAKE_MODULE_PATH=${WASI_SDK_PATH}/share/cmake/"
COMMON_OPTIONS+=" -DWASI_SDK_PREFIX=${WASI_SDK_PATH}"
# Function to output error logs (works in both GitHub Actions and terminal)
output_error_log() {
local log_file="$1"
@@ -88,10 +139,9 @@ run_pipeline() {
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
local wasi_toolchain="${SRCDIR}/cmake/toolchain/wasi-threads.cmake"
if ! execute_with_output "🔧 CMake config" "cmake --fresh -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
@@ -113,13 +163,10 @@ execute_with_output() {
echo " $description..."
fi
rm -f "$log_file"
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"