|  | # IREE "Static Library" sample | 
|  |  | 
|  | This sample shows how to: | 
|  | 1. Produce a static library and bytecode module with IREE's compiler | 
|  | 2. Compile the static library into a program using the `static_library_loader` | 
|  | 3. Run the demo with the module using functions exported by the static library | 
|  |  | 
|  | The model compiled into the static library exports a single function | 
|  | `simple_mul` that returns the multiplication of two tensors: | 
|  |  | 
|  | ```mlir | 
|  | func.func @simple_mul(%arg0: tensor<4xf32>, %arg1: tensor<4xf32>) -> tensor<4xf32> { | 
|  | %0 = "arith.mulf"(%arg0, %arg1) : (tensor<4xf32>, tensor<4xf32>) -> tensor<4xf32> | 
|  | return %0 : tensor<4xf32> | 
|  | } | 
|  | ``` | 
|  |  | 
|  | ## Background | 
|  |  | 
|  | IREE's `static_library_loader` allows applications to inject a set of static | 
|  | libraries that can be resolved at runtime by name. This can be particularly | 
|  | useful on "bare metal" or embedded systems running IREE that lack operating | 
|  | systems or the ability to load shared libraries in binaries. | 
|  |  | 
|  | When static library output is enabled, `iree-compile` produces a separate | 
|  | static library to compile into the target program. At runtime bytecode module | 
|  | instructs the VM which static libraries to load exported functions from the | 
|  | model. | 
|  |  | 
|  | ## Instructions | 
|  | _Note: run the following commands from IREE's github repo root._ | 
|  |  | 
|  | 1. Configure CMake for building the static library then demo. You'll need to set | 
|  | the flags building samples, the compiler, the `llvm-cpu` | 
|  | compiler target backend, and the `local-sync` runtime HAL driver (see | 
|  | [the getting started guide](https://iree.dev/building-from-source/getting-started/) | 
|  | for general instructions on building using CMake): | 
|  |  | 
|  | ```shell | 
|  | cmake -B ../iree-build/ -G Ninja \ | 
|  | -DCMAKE_BUILD_TYPE=RelWithDebInfo . | 
|  | -DIREE_BUILD_SAMPLES=ON \ | 
|  | -DIREE_TARGET_BACKEND_DEFAULTS=OFF \ | 
|  | -DIREE_TARGET_BACKEND_LLVM_CPU=ON \ | 
|  | -DIREE_HAL_DRIVER_DEFAULTS=OFF \ | 
|  | -DIREE_HAL_DRIVER_LOCAL_SYNC=ON \ | 
|  | -DIREE_HAL_EXECUTABLE_LOADER_DEFAULTS=OFF \ | 
|  | -DIREE_HAL_EXECUTABLE_PLUGIN_DEFAULTS=OFF \ | 
|  | -DIREE_BUILD_COMPILER=ON \ | 
|  | ``` | 
|  |  | 
|  | 2. Build the `static_library_demo` CMake target to create the static demo. This | 
|  | target has several dependencies that will compile `simple_mul.mlir` into a | 
|  | static library (`simple_mul.h` & `simple_mul.c`) as well as a bytecode module | 
|  | (`simple_mul.vmfb`) which are finally built into the demo binary: | 
|  |  | 
|  | ```shell | 
|  | cmake --build ../iree-build/ --target iree_samples_static_library_static_library_demo | 
|  | ``` | 
|  |  | 
|  | 3. Run the sample binary: | 
|  |  | 
|  | ```shell | 
|  | ../iree-build/samples/static_library/static_library_demo | 
|  |  | 
|  | # Output: static_library_run_bytecode passed | 
|  | ``` | 
|  |  | 
|  | ### Changing compilation options | 
|  |  | 
|  | The steps above build both the compiler for the host (machine doing the | 
|  | compiling) and the demo for the target using same options as the host machine. | 
|  | If you wish to target a different platform other than the host, you'll need to | 
|  | compile the library and demo with different options. | 
|  |  | 
|  | For example, see | 
|  | [this documentation](https://iree.dev/building-from-source/android/) | 
|  | on cross compiling on Android. | 
|  |  | 
|  | Note: separating the target from the host will require modifying dependencies in | 
|  | the demos `CMakeLists.txt`. See included comments for more info. |