Skip to content

Commit c138651

Browse files
no1wudiacassis
authored andcommitted
tools: New CMake based Wasm build system
Introduce a new CMake based build system for Wasm. And target the Wasm ABI to wasm32-wasi, it should be a more commnly used and standard ABI for Wasm. Signed-off-by: Huang Qi <[email protected]>
1 parent ec4d7a1 commit c138651

12 files changed

+447
-1
lines changed

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ add_subdirectory(platform)
5959
add_subdirectory(sdr)
6060
add_subdirectory(system)
6161
add_subdirectory(testing)
62+
add_subdirectory(tools)
6263
add_subdirectory(wireless)
6364

6465
# add examples and external at the end to allow library dependencies

Makefile

+21
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,25 @@ $(INCDIR): $(TOPDIR)/tools/incdir.c
6464

6565
IMPORT_TOOLS = $(MKDEP) $(INCDIR)
6666

67+
ifeq ($(CONFIG_TOOLS_WASM_BUILD),y)
68+
69+
configure_wasm:
70+
$(Q) cmake -B$(APPDIR)$(DELIM)tools$(DELIM)Wasm$(DELIM)build \
71+
$(APPDIR)$(DELIM)tools$(DELIM)Wasm \
72+
-DAPPDIR=$(APPDIR) -DTOPDIR=$(TOPDIR) \
73+
-DWASI_SDK_PATH=$(WASI_SDK_PATH) \
74+
-DKCONFIG_FILE_PATH=$(TOPDIR)$(DELIM).config
75+
76+
context_wasm: configure_wasm
77+
$(Q) cmake --build $(APPDIR)$(DELIM)tools$(DELIM)Wasm$(DELIM)build
78+
79+
else
80+
81+
context_wasm:
82+
83+
endif
84+
85+
6786
# In the KERNEL build, we must build and install all of the modules. No
6887
# symbol table is needed
6988

@@ -155,6 +174,7 @@ staging:
155174
context: | staging
156175
$(Q) $(MAKE) context_all
157176
$(Q) $(MAKE) register_all
177+
$(Q) $(MAKE) context_wasm
158178

159179
Kconfig:
160180
$(foreach SDIR, $(CONFIGDIRS), $(call MAKE_template,$(SDIR),preconfig))
@@ -205,4 +225,5 @@ distclean: $(foreach SDIR, $(CLEANDIRS), $(SDIR)_distclean)
205225
$(call DELDIR, $(BINDIR))
206226
$(call DELDIR, staging)
207227
$(call DELDIR, wasm)
228+
$(call DELDIR, $(APPDIR)$(DELIM)tools$(DELIM)Wasm$(DELIM)build)
208229
$(call CLEAN)

examples/hello_wasm/CMakeLists.txt

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# ##############################################################################
2+
# apps/examples/hello_wasm/CMakeLists.txt
3+
#
4+
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
5+
# license agreements. See the NOTICE file distributed with this work for
6+
# additional information regarding copyright ownership. The ASF licenses this
7+
# file to you under the Apache License, Version 2.0 (the "License"); you may not
8+
# use this file except in compliance with the License. You may obtain a copy of
9+
# the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16+
# License for the specific language governing permissions and limitations under
17+
# the License.
18+
#
19+
# ##############################################################################
20+
21+
if(CONFIG_EXAMPLES_HELLO_WASM_BUILD_NATIVE)
22+
nuttx_add_application(
23+
NAME
24+
${CONFIG_EXAMPLES_HELLO_WASM_PROGNAME}
25+
SRCS
26+
hello_main.c
27+
STACKSIZE
28+
${CONFIG_EXAMPLES_HELLO_WASM_STACKSIZE}
29+
PRIORITY
30+
${CONFIG_EXAMPLES_HELLO_WASM_PRIORITY})
31+
endif()
32+
33+
if(CONFIG_EXAMPLES_HELLO_WASM_BUILD_WASM)
34+
wasm_add_application(NAME ${CONFIG_EXAMPLES_HELLO_WASM_PROGNAME} SRCS
35+
hello_main.c)
36+
endif()

examples/hello_wasm/Kconfig

+12
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,16 @@ config EXAMPLES_HELLO_WASM_STACKSIZE
2626
int "Hello wasm stack size"
2727
default DEFAULT_TASK_STACKSIZE
2828

29+
config EXAMPLES_HELLO_WASM_BUILD_WASM
30+
bool "Build as WebAssembly module"
31+
default y
32+
---help---
33+
Build the WebAssembly binary from the C source code.
34+
35+
config EXAMPLES_HELLO_WASM_BUILD_NATIVE
36+
bool "Build as native program"
37+
default n
38+
---help---
39+
Build the native binary from the C source code.
40+
2941
endif

examples/hello_wasm/hello_main.c

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
* Included Files
2323
****************************************************************************/
2424

25-
#include <nuttx/config.h>
2625
#include <stdio.h>
2726

