cmake(enhance):Enhanced full WASM library and application compilation

1.add complete compilation FLAGS for wasm toolchain
2.wasm build no longer traverses the native directory, saving build time
3.implement OPT and AOT process actions for wasm files
4.create a bridge interface for navtie build and wasm build

Signed-off-by: xuxin19 <xuxin19@xiaomi.com>
This commit is contained in:
xuxin19 2024-11-26 17:21:29 +08:00 committed by Xiang Xiao
parent 2ad162d27d
commit fb367c9792
5 changed files with 364 additions and 47 deletions

View file

@ -20,17 +20,7 @@
#
# ##############################################################################
# Fake wasm_add_application function to suppress error from native build process
function(wasm_add_application)
endfunction()
# Fake wasm_add_library function to suppress error from native build process
function(wasm_add_library)
endfunction()
if(CONFIG_TOOLS_WASM_BUILD)
if(CONFIG_TOOLS_WASM_BUILD OR CONFIG_INTERPRETERS_WAMR_BUILD_MODULES_FOR_NUTTX)
include(ExternalProject)
@ -45,14 +35,22 @@ if(CONFIG_TOOLS_WASM_BUILD)
# Get parent dir of CMAKE_CURRENT_SOURCE_DIR
get_filename_component(APPDIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
# Get the Wasm build dirs from the wasm_interface target
get_property(
WASM_DIRS
TARGET wasm_interface
PROPERTY WASM_DIR)
# ensure the Wasm build dirs are unique
list(REMOVE_DUPLICATES WASM_DIRS)
# Configure and build the Wasm based application
add_custom_target(
configure_wasm_build
COMMAND
${CMAKE_COMMAND} -B${CMAKE_BINARY_DIR}/Wasm
${CMAKE_CURRENT_SOURCE_DIR}/Wasm -DAPPDIR=${APPDIR} -DTOPDIR=${TOPDIR}
-DKCONFIG_FILE_PATH=${KCONFIG_FILE_PATH}
-DWASI_SDK_PATH=$ENV{WASI_SDK_PATH})
-DTOPBINDIR=${CMAKE_BINARY_DIR} -DKCONFIG_FILE_PATH=${KCONFIG_FILE_PATH}
-DWASI_SDK_PATH=$ENV{WASI_SDK_PATH} -DWASM_DIRS=${WASM_DIRS})
add_custom_target(wasm_build COMMAND ${CMAKE_COMMAND} --build
${CMAKE_BINARY_DIR}/Wasm)

View file

