You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add sample usage: how to use pre-built WAMR library in user mode (#4908)
As an alternative way to compile WAMR directly into the Zephyr app, given a compiled WAMR library, demonstrate how to integrate such a pre-built library into the Zephyr app and use it in user mode.
Copy file name to clipboardExpand all lines: product-mini/platforms/zephyr/user-mode/README.md
+135-3Lines changed: 135 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -45,16 +45,148 @@ When creating a Zephyr thread, set the thread option to `K_USER` and the timeout
45
45
46
46
In a user-mode Zephyr thread, the application can only access a restricted partition of memory it granted to. It creates a sandbox for the WAMR runtime to run in, and the WAMR runtime can only access that memory space, meaning that all global variables in the WAMR runtime and both runtime and wasm app heap memory will be allocated from it. In this way, an extra layer of security is added to the wasm application on top of the wasm sandbox provided by WAMR.
47
47
48
+
### Using a pre-built WAMR library in user mode
49
+
50
+
If the WAMR library is pre-built as a static archive (`.a` file) rather than
51
+
compiled inline via `add_subdirectory`, the library's global variables still
52
+
need to be placed into the `app_smem` section so they are accessible from the
53
+
user-mode thread. This is useful when you want to treat the WAMR runtime as a
54
+
binary dependency copied from an external build.
55
+
56
+
#### How `zephyr_library_app_memory` works internally
57
+
58
+
`zephyr_library_app_memory(partition)` is a thin wrapper that appends metadata
59
+
to a CMake target property:
60
+
61
+
```cmake
62
+
# zephyr/cmake/modules/extensions.cmake
63
+
set_property(TARGET zephyr_property_target
64
+
APPEND PROPERTY COMPILE_OPTIONS
65
+
"-l" <library_filename> "<partition_name>")
66
+
```
67
+
68
+
Zephyr's build system passes this metadata as `-l libname.a partition` arguments
69
+
to `gen_app_partitions.py`, which generates a linker script fragment with
70
+
wildcard patterns that collect the library's `.data` and `.bss` sections into
71
+
the named partition:
72
+
73
+
```ld
74
+
"*libwamr_lib.a:*"(.data .data.* .sdata .sdata.*)
75
+
"*libwamr_lib.a:*"(.bss .bss.* .sbss .sbss.* COMMON COMMON.*)
76
+
```
77
+
78
+
#### Using the built-in `WAMR_USE_PREBUILT_LIB` option
79
+
80
+
This sample's CMakeLists.txt supports a `WAMR_USE_PREBUILT_LIB` option. When
81
+
enabled, the library is still compiled from source under `lib-wamr-zephyr/`,
82
+
but partition registration bypasses `zephyr_library_app_memory()` and uses the
83
+
manual `set_property()` approach instead. This demonstrates the same integration
84
+
path you would use with an externally built `.a` file.
85
+
86
+
Build from source with `zephyr_library_app_memory` (default):
87
+
88
+
```shell
89
+
west build -b qemu_x86 . -p always
90
+
```
91
+
92
+
Build from source with pre-built library partition registration:
93
+
94
+
```shell
95
+
west build -b qemu_x86 . -p always -- -DWAMR_USE_PREBUILT_LIB=1
96
+
```
97
+
98
+
The application code (`main.c`) is unchanged in both cases — define the
99
+
partition with `K_APPMEM_PARTITION_DEFINE(wamr_partition)`, set up the memory
100
+
domain, and create a user-mode thread as usual.
101
+
102
+
#### Applying this to your own project
103
+
104
+
To use a pre-built WAMR library in a standalone Zephyr application, add the
105
+
following to your CMakeLists.txt:
106
+
107
+
```cmake
108
+
# Import the pre-built library
109
+
add_library(wamr_lib STATIC IMPORTED GLOBAL)
110
+
set_target_properties(wamr_lib PROPERTIES
111
+
IMPORTED_LOCATION /path/to/libwamr_lib.a
112
+
)
113
+
114
+
# Tell gen_app_partitions.py to place this library's globals into wamr_partition.
115
+
# This replicates what zephyr_library_app_memory(wamr_partition) does for
116
+
# libraries built through zephyr_library_named().
117
+
set_property(TARGET zephyr_property_target
118
+
APPEND PROPERTY COMPILE_OPTIONS
119
+
"-l" "libwamr_lib.a" "wamr_partition")
120
+
121
+
# Link it to the app
122
+
target_link_libraries(app PRIVATE wamr_lib)
123
+
```
124
+
125
+
#### Notes
126
+
127
+
- The library filename in the `-l` argument must match the archive filename
128
+
that the linker sees (e.g. `libwamr_lib.a`).
129
+
- The pre-built library must be compiled with the same Zephyr toolchain and
130
+
flags (architecture, sysroot, etc.) as the application.
131
+
- For Zephyr 4.x, if building the library inline via `add_subdirectory`, add
132
+
`add_dependencies(wamr_lib zephyr_generated_headers)` to avoid build race
133
+
conditions with generated headers like `heap_constants.h`.
134
+
48
135
### Example Targets
49
136
50
-
x86_64 QEMU (x86_64) is a 64-bit x86 target for emulating the x86_64 platform.
137
+
#### qemu_x86 (Zephyr 4.x with Zephyr SDK 1.0+)
138
+
139
+
Build for the `qemu_x86` board (32-bit x86, the default `WAMR_BUILD_TARGET`):
140
+
141
+
```shell
142
+
west build -b qemu_x86 . -p always
143
+
```
144
+
145
+
To use the pre-built library approach instead:
146
+
147
+
```shell
148
+
west build -b qemu_x86 . -p always -- -DWAMR_USE_PREBUILT_LIB=1
149
+
```
150
+
151
+
Run on QEMU using `west`:
152
+
153
+
```shell
154
+
west build -t run
155
+
```
156
+
157
+
> Press `CTRL+a, x` to exit QEMU.
158
+
159
+
Expected output:
160
+
161
+
```
162
+
*** Booting Zephyr OS build v4.4.0-rc2 ***
163
+
wamr_partition start addr: 1257472, size: 45056
164
+
User mode thread: start
165
+
Hello world!
166
+
buf ptr: 0x1458
167
+
buf: 1234
168
+
User mode thread: elapsed 10
169
+
```
170
+
171
+
> Note: The boot message order may vary. `wamr_partition` size should be around
172
+
> 45056 bytes (40 KB global heap + other library globals).
173
+
174
+
#### qemu_x86_tiny (older Zephyr / manual QEMU)
175
+
176
+
Build for the `qemu_x86_tiny` board:
51
177
52
178
```shell
53
179
west build -b qemu_x86_tiny . -p always -- -DWAMR_BUILD_TARGET=X86_32
0 commit comments