Skip to content

Commit 8ad1b1b

Browse files
authored
Update plugin section - developer guide (#102)
* added plugin requirement Signed-off-by: Mahfuza <mhmohona@gmail.com> * updating front color in flowchart Signed-off-by: Mahfuza <mhmohona@gmail.com> * update the content Signed-off-by: Mahfuza <mhmohona@gmail.com> * updated choosing programming language Signed-off-by: Mahfuza <mhmohona@gmail.com> * updating side_bar position Signed-off-by: Mahfuza <mhmohona@gmail.com> * updated structure Signed-off-by: Mahfuza <mhmohona@gmail.com> * updating changes Signed-off-by: Mahfuza <mhmohona@gmail.com> * final update Signed-off-by: Mahfuza <mhmohona@gmail.com> * updating as per review Signed-off-by: Mahfuza <mhmohona@gmail.com> * rebase and fixed typo Signed-off-by: Mahfuza <mhmohona@gmail.com> * fix typo Signed-off-by: Mahfuza <mhmohona@gmail.com> * updating as per review Signed-off-by: Mahfuza <mhmohona@gmail.com> * update format Signed-off-by: Mahfuza <mhmohona@gmail.com> * added rust in intro Signed-off-by: Mahfuza <mhmohona@gmail.com> * update reference Signed-off-by: Mahfuza <mhmohona@gmail.com> * update Signed-off-by: Mahfuza <mhmohona@gmail.com> * update as per review Signed-off-by: Mahfuza <mhmohona@gmail.com> * Update intro.md Signed-off-by: Mahfuza <mhmohona@gmail.com> * fix typo Signed-off-by: Mahfuza <mhmohona@gmail.com> * Update docusaurus.config.js Signed-off-by: Mahfuza <mhmohona@gmail.com> --------- Signed-off-by: Mahfuza <mhmohona@gmail.com>
1 parent b69f8f5 commit 8ad1b1b

File tree

13 files changed

+2134
-764
lines changed

13 files changed

+2134
-764
lines changed

docs/contribute/plugin/_category_.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
"position": 3,
44
"link": {
55
"type": "generated-index",
6-
"description": "we will learn how to the WasmEdge Plugin System."
6+
"description": "We will learn how to develop the plug-ins for WasmEdge."
77
}
88
}

docs/contribute/plugin/develop_plugin_c.md

Lines changed: 185 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,62 @@ sidebar_position: 2
44

55
# Develop WasmEdge Plug-in in C API
66

