Build System Optimization
This guide is a deep dive into how to configure and optimize your CMakeLists.txt or Makefile when building WebAssembly (WASM) applications for the Wasm Micro Runtime (WAMR) — a pre-requisite for building Atym containers. It covers everything from crafting minimal and flexible CMake configurations, to leveraging linker flags that reduce size or change runtime behavior, to trimming your final binary's footprint for embedded or resource-constrained environments.
CMake Setup
The following CMakeLists.txt file provides a minimal, flexible starting point for WAMR apps using the WASI SDK toolchain.
Required Elements
These are mandatory for compiling a WASM binary:
cmake_minimum_required(VERSION 3.20.0)
# WASI SDK toolchain required for targeting WebAssembly
set(CMAKE_TOOLCHAIN_FILE /opt/wasi-sdk/share/cmake/wasi-sdk-p1.cmake)
# Project declaration
set(APPNAME your-project)
project(${APPNAME})
# Entry point / app source
add_executable(${APPNAME}.wasm main.c)
Optional Enhancements
These additions help reduce binary size and improve debug experience:
# Strip symbols, allow undefined symbols at link time
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--strip-all -Wl,--allow-undefined")
# Additional compiler flags
add_compile_options(
-O3 # Optimize for speed
-Wall -Wextra # Enable common warnings
-Wno-unused-parameter # Suppress warnings from common patterns
-Wno-unknown-attributes # Silence WASI SDK-specific flags
)
Linker Flags
WAMR supports a wide range of linker flags that impact the size, safety, and behavior of your app. Use these selectively based on your app's needs:
| Flag | Description |
|---|---|
-nostdlib | Avoids standard system libraries—use with libc-builtin or libc-wasi. |
--no-entry | Do not generate _start entry point. Useful for module-only WASM apps. |
--export=<symbol> | Export a specific function or global (e.g., main, __heap_base). |
--export-all | Export all symbols (can increase size). |
--initial-memory=<n> | Initial linear memory size in bytes (must be multiple of 64KB). |
--max-memory=<n> | Maximum allowed linear memory. |
-z stack-size=<n> | Set auxiliary stack size (e.g., 8192). |
--strip-all | Strip all symbols for minimal size. |
--shared-memory | Enable shared memory features (advanced). |
--allow-undefined | Allow undefined symbols at link time. |
--allow-undefined-file=<file> | Allow specific undefined symbols listed in a file. |
-pthread | Enable pthread support if needed. |
See the wasi-sdk options section in the WAMR Readme for more details.
Reducing Application Footprint
Reducing footprint is especially important for embedded deployments. WAMR provides multiple paths to achieve smaller binaries while maintaining functionality.
- Use
-O3for optimization and--strip-allto remove symbols. - Avoid unused code using:
-ffunction-sections -fdata-sections -Wl,--gc-sections - Export only required symbols:
-Wl,--export=main -Wl,--export=__heap_base -Wl,--export=__data_end
See the How to reduce the footprint section in the WAMR Readme for more details.
Next Steps
Now that your build is optimized, you may want to check out the Advanced Project Configuration page to learn how to package your WASM binary with a build.yaml file, set permissions, and define your container's runtime behavior.