interpreters/wamr: add compile role of WebAssembly

Add compilation rules to support WebAssembly(WASM/WAMR):

1. Compile Toolchain
 1> Download WASI sdk and export the WASI_SDK_PATH path:

$ wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz
$ tar xf wasi-sdk-19.0-linux.tar.gz
Put wasi-sdk-19.0 to your host WASI_SDK_PATH environment variable, like:
$ export WASI_SDK_PATH=`pwd`/wasi-sdk-19.0

 2> Download Wamr "wamrc" AOT compiler and export to the PATH:
$ mkdir wamrc
$ wget https://github.com/bytecodealliance/wasm-micro-runtime/releases/download/WAMR-1.1.2/wamrc-1.1.2-x86_64-ubuntu-20.04.tar.gz
$ tar xf wamrc-1.1.2-x86_64-ubuntu-20.04.tar.gz
$ export PATH=$PATH:$PWD

2. Configuring and running

 1> Configuring sim/wamr and compile:

nuttx$ ./tools/configure.sh  sim/wamr
nuttx$ make
...
Wamrc Generate AoT: /home/archer/code/nuttx/n5/apps/wasm/hello.aot
Wamrc Generate AoT: /home/archer/code/nuttx/n5/apps/wasm/coremark.aot
LD:  nuttx

 2> Copy the generated wasm file(Interpreter/AoT)

nuttx$ cp ../apps/wasm/hello.aot .
nuttx$ cp ../apps/wasm/hello.wasm .
nuttx$ cp ../apps/wasm/coremark.wasm .

 3> Run iwasm

nuttx$ ./nuttx
NuttShell (NSH) NuttX-10.4.0
nsh> iwasm /data/hello.wasm
Hello, World!!
nsh> iwasm /data/hello.aot
Hello, World!!
nsh> iwasm /data/coremark.wasm
2K performance run parameters for coremark.
CoreMark Size    : 666
Total ticks      : 12000
Total time (secs): 12.000000
Iterations/Sec   : 5.000000
Iterations       : 60
Compiler version : Clang 15.0.7
Compiler flags   : Using NuttX compilation options
Memory location  : Defined by the NuttX configuration
seedcrc          : 0xe9f5
[0]crclist       : 0xe714
[0]crcmatrix     : 0x1fd7
[0]crcstate      : 0x8e3a
[0]crcfinal      : 0xa14c
Correct operation validated. See README.md for run and reporting rules.
CoreMark 1.0 : 5.000000 / Clang 15.0.7 Using NuttX compilation options / Defined by the NuttX configuration

Co-Authored-By: Huang Qi <huangqi3@xiaomi.com>
Signed-off-by: chao an <anchao@xiaomi.com>
This commit is contained in:
chao an 2023-03-02 11:46:37 +08:00 committed by Petro Karashchenko
parent 12d31075eb
commit 4f11f38c38
8 changed files with 266 additions and 1 deletions

2
.gitignore vendored
View File

@ -11,6 +11,7 @@
*.lib
*.lst
*.o
*.wo
*.obj
*.rel
*.src
@ -28,6 +29,7 @@
/romfs.img
/staging
/symtab_apps.c
/wasm
cscope.out
Make.dep
.context

View File

@ -262,3 +262,9 @@ distclean:: clean
$(call DELFILE, .depend)
-include Make.dep
ifeq ($(WASM_BUILD),y)
ifneq ($(CONFIG_INTERPRETERS_WAMR)$(CONFIG_INTERPRETERS_WAMR3),)
include $(APPDIR)$(DELIM)interpreters$(DELIM)Wasm.mk
endif # CONFIG_INTERPRETERS_WAMR || CONFIG_INTERPRETERS_WAMR3
endif # WASM_BUILD

View File

