It is allowed that one WASM module can *import**functions*, *globals*, *memories* and *tables* from other modules as its dependencies, and also one module can *export* those entities for other modules to *access* and may *write*.
WAMR loads all dependencies recursively according to the *import section* of a module.
> Currently WAMR only implements the load-time dynamic linking. Please refer to [dynamic linking](https://webassembly.org/docs/dynamic-linking/) for more details.
It is used to register a *module* with a *module_name* to WASM runtime, especially for the root module, which is loaded by `wasm_runtime_load()` and doesn't have a chance to tell runtime its *module name*.
Fot all the sub modules, WAMR will get their names and load the .wasm files from the filesystem or stream, so no need to register the sub modules again.
### Find a registered module
``` c
wasm_module_t
wasm_runtime_find_module_registered(
const char *module_name);
```
It is used to check if a module with a given *module_name* has been registered, if yes return the module.
WAMR hopes that the native host or embedding environment loads/unloads the module WASM files by themselves and only passes runtime the binary content without worrying filesystem or storage issues. `module_reader` and `module_destroyer` are two callbacks called when dynamic-loading/unloading the sub modules. Developers must implement the two callbacks by themselves.
Multi-module allows to lookup the function of sub module and call it. There are two ways to indicate the function *name*:
- parent function name only by default, used to lookup the function of parent module
- sub module name, function name of sub module and two $ symbols, e.g. `$sub_module_name$function_name`, used to lookup function of sub module
## Example
### WASM modules
Suppose we have three C files, *mA.c*, *mB.c* and *mC.c*. Each of them has some exported functions and import some from others except mA.
Undefined symbols can be marked in the source code with the *import_name* clang attribute which means that they are expected to be undefined at static link time. Without the *import_module* clang attribute, undefined symbols will be marked from the *env* module.
``` C
// mA.c
int A() { return 10; }
```
``` C
// mB.c
__attribute__((import_module("mA"))) __attribute__((import_name("A"))) extern int A();
int B() { return 11; }
int call_A() { return A(); }
```
``` C
// mC.c
__attribute__((import_module("mA"))) __attribute__((import_name("A"))) extern int A();
__attribute__((import_module("mB"))) __attribute__((import_name("B"))) extern int B();
int C() { return 12; }
int call_A() { return A(); }
int call_B() { return B(); }
```
By default no undefined symbols are allowed in the final binary. The flag *--allow-undefined* results in a WebAssembly import being defined for each undefined symbol. It is then up to the runtime to provide such symbols.
When building an executable, only the entry point (_start) and symbols with the *export_name* attribute exported by default. in addition, symbols can be exported via the linker command line using *--export*.
In the example, another linked command option *--export-all* is used.