2827
/****************************************************************************

tools/CMakeLists.txt

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# ##############################################################################
2+
# apps/tools/CMakeLists.txt
3+
#
4+
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
5+
# license agreements. See the NOTICE file distributed with this work for
6+
# additional information regarding copyright ownership. The ASF licenses this
7+
# file to you under the Apache License, Version 2.0 (the "License"); you may not
8+
# use this file except in compliance with the License. You may obtain a copy of
9+
# the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16+
# License for the specific language governing permissions and limitations under
17+
# the License.
18+
#
19+
# ##############################################################################
20+
21+
# Fake wasm_add_application function to suppress error from native build process
22+
function(wasm_add_application)
23+
24+
endfunction()
25+
26+
# Fake wasm_add_library function to suppress error from native build process
27+
function(wasm_add_library)
28+
29+
endfunction()
30+
31+
if(CONFIG_TOOLS_WASM_BUILD)
32+
33+
include(ExternalProject)
34+
35+
set(TOPDIR
36+
${CMAKE_SOURCE_DIR}
37+
CACHE INTERNAL "")
38+
39+
set(KCONFIG_FILE_PATH
40+
${CMAKE_BINARY_DIR}/.config
41+
CACHE INTERNAL "")
42+
43+
# Get parent dir of CMAKE_CURRENT_SOURCE_DIR
44+
get_filename_component(APPDIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
45+
46+
# Configure and build the Wasm based application
47+
add_custom_target(
48+
configure_wasm_build
49+
COMMAND
50+
${CMAKE_COMMAND} -B${CMAKE_BINARY_DIR}/Wasm
51+
${CMAKE_CURRENT_SOURCE_DIR}/Wasm -DAPPDIR=${APPDIR} -DTOPDIR=${TOPDIR}
52+
-DKCONFIG_FILE_PATH=${KCONFIG_FILE_PATH}
53+
-DWASI_SDK_PATH=$ENV{WASI_SDK_PATH})
54+
55+
add_custom_target(wasm_build COMMAND ${CMAKE_COMMAND} --build
56+
${CMAKE_BINARY_DIR}/Wasm)
57+
58+
add_dependencies(wasm_build configure_wasm_build)
59+
60+
# Add the Wasm based application to the build. Notice: Wasm build will be
61+
# triggered by the native build process each time, but it's ok since the
62+
# incremental build is very fast in CMake.
63+
add_dependencies(apps wasm_build)
64+
65+
endif()

tools/Kconfig

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#
2+
# For a description of the syntax of this configuration file,
3+
# see the file kconfig-language.txt in the NuttX tools repository.
4+
#
5+
6+
menu "Extra Tools"
7+
8+
menu "Wasm Build Options"
9+
10+
config TOOLS_WASM_BUILD
11+
bool "Enable Wasm build support"
12+
default n
13+
---help---
14+
If enabled, then then build system will trigger the Wasm build
15+
process. This will require the WASI-SDK to be installed on the
16+
host system.
17+
18+
endmenu
19+
20+
endmenu

tools/Wasm/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
build

tools/Wasm/CMakeLists.txt

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# ##############################################################################
2+
# apps/tools/Wasm/CMakeLists.txt
3+
#
4+
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
5+
# license agreements. See the NOTICE file distributed with this work for
6+
# additional information regarding copyright ownership. The ASF licenses this
7+
# file to you under the Apache License, Version 2.0 (the "License"); you may not
8+
# use this file except in compliance with the License. You may obtain a copy of
9+
# the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16+
# License for the specific language governing permissions and limitations under
17+
# the License.
18+
#
19+
# ##############################################################################
20+
21+
# ~~~
22+
# This file is used to manage the WebAssembly (Wasm) build process as entry
23+
# point. All the wasm apps are built using this file as a sub target.
24+
#
25+
# Necessary input for this file is the APPDIR, TOPDIR and KCONFIG_FILE_PATH.
26+
# The APPDIR is the directory where the Wasm apps are located.
27+
# The TOPDIR is the root directory of the NuttX source code.
28+
# The KCONFIG_FILE_PATH is the path to the .config file of the NuttX build.
29+
# ~~~
30+
31+
cmake_minimum_required(VERSION 3.5)
32+
33+
include(WASI-SDK.cmake)
34+
35+
project(WasmApps)
36+
37+
# Check whether the APPDIR is defined or not. If not, then set it to the parent
38+
# directory of the current CMakeLists.txt file.
39+
if(NOT DEFINED APPDIR)
40+
message(FATAL_ERROR "APPDIR is not defined")
41+
endif()
42+
43+
# Check wether the TOPDIR is defined or not. If not, then raise an error.
44+
if(NOT DEFINED TOPDIR)
45+
message(FATAL_ERROR "TOPDIR is not defined")
46+
endif()
47+
48+
# Check wether the KCONFIG_FILE_PATH is defined or not. If not, then raise an
49+
# error.
50+
if(NOT DEFINED KCONFIG_FILE_PATH)
51+
message(FATAL_ERROR "KCONFIG_FILE_PATH is not defined")
52+
endif()
53+
54+
# Include the NuttX kconfig parser to shared the configuration between the NuttX
55+
# build and the Wasm build. And then parse the input KCONFIG_FILE_PATH to get
56+
# the configuration.
57+
include(${TOPDIR}/cmake/nuttx_kconfig.cmake)
58+
nuttx_export_kconfig(${KCONFIG_FILE_PATH})
59+
60+
# Provide FAR macro from command line since it is not supported in wasi-sdk, but
61+
# it is used in NuttX code.
62+
# ~~~
63+
# #define FAR
64+
# ~~~
65+
# It usually defined in nuttx/compiler.h.
66+
set(NUTTX_MACRO_FAR "")
67+
add_definitions(-DFAR=${NUTTX_MACRO_FAR})
68+
69+
# Fake nuttx_add_application to avoid error in the Wasm build process.
70+
function(nuttx_add_application)
71+
72+
endfunction()
73+
74+
# Fake nuttx_add_library to avoid error in the Wasm build process.
75+
function(nuttx_add_library)
76+
77+
endfunction()
78+
79+
# Recursively find all the CMakeLists.txt files in the ${APPDIR} and add it by
80+
# add_subdirectory, but exclude the CMakeLists.txt file in the ${APPDIR}/tools
81+
# directory.
82+
file(GLOB_RECURSE WASM_APPS ${APPDIR}/*/CMakeLists.txt)
83+
list(FILTER WASM_APPS EXCLUDE REGEX ".*/tools/.*")
84+
85+
# Read and check if wasm_add_application is called in the CMakeLists.txt file in
86+
# WASM_APPS If true, then add the directory to the build process
87+
foreach(WASM_APP ${WASM_APPS})
88+
file(READ ${WASM_APP} WASM_APP_CONTENTS)
89+
string(FIND "${WASM_APP_CONTENTS}" "wasm_add_application" WASM_APP_FOUND)
90+
string(FIND "${WASM_APP_CONTENTS}" "wasm_add_library" WASM_LIB_FOUND)
91+
if(WASM_APP_FOUND GREATER -1 OR WASM_LIB_FOUND GREATER -1)
92+
get_filename_component(WASM_APP_DIR ${WASM_APP} DIRECTORY)
93+
# Add subdirectory to the build process and put the build directory in the
94+
# current build directory with the name same as the relative path of the
95+
# ${APPDIR}
96+
string(REPLACE ${APPDIR} "" WASM_APP_BUILD_DIR ${WASM_APP_DIR})
97+
add_subdirectory(${WASM_APP_DIR}
98+
${CMAKE_CURRENT_BINARY_DIR}/Wasm/${WASM_APP_BUILD_DIR})
99+
endif()
100+
endforeach()