@ -65,7 +65,8 @@ BINDIR ?= $(APPDIR)$(DELIM)bin
# The final build target
BIN ?= $(APPDIR)$(DELIM)libapps$(LIBEXT)
BIN ?= $(APPDIR)$(DELIM)libapps$(LIBEXT)
WBIN ?= $(APPDIR)$(DELIM)wasm$(DELIM)libwasm$(LIBEXT)
# Tools
@ -105,3 +106,19 @@ CFLAGS += ${INCDIR_PREFIX}"$(APPDIR)$(DELIM)include"
CXXFLAGS += ${INCDIR_PREFIX}"$(APPDIR)$(DELIM)include"
NUTTXLIB ?= $(call CONVERT_PATH,$(TOPDIR)$(DELIM)staging)
# Function to get entry index
define GETINDEX
$(eval i=1)
$(eval entry=)
$(foreach e,$(2), \
$(if $(filter $(notdir $(1)),$(notdir $(e))), \
$(eval entry=$(1)), \
$(if $(entry), \
,$(eval i=$(shell expr $(i) + 1)) \
) \
) \
)
$(i)
endef

View File

@ -21,6 +21,10 @@
export APPDIR = $(CURDIR)
include $(APPDIR)/Make.defs
ifeq ($(CONFIG_INTERPRETERS_WAMR),y)
include $(APPDIR)$(DELIM)interpreters$(DELIM)wamr$(DELIM)Toolchain.defs
endif
# The GNU make CURDIR will always be a POSIX-like path with forward slashes
# as path segment separators. This is fine for the above inclusions but
# will cause problems later for the native build. If we know that this is
@ -101,6 +105,9 @@ $(BIN): $(foreach SDIR, $(CONFIGURED_APPS), $(SDIR)_all)
$(Q) for app in ${CONFIGURED_APPS}; do \
$(MAKE) -C "$${app}" archive ; \
done
ifeq ($(CONFIG_INTERPRETERS_WAMR),y)
$(call LINK_WAMR)
endif
endif
else
@ -118,6 +125,9 @@ $(SYMTABOBJ): %$(OBJEXT): %.c
$(BIN): $(SYMTABOBJ)
$(call ARCHIVE_ADD, $(call CONVERT_PATH,$(BIN)), $^)
ifeq ($(CONFIG_INTERPRETERS_WAMR),y)
$(call LINK_WAMR)
endif
endif # !CONFIG_BUILD_LOADABLE
@ -211,4 +221,5 @@ distclean: $(foreach SDIR, $(CLEANDIRS), $(SDIR)_distclean)
$(call DELFILE, $(BIN))
$(call DELFILE, Kconfig)
$(call DELDIR, $(BINDIR))
$(call DELDIR, wasm)
$(call CLEAN)

View File

@ -105,4 +105,8 @@ STACKSIZE += $(CONFIG_COREMARK_STACKSIZE)
MAINSRC += core_main.c
# Build with WebAssembly when CONFIG_INTERPRETERS_WAMR is enabled
WASM_BUILD = y
include $(APPDIR)/Application.mk

View File

@ -31,4 +31,12 @@ MODULE = $(CONFIG_EXAMPLES_HELLO)
MAINSRC = hello_main.c
# Build with WebAssembly when CONFIG_INTERPRETERS_WAMR is enabled
WASM_BUILD = y
# Mode of WebAssembly Micro Runtime
WAMR_MODE = AOT
include $(APPDIR)/Application.mk

68
interpreters/Wasm.mk Normal file
View File