@ -32,10 +32,24 @@
cmake_minimum_required(VERSION 3.5)
cmake_policy(SET CMP0079 NEW)
# Include the NuttX kconfig parser to shared the configuration between the NuttX
# build and the Wasm build. And then parse the input KCONFIG_FILE_PATH to get
# the configuration.
include(${TOPDIR}/cmake/nuttx_kconfig.cmake)
# Parse the input KCONFIG_FILE_PATH to get the configuration.
nuttx_export_kconfig(${KCONFIG_FILE_PATH})
# Include the WASI-SDK.cmake file to setup the necessary flags for building
include(WASI-SDK.cmake)
project(WasmApps)
# Add the wasm_interface library to hold all the Wasm libraries.
add_library(wasm_interface INTERFACE)
# Check whether the APPDIR is defined or not. If not, then set it to the parent
# directory of the current CMakeLists.txt file.
if(NOT DEFINED APPDIR)
@ -47,18 +61,21 @@ if(NOT DEFINED TOPDIR)
message(FATAL_ERROR "TOPDIR is not defined")
endif()
# Check wether the TOPBINDIR is defined or not. If not, then raise an error.
if(NOT DEFINED TOPBINDIR)
message(FATAL_ERROR "TOPBINDIR is not defined")
endif()
if(NOT EXISTS ${TOPBINDIR}/wasm)
file(MAKE_DIRECTORY ${TOPBINDIR}/wasm)
endif()
# Check wether the KCONFIG_FILE_PATH is defined or not. If not, then raise an
# error.
if(NOT DEFINED KCONFIG_FILE_PATH)
message(FATAL_ERROR "KCONFIG_FILE_PATH is not defined")
endif()
# Include the NuttX kconfig parser to shared the configuration between the NuttX
# build and the Wasm build. And then parse the input KCONFIG_FILE_PATH to get
# the configuration.
include(${TOPDIR}/cmake/nuttx_kconfig.cmake)
nuttx_export_kconfig(${KCONFIG_FILE_PATH})
# Provide FAR macro from command line since it is not supported in wasi-sdk, but
# it is used in NuttX code.
# ~~~
@ -78,25 +95,11 @@ function(nuttx_add_library)
endfunction()
# Recursively find all the CMakeLists.txt files in the ${APPDIR} and add it by
# add_subdirectory, but exclude the CMakeLists.txt file in the ${APPDIR}/tools
# directory.
file(GLOB_RECURSE WASM_APPS ${APPDIR}/*/CMakeLists.txt)
list(FILTER WASM_APPS EXCLUDE REGEX ".*/tools/.*")
# Read and check if wasm_add_application is called in the CMakeLists.txt file in
# WASM_APPS If true, then add the directory to the build process
foreach(WASM_APP ${WASM_APPS})
file(READ ${WASM_APP} WASM_APP_CONTENTS)
string(FIND "${WASM_APP_CONTENTS}" "wasm_add_application" WASM_APP_FOUND)
string(FIND "${WASM_APP_CONTENTS}" "wasm_add_library" WASM_LIB_FOUND)
if(WASM_APP_FOUND GREATER -1 OR WASM_LIB_FOUND GREATER -1)
get_filename_component(WASM_APP_DIR ${WASM_APP} DIRECTORY)
# Add subdirectory to the build process and put the build directory in the
# current build directory with the name same as the relative path of the
# ${APPDIR}
string(REPLACE ${APPDIR} "" WASM_APP_BUILD_DIR ${WASM_APP_DIR})
add_subdirectory(${WASM_APP_DIR}
${CMAKE_CURRENT_BINARY_DIR}/Wasm/${WASM_APP_BUILD_DIR})
endif()
# ~~~
# Add all the Wasm apps to the build process.
foreach(WASM_APP ${WASM_DIRS})
string(REPLACE ${APPDIR} "" WASM_APP_BUILD_DIR ${WASM_APP})
add_subdirectory(${WASM_APP}
${CMAKE_CURRENT_BINARY_DIR}/Wasm/${WASM_APP_BUILD_DIR})
endforeach()
# ~~~

View file

@ -46,6 +46,43 @@ set(CMAKE_SYSTEM_PROCESSOR wasm32)
set(CMAKE_C_COMPILER ${WASI_SDK_PATH}/bin/clang)
set(CMAKE_CXX_COMPILER ${WASI_SDK_PATH}/bin/clang++)
# setup the flags for the compiler and linker
include_directories(${TOPDIR}/include ${TOPBINDIR}/include)
if(CONFIG_DEBUG_FULLOPT)
add_compile_options(-Oz)
elseif(CONFIG_DEBUG_CUSTOMOPT)
add_compile_options(${CONFIG_DEBUG_OPTLEVEL})
endif()
if(CONFIG_LTO_FULL OR CONFIG_LTO_THIN)
add_compile_options(-flto)
add_link_options(-flto)
endif()
add_compile_options(--sysroot=${TOPDIR})
add_compile_options(-nostdlib)
add_compile_options(-D__NuttX__)
if(NOT CONFIG_LIBM)
add_compile_options(-DCONFIG_LIBM=1)
include_directories(${APPDIR}/include/wasm)
endif()
add_link_options(-Wl,--export=main)
add_link_options(-Wl,--export=__main_argc_argv)
add_link_options(-Wl,--export=__heap_base)
add_link_options(-Wl,--export=__data_end)
add_link_options(-Wl,--no-entry)
add_link_options(-Wl,--strip-all)
add_link_options(-Wl,--allow-undefined)
execute_process(
COMMAND ${CMAKE_C_COMPILER} --print-libgcc-file-name
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE WCC_COMPILER_RT_LIB)
# ~~~
# Function "wasm_add_application" to add a WebAssembly application to the
# build system.
@ -71,11 +108,17 @@ function(wasm_add_application)
# Parse the APP_NAME and APP_SRCS from the arguments
set(APP_NAME "")
set(APP_SRCS "")
set(APP_STACK_SIZE 2048)
set(APP_INITIAL_MEMORY_SIZE 65536)
set(APP_STACK_SIZE "")
set(APP_INITIAL_MEMORY_SIZE "")
set(APP_INSTALL_NAME "")
set(APP_WAMR_MODE INT)
set(APP_WCFLAGS "")
set(APP_WLDFLAGS "")
set(APP_WINCLUDES "")
cmake_parse_arguments(APP "" "NAME;STACK_SIZE;INITIAL_MEMORY_SIZE" "SRCS"
${ARGN})
cmake_parse_arguments(
APP "" "NAME;STACK_SIZE;INITIAL_MEMORY_SIZE;WAMR_MODE;INSTALL_NAME"
"SRCS;WLDFLAGS;WCFLAGS;WINCLUDES" ${ARGN})
# Check if the APP_NAME (NAME) is provided
if(NOT APP_NAME)
@ -87,12 +130,219 @@ function(wasm_add_application)
message(FATAL_ERROR "SRCS is not provided.")
endif()
if(NOT APP_STACK_SIZE)
set(APP_STACK_SIZE 2048)
endif()
if(NOT APP_INITIAL_MEMORY_SIZE)
set(APP_INITIAL_MEMORY_SIZE 65536)
endif()
# Create the executable target for the application
add_executable(${APP_NAME} ${APP_SRCS})
target_link_libraries(${APP_NAME} PRIVATE wasm_interface)
target_include_directories(${APP_NAME} PRIVATE ${APP_WINCLUDES})
target_compile_options(${APP_NAME} PRIVATE ${APP_WCFLAGS})
target_link_options(${APP_NAME} PRIVATE -z stack-size=${APP_STACK_SIZE})
target_link_options(${APP_NAME} PRIVATE
-Wl,--initial-memory=${APP_INITIAL_MEMORY_SIZE})
target_link_options(${APP_NAME} PRIVATE ${APP_WLD_FLAGS})
target_link_libraries(${APP_NAME} PRIVATE ${WCC_COMPILER_RT_LIB})
# Set the target properties
set_target_properties(${APP_NAME} PROPERTIES OUTPUT_NAME ${APP_NAME}.wasm)
# do WASM OPTIMIZATION
add_custom_target(
${APP_NAME}_OPT ALL
COMMAND ${WASI_SDK_PATH}/wasm-opt -Oz --enable-bulk-memory -o
${APP_NAME}.wasm ${APP_NAME}.wasm
DEPENDS ${APP_NAME}
COMMENT "WASM build:Optimizing ${APP_NAME}")
# armv7a
if(CONFIG_ARCH_ARMV7A)
if(CONFIG_ARCH_CORTEXA5)
set(LLVM_CPUTYPE cortex-a5)
elseif(CONFIG_ARCH_CORTEXA7)
set(LLVM_CPUTYPE cortex-a7)
elseif(CONFIG_ARCH_CORTEXA8)
set(LLVM_CPUTYPE cortex-a8)
elseif(CONFIG_ARCH_CORTEXA9)
set(LLVM_CPUTYPE cortex-a9)
endif()
if(CONFIG_ARM_THUMB)
set(LLVM_ARCHTYPE thumbv7)
else()
set(LLVM_ARCHTYPE armv7a)
endif()
if(CONFIG_ARCH_FPU)
set(LLVM_ABITYPE eabihf)
else()
set(LLVM_ABITYPE eabi)
endif()
endif()
# armv7m
if(CONFIG_ARCH_ARMV7M)
if(CONFIG_ARCH_CORTEXM4)
set(LLVM_CPUTYPE cortex-m4)
elseif(CONFIG_ARCH_CORTEXM7)
set(LLVM_CPUTYPE cortex-m7)
else()
set(LLVM_CPUTYPE cortex-m3)
endif()
if(CONFIG_ARCH_CORTEXM3)
set(LLVM_ARCHTYPE thumbv7m)
else()
set(LLVM_ARCHTYPE thumbv7em)
endif()
if(CONFIG_ARCH_FPU)
set(LLVM_ABITYPE eabihf)
else()
set(LLVM_ABITYPE eabi)
endif()
endif()
# armv8m
if(CONFIG_ARCH_ARMV8M)
if(CONFIG_ARM_DS)
set(EXTCPUFLAGS +dsp)
endif()
if(CONFIG_ARM_PACBTI)
set(EXTCPUFLAGS ${EXTCPUFLAGS}+pacbti)
endif()
if(CONFIG_ARM_HAVE_MVE)
set(EXTCPUFLAGS ${EXTCPUFLAGS}+mve.fp+fp.dp)
endif()
if(CONFIG_ARCH_CORTEXM23)
set(LLVM_CPUTYPE cortex-m23)
elseif(CONFIG_ARCH_CORTEXM33)
set(LLVM_CPUTYPE cortex-m33)
elseif(CONFIG_ARCH_CORTEXM35P)
set(LLVM_CPUTYPE cortex-m35p)
elseif(CONFIG_ARCH_CORTEXM55)
set(LLVM_CPUTYPE cortex-m55)
elseif(CONFIG_ARCH_CORTEXM85)
set(LLVM_CPUTYPE cortex-m85)
endif()
set(LLVM_ARCHTYPE thumbv8m.main${EXTCPUFLAGS})
if(CONFIG_ARCH_FPU)
set(LLVM_ABITYPE eabihf)
else()
set(LLVM_ABITYPE eabi)
endif()
endif()
# armv7r
if(CONFIG_ARCH_ARMV7R)
if(CONFIG_ARCH_CORTEXR4)
set(LLVM_CPUTYPE cortex-r4)
elseif(CONFIG_ARCH_CORTEXR5)
set(LLVM_CPUTYPE cortex-r5)
elseif(CONFIG_ARCH_CORTEXR7)
set(LLVM_CPUTYPE cortex-r7)
endif()
if(CONFIG_ARM_THUMB)
set(LLVM_ARCHTYPE thumbv7r)
else()
set(LLVM_ARCHTYPE armv7r)
endif()
if(CONFIG_ARCH_FPU)
set(LLVM_ABITYPE eabihf)
else()
set(LLVM_ABITYPE eabi)
endif()
endif()
# armv6m
if(CONFIG_ARCH_ARMV6M)
set(LLVM_CPUTYPE cortex-m0)
set(LLVM_ARCHTYPE thumbv6m)
set(LLVM_ABITYPE eabi)
endif()
set(RCFLAGS)
set(WRC wamrc)
if(CONFIG_ARCH_XTENSA)
set(WTARGET "xtensa")
elseif(CONFIG_ARCH_X86_64)
set(WTARGET "x86_64")
elseif(CONFIG_ARCH_X86)
set(WTARGET "i386")
elseif(CONFIG_ARCH_MIPS)
set(WTARGET "mips")
elseif(CONFIG_ARCH_SIM)
list(APPEND RCFLAGS --disable-simd)
if(CONFIG_SIM_M32)
set(WTARGET "i386")
else()
set(WTARGET "x86_64")
endif()
elseif(LLVM_ARCHTYPE MATCHES "thumb")
string(FIND "${LLVM_ARCHTYPE}" "+" PLUS_INDEX)
if(PLUS_INDEX EQUAL -1)
set(WTARGET "${LLVM_ARCHTYPE}")
else()
string(SUBSTRING "${LLVM_ARCHTYPE}" 0 ${PLUS_INDEX} WTARGET)
endif()
else()
set(WTARGET ${LLVM_ARCHTYPE})
endif()
set(WCPU ${LLVM_CPUTYPE})
if("${LLVM_ABITYPE}" STREQUAL "eabihf")
set(WABITYPE "gnueabihf")
else()
set(WABITYPE "${LLVM_ABITYPE}")
endif()
list(APPEND RCFLAGS --target=${WTARGET})
list(APPEND RCFLAGS --cpu=${WCPU})
list(APPEND RCFLAGS --target-abi=${WABITYPE})
if(CONFIG_INTERPRETERS_WAMR_AOT)
if("${APP_WAMR_MODE}" STREQUAL "AOT")
# generate AoT
add_custom_target(
${APP_NAME}_AOT ALL
COMMAND ${WRC} ${RCFLAGS} -o ${APP_NAME}.aot ${APP_NAME}.wasm
DEPENDS ${APP_NAME}_OPT
COMMENT "Wamrc Generate AoT: ${APP_NAME}.aot")
set(APP_INSTALL_BIN ${APP_NAME}.aot)
if(NOT APP_INSTALL_NAME)
set(APP_INSTALL_NAME ${APP_NAME}.aot)
endif()
elseif("${APP_WAMR_MODE}" STREQUAL "XIP")
# generate XIP
add_custom_target(
${APP_NAME}_AOT ALL
COMMAND ${WRC} ${RCFLAGS} --enable-indirect-mode
--disable-llvm-intrinsics -o ${APP_NAME}.xip ${APP_NAME}.wasm
DEPENDS ${APP_NAME}_OPT
COMMENT "Wamrc Generate XIP: ${APP_NAME}.xip")
set(APP_INSTALL_BIN ${APP_NAME}.xip)
if(NOT APP_INSTALL_NAME)
set(APP_INSTALL_NAME ${APP_NAME}.xip)
endif()
endif()
else()
set(APP_INSTALL_BIN ${APP_NAME}.wasm)
if(NOT APP_INSTALL_NAME)
set(APP_INSTALL_NAME ${APP_NAME}.wasm)
endif()
endif()
# install WASM BIN
add_custom_target(
${APP_NAME}_INSTALL ALL
COMMAND ${CMAKE_COMMAND} -E copy ${APP_INSTALL_BIN}
${TOPBINDIR}/wasm/${APP_INSTALL_NAME}
DEPENDS ${APP_NAME}_OPT
COMMENT "Install WASM BIN: ${APP_INSTALL_NAME}")
endfunction()
# ~~~
@ -115,8 +365,10 @@ function(wasm_add_library)
# Parse the LIB_NAME and LIB_SRCS from the arguments
set(LIB_NAME "")
set(LIB_SRCS "")
set(APP_WCFLAGS "")
set(APP_WINCLUDES "")
cmake_parse_arguments(LIB "" "NAME" "SRCS" ${ARGN})
cmake_parse_arguments(LIB "" "NAME" "SRCS;WCFLAGS;WINCLUDES" ${ARGN})
# Check if the LIB_NAME (NAME) is provided
if(NOT LIB_NAME)
@ -131,7 +383,12 @@ function(wasm_add_library)
# Create the static library target for the library
add_library(${LIB_NAME} STATIC ${LIB_SRCS})
target_include_directories(${LIB_NAME} PRIVATE ${LIB_WINCLUDES})
target_compile_options(${LIB_NAME} PRIVATE ${LIB_WCFLAGS})
add_dependencies(wasm_interface ${LIB_NAME})
target_link_libraries(wasm_interface INTERFACE ${LIB_NAME})
# Set the target properties
set_target_properties(${LIB_NAME} PROPERTIES OUTPUT_NAME lib${LIB_NAME}.a)
set_target_properties(${LIB_NAME} PROPERTIES OUTPUT_NAME ${LIB_NAME})
endfunction()