tools/Wasm/Kconfig

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#
2+
# For a description of the syntax of this configuration file,
3+
# see the file kconfig-language.txt in the NuttX tools repository.
4+
#

tools/Wasm/README.md

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Wasm build system in NuttX
2+
3+
## Overview
4+
5+
The files in this directory are used to build the Wasm module in NuttX:
6+
* CMakeLists.txt - The project configuration file for all Wasm targets
7+
* WASI-SDK.cmake - Provides the toolchain definition and utility functions for the Wasm build
8+
9+
Since the Wasm module is built with dedicated toolchain and flags, the main NuttX build system will treat the Wasm module as an external project, but share the same source tree and configuration (.config file).
10+
11+
## Design goals
12+
13+
* **Consistency**: The Wasm module can be built with the same build system as NuttX, and share the same source tree and configuration.
14+
* **Flexibility**: Can be built with CMake or Makefile, and can be integrated into the NuttX build system easily (until Makefile based build system is deprecated)
15+
* **Maintainability**: The Wasm module build system should be simple and less dependent on the NuttX build system.
16+
* **Portability**: The Wasm module can be built on any platform with CMake and WASI-SDK installed.
17+
18+
## Build process
19+
20+
Each Wasm target (such as examples/hello_wasm) will have its own CMakeLists.txt file, which will be included in the main CMakeLists.txt file in this directory.
21+
22+
Each target will have its own build directory (Wasm) inside the NuttX build directory, such as:
23+
```
24+
* apps
25+
* nuttx
26+
* cmake_build_dir
27+
* other NuttX native targets
28+
* Wasm
29+
* examples
30+
* hello_wasm
31+
* hello_wasm.wasm
32+
* other build files
33+
* benchmarks
34+
* coremark
35+
* coremark.wasm
36+
* netutils
37+
* cjson
38+
* libcJSON.a
39+
* libWasm.a
40+
* other build files
41+
```
42+
43+
Each target can be built with private source files, or shared source files with other targets. The shared source files will be built into a static global library (libWasm.a) or a custom library and linked to the Wasm targets.
44+
45+
Each target will be visible to other targets, so that the module level CMakelists.txt can define the dependencies between targets.
46+
47+
## Limitations
48+
49+
Now the Wasm module is targeted to wasm32-wasi, instead of legacy custom build with NuttX sysroot.
50+
So the source files should not call any NuttX APIs directly, and should not include any NuttX header files.
51+
It will limit the usage that some applications inside apps directory can not be built as Wasm targets directly.But still
52+
can be used for many POSIX compatible applications.

0 commit comments

Comments
 (0)