@ -0,0 +1,68 @@
############################################################################
# apps/interpreters/Wasm.mk
#
# 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.
#
############################################################################
ifeq ($(WASM_BUILD),y)
ifneq ($(CONFIG_INTERPRETERS_WAMR)$(CONFIG_INTERPRETERS_WAMR3),)
WASM_INITIAL_MEMORY ?= 65536
STACKSIZE ?= $(CONFIG_DEFAULT_TASK_STACKSIZE)
PRIORITY ?= SCHED_PRIORITY_DEFAULT
# Wamr mode:
# INT: Interpreter (Default)
# AOT: Ahead-of-Time
# XIP: Execution In Place
# JIT: Just In Time
WAMR_MODE ?= INT
# WebAssembly Micro Runtime Toolchain Setting
-include $(APPDIR)$(DELIM)interpreters$(DELIM)wamr$(DELIM)Toolchain.defs
# Targets follow
.PRECIOUS: $(WBIN)
WSRCS := $(MAINSRC) $(CSRCS)
WOBJS := $(WSRCS:%.c=%.wo)
all:: $(WBIN)
$(WOBJS): %.wo : %.c
$(Q) $(WCC) $(WCFLAGS) -c $^ -o $@
$(WBIN): $(WOBJS)
$(shell mkdir -p $(APPDIR)/wasm)
$(Q) $(WAR) $@ $(filter-out $(MAINSRC:%.c=%.wo),$^)
$(foreach main,$(MAINSRC), \
$(eval mainindex=$(strip $(call GETINDEX,$(main),$(MAINSRC)))) \
$(eval dstname=$(shell echo $(main:%.c=%.wo) | sed -e 's/\//_/g')) \
$(shell cp -rf $(strip $(main:%.c=%.wo)) \
$(strip $(APPDIR)/wasm/$(word $(mainindex),$(PROGNAME))#$(WASM_INITIAL_MEMORY)#$(STACKSIZE)#$(PRIORITY)#$(WAMR_MODE)#$(dstname)) \
) \
)
clean::
$(call DELFILE, $(WOBJS))
$(call DELFILE, $(WBIN))
endif # CONFIG_INTERPRETERS_WAMR || CONFIG_INTERPRETERS_WAMR3
endif # WASM_BUILD

View File

@ -0,0 +1,149 @@
############################################################################
# apps/interpreters/wamr/Toolchain.defs
#
# 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.
#
############################################################################
# Wasm32 toolchain setting
# Target: wasm32-unknown-wasi
WCC ?= $(WASI_SDK_PATH)/bin/clang
WAR ?= $(WASI_SDK_PATH)/bin/llvm-ar rcs
WRC ?= wamrc
WSYSROOT ?= $(TOPDIR)
CFLAGS_STRIP = -fsanitize=kernel-address -fsanitize=address -fsanitize=undefined
CFLAGS_STRIP += $(ARCHCPUFLAGS) $(ARCHCFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(ARCHOPTIMIZATION) $(EXTRAFLAGS)
WCFLAGS += $(filter-out $(CFLAGS_STRIP),$(CFLAGS))
WCFLAGS += --sysroot=$(WSYSROOT) -nostdlib -D__NuttX__
WLDFLAGS = -z stack-size=$(STACKSIZE) -Wl,--initial-memory=$(INITIAL_MEMORY)
WLDFLAGS += -Wl,--export=main -Wl,--export=__main_argc_argv
WLDFLAGS += -Wl,--export=__heap_base -Wl,--export=__data_end
WLDFLAGS += -Wl,--no-entry -Wl,--strip-all -Wl,--allow-undefined
ifeq ($(CONFIG_ARCH_ARM),y)
ifeq ($(CONFIG_ARM_THUMB),y)
WTARGET = thumb
else
WTARGET = arm
endif
ifeq ($(CONFIG_ARCH_CORTEXM85),y)
WTARGET := $(WTARGET)v8.1m.main
WCPU = --cpu=cortex-m85
else ifeq ($(CONFIG_ARCH_CORTEXM55),y)
WTARGET := $(WTARGET)v8.1m.main
WCPU = --cpu=cortex-m55
else ifeq ($(CONFIG_ARCH_CORTEXM35P),y)
WTARGET := $(WTARGET)v8m.main
WCPU = --cpu=cortex-m35p
else ifeq ($(CONFIG_ARCH_CORTEXM33),y)
WTARGET := $(WTARGET)v8m.main
WCPU = --cpu=cortex-m33
else ifeq ($(CONFIG_ARCH_CORTEXM23),y)
WTARGET := $(WTARGET)v8m.main
WCPU = --cpu=cortex-m23
else ifeq ($(CONFIG_ARCH_CORTEXM7),y)
WTARGET := $(WTARGET)v7em
WCPU = --cpu=cortex-m7
else ifeq ($(CONFIG_ARCH_CORTEXM4),y)
WTARGET := $(WTARGET)v7em
WCPU = --cpu=cortex-m4
else ifeq ($(CONFIG_ARCH_CORTEXM3),y)
WTARGET := $(WTARGET)v7em
WCPU = --cpu=cortex-m3
else ifeq ($(CONFIG_ARCH_CORTEXM0),y)
WTARGET := $(WTARGET)v6m
WCPU = --cpu=cortex-m0
endif
ifeq ($(CONFIG_ARCH_CORTEXA5),y)
WTARGET := $(WTARGET)armv7
WCPU = --cpu=cortex-a5
else ifeq ($(CONFIG_ARCH_CORTEXA7),y)
WTARGET := $(WTARGET)armv7
WCPU = --cpu=cortex-a7
else ifeq ($(CONFIG_ARCH_CORTEXA8),y)
WTARGET := $(WTARGET)armv8a
WCPU = --cpu=cortex-a8
else ifeq ($(CONFIG_ARCH_CORTEXA9),y)
WTARGET := $(WTARGET)armv7
WCPU = --cpu=cortex-a9
endif
ifeq ($(CONFIG_ARCH_CORTEXR4),y)
WTARGET := $(WTARGET)armv7
WCPU = --cpu=cortex-r4
else ifeq ($(CONFIG_ARCH_CORTEXR5),y)
WTARGET := $(WTARGET)armv7
WCPU = --cpu=cortex-r5
else ifeq ($(CONFIG_ARCH_CORTEXR7),y)
WTARGET := $(WTARGET)armv7
WCPU = --cpu=cortex-r7
endif
else ifeq ($(CONFIG_ARCH_RISCV),y)
ifeq ($(CONFIG_ARCH_RV64),y)
WTARGET = riscv64
else
WTARGET = riscv32
endif
else ifeq ($(CONFIG_ARCH_XTENSA),y)
WTARGET = xtensa
else ifeq ($(CONFIG_ARCH_X86_64),y)
WTARGET = x86_64
else ifeq ($(CONFIG_ARCH_X86),y)
WTARGET = i386
else ifeq ($(CONFIG_ARCH_MIPS),y)
WTARGET = mips
else ifeq ($(CONFIG_ARCH_SIM),y)
RCFLAGS += --disable-simd
ifeq ($(CONFIG_SIM_M32),y)
WTARGET = i386
else
WTARGET = x86_64
endif
endif
RCFLAGS += --target=$(WTARGET) $(WCPU)
define LINK_WAMR
$(if $(wildcard $(APPDIR)$(DELIM)wasm$(DELIM)*.wo), \
$(foreach bin,$(wildcard $(APPDIR)$(DELIM)wasm$(DELIM)*.wo), \
$(eval INITIAL_MEMORY=$(shell echo $(notdir $(bin)) | cut -d'#' -f2)) \
$(eval STACKSIZE=$(shell echo $(notdir $(bin)) | cut -d'#' -f3)) \
$(eval PROGNAME=$(shell echo $(notdir $(bin)) | cut -d'#' -f1)) \
$(eval WAMRMODE=$(shell echo $(notdir $(bin)) | cut -d'#' -f5)) \
$(shell $(WCC) $(bin) $(WBIN) $(WCFLAGS) $(WLDFLAGS) -o $(APPDIR)$(DELIM)wasm$(DELIM)$(PROGNAME).wasm) \
$(if $(CONFIG_INTERPRETERS_WAMR_AOT), \
$(if $(filter AOT,$(WAMRMODE)), \
$(info Wamrc Generate AoT: $(APPDIR)$(DELIM)wasm$(DELIM)$(PROGNAME).aot) \
$(shell $(WRC) $(RCFLAGS) -o $(APPDIR)$(DELIM)wasm$(DELIM)$(PROGNAME).aot \
$(APPDIR)$(DELIM)wasm$(DELIM)$(PROGNAME).wasm > /dev/null), \
$(if $(filter XIP,$(WAMRMODE)), \
$(info Wamrc Generate XiP: $(APPDIR)$(DELIM)wasm$(DELIM)$(PROGNAME).xip) \
$(shell $(WRC) $(RCFLAGS) --enable-indirect-mode --disable-llvm-intrinsics \
-o $(APPDIR)$(DELIM)wasm$(DELIM)$(PROGNAME).xip \
$(APPDIR)$(DELIM)wasm$(DELIM)$(PROGNAME).wasm > /dev/null) \
) \
) \
) \
) \
)
endef