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

This commit is contained in:
xuxin19
2024-11-26 17:21:29 +08:00
committed by Xiang Xiao
parent 3c92c9bff2
commit a0b6f5b67e
5 changed files with 364 additions and 47 deletions

View File

@@ -34,6 +34,7 @@ if(CONFIG_APPS_DIR)
include(nuttx_add_makefile)
include(nuttx_add_luamod)
include(nuttx_add_wamrmod)
include(nuttx_wasm_interface)
nuttx_add_library(apps)
if(NOT EXISTS {NUTTX_APPS_BINDIR}/dummy.c)
file(TOUCH ${NUTTX_APPS_BINDIR}/dummy.c)
@@ -66,7 +67,6 @@ add_subdirectory(platform)
add_subdirectory(sdr)
add_subdirectory(system)
add_subdirectory(testing)
add_subdirectory(tools)
add_subdirectory(videoutils)
add_subdirectory(wireless)
@@ -88,6 +88,7 @@ if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/vendor/CMakeLists.txt)
add_subdirectory(vendor)
endif()
add_subdirectory(tools) # after traversing all subdirectories
add_subdirectory(builtin) # must be last
nuttx_generate_kconfig()

View File

@@ -0,0 +1,58 @@
# ##############################################################################
# cmake/nuttx_wasm_interface.cmake
#
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
# license agreements. See the NOTICE file distributed with this work for
# additional information regarding copyright ownership. The ASF licenses this
# file to you under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
#
# ##############################################################################
# This is NuttX native wrapper for the WAMR interface.
if(NOT TARGET wasm_interface)
add_custom_target(wasm_interface)
endif()
# declare WAMS build directory and add INSTALL path
function(wasm_add_application)
cmake_parse_arguments(
APP "" "NAME;STACK_SIZE;INITIAL_MEMORY_SIZE;WAMR_MODE;INSTALL_NAME"
"SRCS;WLDFLAGS;WCFLAGS;WINCLUDES" ${ARGN})
set_property(
TARGET wasm_interface
APPEND
PROPERTY WASM_DIR ${CMAKE_CURRENT_LIST_DIR})
if(APP_INSTALL_NAME)
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/wasm/${APP_INSTALL_NAME}
COMMAND ${CMAKE_COMMAND} -E touch_nocreate
${CMAKE_BINARY_DIR}/wasm/${APP_INSTALL_NAME}
DEPENDS apps)
add_custom_target(wasm_gen_${APP_NAME}
DEPENDS ${CMAKE_BINARY_DIR}/wasm/${APP_INSTALL_NAME})
add_dynamic_rcraws(RAWS ${CMAKE_BINARY_DIR}/wasm/${APP_INSTALL_NAME}
DEPENDS wasm_gen_${APP_NAME})
endif()
endfunction()
function(wasm_add_library)
set_property(
TARGET wasm_interface
APPEND
PROPERTY WASM_DIR ${CMAKE_CURRENT_LIST_DIR})
endfunction()

View File

@@ -18,17 +18,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)
@@ -43,14 +33,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

@@ -30,10 +30,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)
@@ -45,18 +59,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.
# ~~~
@@ -76,25 +93,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

@@ -44,6 +44,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.
@@ -69,11 +106,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)
@@ -85,12 +128,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()
# ~~~
@@ -113,8 +363,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)
@@ -129,7 +381,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()