re-org platform APIs, simplify porting process (#201)

Co-authored-by: Xu Jun <jun1.xu@intel.com>
This commit is contained in:
Xu Jun
2020-03-16 16:43:57 +08:00
committed by GitHub
parent ef5ceffe71
commit f1a0e75ab7
177 changed files with 2954 additions and 7904 deletions

View File

@ -1,64 +1,82 @@
Build WAMR core (iwasm)
=========================
It is recommended to use the [WAMR SDK](../wamr-sdk) tools to build a project that embedes the WAMR. This document introduces how to build the WAMR minimal product which is vmcore only (no app-framework and app-mgr) for multiple platforms.
It is recommended to use the [WAMR SDK](../wamr-sdk) tools to build a project that integrates the WAMR. This document introduces how to build the WAMR minimal product which is vmcore only (no app-framework and app-mgr) for multiple platforms.
## iwasm VM core CMake building configurations
By including the cmake scripts under folder [build-scripts](../build-scripts), it is easy to build minimal product with CMake. WAMR provides a number of features which can be easily configured through cmake variables:
By including the script `runtime_lib.cmake` under folder [build-scripts](../build-scripts) in CMakeList.txt, it is easy to build minimal product with CMake.
``` Bash
cmake -DWAMR_BUILD_INTERP=1/0 to enable or disable WASM intepreter
cmake -DWAMR_BUILD_FAST_INTERP=1/0 to build fast (default) or classic WASM intepreter.
cmake -DWAMR_BUILD_AOT=1/0 to enable or disable WASM AOT
cmake -DWAMR_BUILD_JIT=1/0 to enable or disable WASM JIT. (Disabled by default)
cmake -DWAMR_BUILD_LIBC_BUILTIN=1/0 enable or disable Libc builtin API's. (Enabled by default)
cmake -DWAMR_BUILD_LIBC_WASI=1/0 enable or disable Libc WASI API's
cmake -DWAMR_BUILD_TARGET=<arch> to set the building target, including:
X86_64, X86_32, ARM, THUMB, XTENSA and MIPS
For ARM and THUMB, the format is <arch>[<sub-arch>][_VFP] where <sub-arch> is the ARM sub-architecture and the "_VFP" suffix means VFP coprocessor registers s0-s15 (d0-d7) are used for passing arguments or returning results in standard procedure-call. Both <sub-arch> and [_VFP] are optional. e.g. ARMV7, ARMV7_VFP, THUMBV7, THUMBV7_VFP and so on.
```cmake
# add this in your CMakeList.text
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
```
For example, if we want to enable classic interpreter, we can:
The script `runtime_lib.cmake` defined a number of variables for configuring the WAMR runtime features. You can set these variables in your CMakeList.txt or pass the configurations from cmake command line.
#### **Configure platform and architecture**
- **WAMR_BUILD_PLATFORM**: set the target platform. It can be set to any platform name (folder name) under folder [core/shared/platform](../core/shared/platform).
- **WAMR_BUILD_TARGET**: set the target CPU architecture. Current supported targets: X86_64, X86_32, ARM, THUMB, XTENSA and MIPS. For ARM and THUMB, the format is <arch>[<sub-arch>][_VFP] where <sub-arch> is the ARM sub-architecture and the "_VFP" suffix means VFP coprocessor registers s0-s15 (d0-d7) are used for passing arguments or returning results in standard procedure-call. Both <sub-arch> and [_VFP] are optional. e.g. ARMV7, ARMV7_VFP, THUMBV7, THUMBV7_VFP and so on.
```bash
cmake -DWAMR_BUILD_PLATFORM=linux -DWAMR_BUILD_TARGET=ARM
```
#### **Configure interpreter**
- **WAMR_BUILD_INTERP**=1/0: enable or disable WASM interpreter
- **WAMR_BUILD_FAST_INTERP**=1/0build fast (default) or classic WASM interpreter.
NOTE: the fast interpreter will run ~2X faster than classic interpreter, but it consumes about 2X memory to hold the WASM bytecode code.
#### **Configure AoT and JIT**
- **WAMR_BUILD_AOT**=1/0
- **WAMR_BUILD_JIT**=1/0 , (Disabled if no set)
#### **Configure LIBC**
- **WAMR_BUILD_LIBC_BUILTIN**=1/0, default to enable if no set
- **WAMR_BUILD_LIBC_WASI**=1/0, default to disable if no set
**Combination of configurations:**
We can combine the configurations. For example, if we want to disable interpreter, enable AOT and WASI, we can run command:
``` Bash
cmake .. -DWAMR_BUILD_FAST_INTERP=0
cmake .. -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_AOT=1 -DWAMR_BUILD_LIBC_WASI=0 -DWAMR_BUILD_PLATFORM=linux
```
**Note** the fast interpreter will run ~2X faster than classic interpreter, but it consumes about 2X memory to hold the WASM bytecode code.
If we want to disable interpreter, enable AOT and WASI, we can:
``` Bash
cmake .. -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_AOT=1 -DWAMR_BUILD_LIBC_WASI=0
```
Or if we want to enable inerpreter, disable AOT and WASI, and build as X86_32, we can:
Or if we want to enable interpreter, disable AOT and WASI, and build as X86_32, we can run command:
``` Bash
cmake .. -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_AOT=0 -DWAMR_BUILD_LIBC_WASI=0 -DWAMR_BUILD_TARGET=X86_32
```
By default in Linux, the interpreter, AOT and WASI are enabled, and JIT is disabled. And the build target is
set to X86_64 or X86_32 depending on the platform's bitwidth.
To enable WASM JIT, firstly we should build LLVM:
``` Bash
cd product-mini/platforms/linux/
./build_llvm.sh (The llvm source code is cloned under <wamr_root_dir>/core/deps/llvm and auto built)
## Cross compilation
If you are building for ARM architecture on a X86 development machine, you can use the `CMAKE_TOOLCHAIN_FILE` to set the toolchain file for cross compling.
```
cmake .. -DCMAKE_TOOLCHAIN_FILE=$TOOL_CHAIN_FILE \
-DWAMR_BUILD_PLATFORM=linux \
-DWAMR_BUILD_TARGET=ARM
```
Then pass option -DWAMR_BUILD_JIT=1 to cmake to enable WASM JIT:
``` Bash
mkdir build
cd build
cmake .. -DWAMR_BUILD_JIT=1
make
```
Refer to toochain sample file [`samples/simple/profiles/arm-interp/toolchain.cmake`](../samples/simple/profiles/arm-interp/toolchain.cmake) for how to build mini product for ARM target architecture.
@ -87,9 +105,26 @@ cd build
cmake ..
make
```
The binary file iwasm will be generated under build folder.
By default in Linux, the interpreter, AOT and WASI are enabled, and JIT is disabled. And the build target is
set to X86_64 or X86_32 depending on the platform's bitwidth.
To enable WASM JIT, firstly we should build LLVM:
``` Bash
cd product-mini/platforms/linux/
./build_llvm.sh (The llvm source code is cloned under <wamr_root_dir>/core/deps/llvm and auto built)
```
Then pass argument `-DWAMR_BUILD_JIT=1` to cmake to enable WASM JIT:
``` Bash
mkdir build
cd build
cmake .. -DWAMR_BUILD_JIT=1
make
```
@ -231,19 +266,21 @@ AliOS-Things
$(NAME)_COMPONENTS := osal_aos iwasm
```
7. build source code and run
For linuxhost:
For linux host:
``` Bash
aos make helloworld@linuxhost -c config
aos make
./out/helloworld@linuxhost/binary/helloworld@linuxhost.elf
```
```
For developerkit:
Modify file middleware/iwasm/aos.mk, patch as:
``` C
WAMR_BUILD_TARGET := THUMBV7M
WAMR_BUILD_TARGET := THUMBV7M
```
``` Bash
aos make helloworld@developerkit -c config
aos make

View File

@ -7,40 +7,60 @@ This document describes how to port WAMR to a new platform "**super-os**"
# Step 1: Create folders for the new platform
# Step 1: Implement platform API layer
-------------------------
Create folders:
- **core/shared/platform/super-os**: for platform API layer implementations
- **product-mini/platforms/super-os**: for the platform mini product build
Firstly create the folder **`core/shared/platform/super-os`** for platform API layer implementations. In the folder you just created, you must provide the following files:
# Step 2: Implement platform API layer
- `platform_internal.h`: It can be used for any platform specific definitions such as macros, data types and internal APIs.
- `shared_platform.cmake`: the cmake file will be included by the building script. It is recommended to add a definition for your platform:
- ```cmake
add_definitions(-DBH_PLATFORM_YOUR_NAME)
```
Then go to implement the APIs defined in following header files for the platform abstraction layer:
- [`platform_api_vmcore.h`](../core/shared/platform/include/platform_api_vmcore.h): mandatory for building mini-product (vmcore only). Part of APIs are needed only for Ahead of Time compilation support.
- [`platform_api_extension.h`](../core/shared/platform/include/platform_api_extension.h): mandatory for app-mgr and app-framework. Given that the app-mgr and app-framework are not required for your target platform, you won't have to implement the API defined in the `platform_api_extension.h`.
**common/posix:**
There is posix based implementation of the platform API located in the `platform/common/posix` folder. You can include it if your platform support posix API. refer to platform linux implementation.
**common/math:**
Some platforms such as ZephyrOS don't provide math functions e.g. sqrt, fabs and isnan, then you should include source files under the folder `platform/common/math`.
# Step 2: Create the mini product for the platform
-------------------------
Implement folder core/shared/platform/super-os. Normally in this folder you should implement the following files:
- bh_platform.h and bh_platform.c: define the platform related macros, data types and APIs.
- bh_assert.c: implement function bh_assert_internal() and bh_debug_internal().
- bh_platform_log.c: implement function bh_log_emit, bh_fprintf and bh_fflush.
- bh_time.c: implement several time related functions.
- bh_thread.c: implement thread, mutex, condition related functions.
- bh_math.c: implement some math functions if the platform doesn't support them, e.g. sqrt,
fabs and isnan. We may use the open source fdlibm implementation, for example,
ref to platform/zephyr/bh_math.c.
You can build a mini WAMR product which is only the vmcore for you platform. Normally you need to implement the main function which loads a WASM file and run it with the WASM runtime. You don't have to do this step if there is no such need for your platform.
Please ref to implementation of other platform for more details, e.g. platform/zephyr, platform/linux.
# Step 3: Create the mini product build for the platform
-------------------------
Implement folder product-mini/platforms/super-os. Normally this folder is to implement the C main function, and generate a WAMR VM core binary named iwasm which can load and run wasm apps. We should implement following files:
- main.c: implement the C main function, which reads wasm file to buffer, loads the wasm file to wasm module, instantiate the module, lookup wasm app main function, and then execute the function.
- ext_lib_export.c: implement the native APIs if you want, and if no native API is to be implemented, just keep array extended_native_symbol_defs empty.
- CMakeLists.txt: there are some settings which can be passed from cmake variables:
- set (WAMR_BUILD_PLATFORM "platform_name"): set the name of the platform
- set (WAMR_BUILD_TARGET <arch><sub>): set the build target, currently the value supported: X86_64, X86_32, ARM[sub], THUMB[sub], MIPS and XTENSA. For ARM and THUMB, you can specify the sub version, e.g. ARMV4, ARMV7, THUMBV4T, THUMBV7T.
- set (WAMR_BUILD_INTERP 1 or 0): whether to interpreter or not
- set (WAMR_BUILD_AOT 1 or 0): whether to build AOT or not
- set (WAMR_BUILD_JIT 1 or 0): whether to build JIT or not
- set (WAMR_BUILD_LIBC_BUILTIN 1 or 0): whether to build Libc builtin or not
- set (WAMR_BUILD_LIBC_WASI 1 or 0): whether to build Libc WASI or not
Firstly create folder **product-mini/platforms/super-os** for the platform mini product build, then refer to the linux platform mini-product for creating the CMakeList.txt and the C implementations.
You should set cmake variable `WAMR_BUILD_PLATFORM` to your platform name while building the mini product. It can be done in the mini product CMakeList.txt file, or pass arguments to cmake command line like:
```
mkdir build
cd build
cmake .. -DWAMR_BUILD_PLATFORM=new-os
```
Refer to [build_wamr.md](./build_wamr.md) for the building configurations and parameters.