re-org platform APIs, simplify porting process (#201)
Co-authored-by: Xu Jun <jun1.xu@intel.com>
This commit is contained in:
@ -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/0:build 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
|
||||
|
||||
@ -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.
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user