Skip to main content
Version: old

WASM Root Orchestrator - CMake Build System

This file serves as the root CMake build orchestrator for all WebAssembly (WASM) modules in the Img2Num project.
It provides a cross-platform alternative to traditional Makefiles and integrates seamlessly with Emscripten for compiling C++ code to WASM.

It was introduced in PR #93.

Key Features

  • Cross-platform: Works on Windows, macOS, and Linux with Emscripten.
  • Automatic module discovery: Detects and adds any submodule with its own CMakeLists.txt.
  • Standardized build configuration: Defaults to C++17 and Release mode.
  • Emscripten integration: Ensures the build system is executed with Emscripten (emcmake).

Configuration

cmake_minimum_required(VERSION 3.16)
project(Img2NumWASM LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
  • cmake_minimum_required(VERSION 3.16) ensures a modern CMake version.
  • project(Img2NumWASM LANGUAGES CXX) declares the project and specifies C++ as the language.
  • CMAKE_CXX_STANDARD 17 ensures all modules are compiled with C++17.
  • CMAKE_CXX_STANDARD_REQUIRED ON enforces the C++17 standard strictly.

Emscripten Check

if(NOT EMSCRIPTEN)
message(FATAL_ERROR
"This project must be built with Emscripten.\n"
"Use: emcmake cmake .. && cmake --build .\n"
"See docs for installation: https://emscripten.org/docs/getting_started/"
)
endif()
  • Ensures the project is built with Emscripten.
  • If not, it exits with a fatal error and provides instructions to the developer.
  • Helps prevent accidental builds with incompatible toolchains.

Build Type

if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
endif()

message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "Emscripten: ${EMSCRIPTEN_ROOT_PATH}")
  • Defaults the build type to Release if not explicitly set.
  • Prints the build type and Emscripten root path for developer visibility.
  • Ensures consistent optimization levels across all modules.

Automatic Module Discovery

file(GLOB MODULE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/modules/*")
foreach(MODULE_DIR ${MODULE_DIRS})
if(IS_DIRECTORY ${MODULE_DIR} AND EXISTS "${MODULE_DIR}/CMakeLists.txt")
get_filename_component(MODULE_NAME ${MODULE_DIR} NAME)
message(STATUS "Adding module: ${MODULE_NAME}")
add_subdirectory(${MODULE_DIR})
endif()
endforeach()
  • file(GLOB MODULE_DIRS ...) lists all directories inside modules/.
  • Checks each directory to see if it contains a CMakeLists.txt.
  • If found, adds it as a subdirectory, effectively including the module in the build.
  • Prints a status message for each module added.

This allows plug-and-play addition of new WASM modules: Just create a new folder under modules/ with its own CMakeLists.txt, and the root orchestrator automatically includes it.

Usage

Development Build

emcmake cmake ..
cmake --build .
  • emcmake ensures the proper Emscripten environment is used.
  • cmake --build . compiles all modules to WASM.

Production Integration

  • The resulting WASM files are placed in each module’s build folder.
  • The Vite configuration automatically discovers these using aliases like @wasm-{module}.

Summary

This CMake root orchestrator provides a scalable and maintainable system for building all WASM modules in Img2Num:

  • Enforces C++17 standard.
  • Requires Emscripten.
  • Defaults to Release builds.
  • Automatically discovers modules.
  • Integrates smoothly with the Vite WASM workflow.

It eliminates manual Makefile management and allows contributors to add new modules effortlessly.

WASM Build Flow (CMake → Vite Integration)

The diagram below illustrates how the root CMake orchestrator builds WASM modules and integrates with Vite for both development and production environments.

note

This diagram shows the full end-to-end WASM build flow from CMake to Vite and how development vs production builds differ.

Explanation of Flow:

  1. Start: Run emcmake cmake .. to initialize Emscripten environment.
  2. Root CMakeLists.txt: Sets build configuration, ensures C++17 and Release mode.
  3. Emscripten Check: Fails immediately if Emscripten is not installed.
  4. Module Discovery: Automatically finds modules in modules/ folder with CMakeLists.txt.
  5. Compilation: Each module is added via add_subdirectory and compiled to WASM.
  6. WASM Output: Compiled files go to module/build.
  7. Vite Integration:
    • Development: Hot-reloads WASM modules on source changes.
    • Production: Uses prebuilt WASM modules.
  8. Final: React + WASM modules are served by Vite with proper aliases.