7-
WasmEdge provides a C++ based API for registering extension modules and host functions. While the WasmEdge language SDKs allow registering host functions from a host (wrapping) application, the plugin API allows such extensions to be incorporated into WasmEdge's own building and releasing process.
7+
By developing a plug-in, one can extend the functionality of WasmEdge and customize it to suit specific needs. WasmEdge provides a C based API for registering extension modules and host functions. While the WasmEdge language SDKs allow registering host functions from a host (wrapping) application, the plug-in API allows such extensions to be incorporated into WasmEdge's building and releasing process. Here is a flowchart showing all the steps needed for developing WasmEdge Plug-in -
8+
9+
```mermaid
10+
graph LR;
11+
A[Developing WasmEdge Plug-in in C]
12+
A --> B(Set up the development environment)
13+
A --> C(Create a WasmEdge plug-in project)
14+
A --> D(Write the plug-in code)
15+
A --> E(Build the plug-in)
16+
A --> F(Test and debug the plug-in)
17+
B --> E
18+
C --> D
19+
D --> E
20+
```
21+
22+
This flowchart illustrates developing a WasmEdge plug-in, showcasing the steps from choosing a programming language to finalizing and releasing the plug-in.
23+
24+
## Set up the development environment
25+
26+
To start developing WasmEdge plug-ins, it is essential to correctly set up the development environment. This section provides step-by-step instructions for WasmEdge plug-in development -
27+
28+
**Install a WasmEdge runtime**: You can download the latest version of WasmEdge from [GitHub repository](https://github.com/wasmEdge/wasmEdge). Follow the instructions in the [installation guide](../../start/install.md) for your specific operating system.
829

9-
## Prerequisites
30+
After installing WasmEdge, you need to set up the build environment. If you're using Linux or other platforms, you can follow the instructions in the [build environment setup guide](../source/os/linux.md).
1031

11-
For developing the WasmEdge plug-in in C API, please [install WasmEdge](../../start/install.md#install) first.
32+
## Create a WasmEdge plug-in project
1233

13-
## Example
34+
To create a WasmEdge plug-in project, follow these steps:
1435

15-
Assume that the plug-in example is in the file `testplugin.c`.
36+
- **Set up the project directory**: Create a directory structure for your plug-in project. You can use a standard structure for the chosen language or create your structure. To create a project directory structure, use the following commands:
1637

17-
### Host Functions
38+
```bash
39+
mkdir testplugin
40+
cd testplugin
41+
mkdir src include build
42+
```
1843

19-
The goal of the plug-in is to provide the host functions which can be imported when instantiating WASM.
44+
- **Add configuration files**: Add configuration files specifying the plug-in name, version, and dependencies. The specific files and content depend on the chosen programming language and build system.
2045

21-
Therefore, developers can implement their plug-in host functions first, as the same as the [host functions in WasmEdge C API](../../embed/c/reference/latest.md#host-functions).
46+
- **Add any necessary libraries or dependencies**: Include any required libraries or dependencies for your plug-in. Modify the configuration files created in the previous step to include the required dependencies.
47+
48+
## Write the plug-in code
49+
50+
To create a plug-in with host functions and modules, follow these steps:
51+
52+
- **Implement host function definitions**: In this step, you must define the host functions that will be imported when instantiating the WASM module. These functions will perform specific operations and return results.
53+
54+
Therefore, developers can first implement their plug-in host functions, like the [host functions in WasmEdge C API](/embed/c/reference/latest.md#host-functions).
2255

2356
<!-- prettier-ignore -->
2457
:::note
25-
For the more details about the [external data](../../embed/c/host_function.md#host-data) and [calling frame context](../../embed/c/host_function.md#calling-frame-context), please refer to the host function guide.
58+
For more details about the [external data](/embed/c/host_function.md#host-data) and [calling frame context](/embed/c/host_function.md#calling-frame-context), please refer to the host function guide.
2659
:::
2760

61+
Here's an example of two host functions, `HostFuncAdd` and `HostFuncSub`, that add and subtract two `int32_t` numbers, respectively:
62+
2863
```c
2964
#include <wasmedge/wasmedge.h>
3065

@@ -51,152 +86,147 @@ WasmEdge_Result HostFuncSub(void *Data,
5186
}
5287
```
5388
54-
### Host Modules
89+
- **Implement the module creation functions**: In this step, you need to implement the module creation function that creates an instance of the module. This function will be called when the plug-in is loaded.
5590
56-
Then developers should implement the module creation functions.
91+
Here's an example of a module creation function named `CreateTestModule`:
5792
58-
Noticed that there can be several module instances in a plug-in shared library. Here take a module named as `wasmedge_plugintest_c_module` for the example.
59-
60-
```c
61-
/* The creation function of creating the module instance. */
62-
WasmEdge_ModuleInstanceContext *
63-
CreateTestModule(const struct WasmEdge_ModuleDescriptor *Desc) {
64-
/*
65-
* The `Desc` is the const pointer to the module descriptor struct:
66-
*
67-
* typedef struct WasmEdge_ModuleDescriptor {
68-
* const char *Name;
69-
* const char *Description;
70-
* WasmEdge_ModuleInstanceContext *(*Create)(
71-
* const struct WasmEdge_ModuleDescriptor *);
72-
* } WasmEdge_ModuleDescriptor;
73-
*
74-
* Developers can get the name and the description from this descriptor.
75-
*/
76-
77-
/* Exported module name of this module instance. */
78-
WasmEdge_String ModuleName =
79-
WasmEdge_StringCreateByCString("wasmedge_plugintest_c_module");
80-
WasmEdge_ModuleInstanceContext *Mod =
81-
WasmEdge_ModuleInstanceCreate(ModuleName);
82-
WasmEdge_StringDelete(ModuleName);
83-
84-
WasmEdge_String FuncName;
85-
WasmEdge_FunctionTypeContext *FType;
86-
WasmEdge_FunctionInstanceContext *FuncCxt;
87-
enum WasmEdge_ValType ParamTypes[2], ReturnTypes[1];
88-
ParamTypes[0] = WasmEdge_ValType_I32;
89-
ParamTypes[1] = WasmEdge_ValType_I32;
90-
ReturnTypes[0] = WasmEdge_ValType_I32;
91-
92-
/* Create and add the host function instances into the module instance. */
93-
FType = WasmEdge_FunctionTypeCreate(ParamTypes, 2, ReturnTypes, 1);
94-
FuncName = WasmEdge_StringCreateByCString("add");
95-
FuncCxt = WasmEdge_FunctionInstanceCreate(FType, HostFuncAdd, NULL, 0);
96-
WasmEdge_ModuleInstanceAddFunction(Mod, FuncName, FuncCxt);
97-
WasmEdge_StringDelete(FuncName);
98-
FuncName = WasmEdge_StringCreateByCString("sub");
99-
FuncCxt = WasmEdge_FunctionInstanceCreate(FType, HostFuncSub, NULL, 0);
100-
WasmEdge_ModuleInstanceAddFunction(Mod, FuncName, FuncCxt);
101-
WasmEdge_StringDelete(FuncName);
102-
WasmEdge_FunctionTypeDelete(FType);
103-
104-
return Mod;
105-
}
106-
```
107-
108-
### Plug-in Descriptions
109-
110-
For constructing the plug-in, developers should supply the descriptions of this plug-in and the modules.
111-
112-
```c
113-
/* The module descriptor array. There can be multiple modules in a plug-in. */
114-
static WasmEdge_ModuleDescriptor ModuleDesc[] = {{
93+
```c
94+
/* The creation function of creating the module instance. */
95+
WasmEdge_ModuleInstanceContext *
96+
CreateTestModule(const struct WasmEdge_ModuleDescriptor *Desc) {
11597
/*
116-
* Module name. This is the name for searching and creating the module
117-
* instance context by the `WasmEdge_PluginCreateModule()` API.
118-
*/
119-
.Name = "wasmedge_plugintest_c_module",
120-
/* Module description. */
121-
.Description = "This is for the plugin tests in WasmEdge C API.",
122-
/* Creation function pointer. */
123-
.Create = CreateTestModule,
124-
}};
125-
126-
/* The plug-in descriptor */
127-
static WasmEdge_PluginDescriptor Desc[] = {{
128-
/*
129-
* Plug-in name. This is the name for searching the plug-in context by the
130-
* `WasmEdge_PluginFind()` API.
131-
*/
132-
.Name = "wasmedge_plugintest_c",
133-
/* Plug-in description. */
134-
.Description = "",
135-
/* Plug-in API version. */
136-
.APIVersion = WasmEdge_Plugin_CurrentAPIVersion,
137-
/* Plug-in version. Developers can define the version of this plug-in. */
138-
.Version =
139-
{
140-
.Major = 0,
141-
.Minor = 1,
142-
.Patch = 0,
143-
.Build = 0,
144-
},
145-
/* Module count in this plug-in. */
146-
.ModuleCount = 1,
147-
/* Plug-in option description count in this plug-in (Work in progress). */
148-
.ProgramOptionCount = 0,
149-
/* Pointer to the module description array. */
150-
.ModuleDescriptions = ModuleDesc,
151-
/* Pointer to the plug-in option description array (Work in progress). */
152-
.ProgramOptions = NULL,
153-
}};
154-
```
155-
156-
### Plug-in Options
157-
158-
WORK IN PROGRESS. This section is reserved for the feature in the future.
159-
160-
### Implement the Get Descriptor API
161-
162-
The final step is to implement the `WasmEdge_Plugin_GetDescriptor()` API to return the plug-in descriptor.
163-
164-
```c
165-
WASMEDGE_CAPI_PLUGIN_EXPORT const WasmEdge_PluginDescriptor *
166-
WasmEdge_Plugin_GetDescriptor(void) {
167-
return &Desc;
168-
}
169-
```
170-
171-
## Build
172-
173-
To build the plug-in shared library, developers can choose to build stand-alone by the compiler or use cmake.
174-
175-
### Build with Command
176-
177-
```bash
178-
clang -shared -std=c11 -DWASMEDGE_PLUGIN testplugin.c -lwasmedge -o libwasmedgePluginTest.so
179-
```
180-
181-
### Build in CMake
182-
183-
```cmake
184-
add_library(wasmedgePluginTest
185-
SHARED
186-
testplugin.c
187-
)
188-
189-
set_target_properties(wasmedgePluginTest PROPERTIES
190-
C_STANDARD 11
191-
)
192-
193-
target_compile_options(wasmedgePluginTest
194-
PUBLIC
195-
-DWASMEDGE_PLUGIN
196-
)
197-
198-
target_link_libraries(wasmedgePluginTest
199-
PRIVATE
200-
wasmedge
201-
)
202-
```
98+
* The `Desc` is the const pointer to the module descriptor struct:
99+
*
100+
* typedef struct WasmEdge_ModuleDescriptor {
101+
* const char *Name;
102+
* const char *Description;
103+
* WasmEdge_ModuleInstanceContext *(*Create)(
104+
* const struct WasmEdge_ModuleDescriptor *);
105+
* } WasmEdge_ModuleDescriptor;
106+
*
107+
* Developers can get the name and description from this descriptor.
108+
*/
109+
110+
/* Exported module name of this module instance. */
111+
WasmEdge_String ModuleName =
112+
WasmEdge_StringCreateByCString("wasmedge_plugintest_c_module");
113+
WasmEdge_ModuleInstanceContext *Mod =
114+
WasmEdge_ModuleInstanceCreate(ModuleName);
115+
WasmEdge_StringDelete(ModuleName);
116+
117+
WasmEdge_String FuncName;
118+
WasmEdge_FunctionTypeContext *FType;
119+
WasmEdge_FunctionInstanceContext *FuncCxt;
120+
enum WasmEdge_ValType ParamTypes[2], ReturnTypes[1];
121+
ParamTypes[0] = WasmEdge_ValType_I32;
122+
ParamTypes[1] = WasmEdge_ValType_I32;
123+
ReturnTypes[0] = WasmEdge_ValType_I32;
124+
125+
/* Create and add the host function instances into the module instance. */
126+
FType = WasmEdge_FunctionTypeCreate(ParamTypes, 2, ReturnTypes, 1);
127+
FuncName = WasmEdge_StringCreateByCString("add");
128+
FuncCxt = WasmEdge_FunctionInstanceCreate(FType, HostFuncAdd, NULL, 0);
129+
WasmEdge_ModuleInstanceAddFunction(Mod, FuncName, FuncCxt);
130+
WasmEdge_StringDelete(FuncName);
131+
FuncName = WasmEdge_StringCreateByCString("sub");
132+
FuncCxt = WasmEdge_FunctionInstanceCreate(FType, HostFuncSub, NULL, 0);
133+
WasmEdge_ModuleInstanceAddFunction(Mod, FuncName, FuncCxt);
134+
WasmEdge_StringDelete(FuncName);
135+
WasmEdge_FunctionTypeDelete(FType);
136+
137+
return Mod;
138+
}
139+
```
140+
141+
There can be several module instances in a plug-in shared library. Here in the above code snippet, take a module named `wasmedge_plugintest_c_module` for the example.
142+
143+
- **Supply the plug-in descriptions**- In this step, you need to provide the descriptions of the plug-in and the modules it contains. These descriptions will be used for searching and creating the plug-in and module instances.
144+
145+
Here's an example of the plug-in and module descriptors:
146+
147+
```c
148+
/* The module descriptor array. There can be multiple modules in a plug-in. */
149+
static WasmEdge_ModuleDescriptor ModuleDesc[] = {{
150+
/*
151+
* Module name. This is the name for searching and creating the module
152+
* instance context by the `WasmEdge_PluginCreateModule()` API.
153+
*/
154+
.Name = "wasmedge_plugintest_c_module",
155+
/* Module description. */
156+
.Description = "This is for the plugin tests in WasmEdge C API.",
157+
/* Creation function pointer. */
158+
.Create = CreateTestModule,
159+
}};
160+
161+
/* The plug-in descriptor */
162+
static WasmEdge_PluginDescriptor Desc[] = {{
163+
/*
164+
* Plug-in name. This is the name for searching the plug-in context by the
165+
* `WasmEdge_PluginFind()` API.
166+
*/
167+
.Name = "wasmedge_plugintest_c",
168+
/* Plug-in description. */
169+
.Description = "",
170+
/* Plug-in API version. */
171+
.APIVersion = WasmEdge_Plugin_CurrentAPIVersion,
172+
/* Plug-in version. Developers can define the version of this plug-in. */
173+
.Version =
174+
{
175+
.Major = 0,
176+
.Minor = 1,
177+
.Patch = 0,
178+
.Build = 0,
179+
},
180+
/* Module count in this plug-in. */
181+
.ModuleCount = 1,
182+
/* Plug-in option description count in this plug-in (Work in progress). */
183+
.ProgramOptionCount = 0,
184+
/* Pointer to the module description array. */
185+
.ModuleDescriptions = ModuleDesc,
186+
/* Pointer to the plug-in option description array (Work in progress). */
187+
.ProgramOptions = NULL,
188+
}};
189+
```
190+
191+
These descriptions define the name, description, version, and creation function of the plug-in and the name and description of the module it contains.
192+
193+
Remember to implement any additional functions or structures your plug-in requires to fulfill its functionality.
194+
195+
Following these steps and implementing the necessary functions and descriptors, you can create a plug-in with host functions and modules in WasmEdge C API. You can continue developing your plug-in by adding functionality and implementing the desired behavior.
196+
197+
- **Plug-in option** - _WORK IN PROGRESS. This section is reserved for the feature in the future._
198+
199+
## Build your plug-in
200+
201+
To build the WasmEdge plug-in shared library, you have two options: build it directly using the compiler or CMake. Here are the instructions for both methods:
202+
203+
- **Build with Command**: if you choose to build the plug-in using the command line, run the following command in the terminal:
204+
205+
This command compiles the `testplugin.c` file into a shared library named `libwasmedgePluginTest.so`. The `-std=c11` flag sets the C language standard to C11, and the `-DWASMEDGE_PLUGIN` flag defines the WASMEDGE_PLUGIN macro, which can be used in your code.
206+
207+
- **Build with CMake**: If you prefer to use CMake to build the plug-in, create a `CMakeLists.txt` file in the root directory of your project and add the following content to the CMakeLists.txt file:
208+
209+
```cmake
210+
add_library(wasmedgePluginTest
211+
SHARED
212+
testplugin.c
213+
)
214+
215+
set_target_properties(wasmedgePluginTest PROPERTIES
216+
C_STANDARD 11
217+
)
218+
219+
target_compile_options(wasmedgePluginTest
220+
PUBLIC
221+
-DWASMEDGE_PLUGIN
222+
)
223+
224+
target_link_libraries(wasmedgePluginTest
225+
PRIVATE
226+
wasmedge
227+
)
228+
```
229+
230+
This CMake configuration sets up a build target called `wasmedgePluginTest`. It compiles the `testplugin.c` file into a shared library. The `C_STANDARD 11` property sets the C language standard to C11. The `target_compile_options` command defines the `WASMEDGE_PLUGIN` macro using the `-DWASMEDGE_PLUGIN` flag. Finally, the `target_link_libraries` command links the wasmedge library to the plug-in.
231+
232+
Once you have set up either the command-line build or the CMake build, you can execute the corresponding build command or generate build files using CMake, which will compile your plug-in source code and produce the shared library file `(libwasmedgePluginTest.so)`.

0 commit comments

Comments
 (0)