Docs/Build & Run

Graphics Backend Selection

MeshCraft uses the CNA framework which supports multiple rendering backends. Select one at configure time:

BackendCMake FlagNotes
EASYGL (default)-DMESH_CRAFT_GRAPHICS_BACKEND=EASYGLOpenGL ES 3.2 via EasyGL. Default for Linux desktop and Emscripten/WASM.
SDL_RENDERER-DMESH_CRAFT_GRAPHICS_BACKEND=SDL_RENDERERSDL2D renderer. Forced for Android. Easier setup, no OpenGL required.
BGFX-DMESH_CRAFT_GRAPHICS_BACKEND=BGFXCross-platform via BGFX. Needs verification.
VULKAN-DMESH_CRAFT_GRAPHICS_BACKEND=VULKANPlanned. Needs verification.

Desktop Build (Linux)

# Configure
cmake -S . -B cmake-build-debug \
      -DCMAKE_BUILD_TYPE=Debug \
      -DMESH_CRAFT_GRAPHICS_BACKEND=EASYGL \
      -DFETCHCONTENT_UPDATES_DISCONNECTED=ON   # skip update checks if offline

# Build
cmake --build cmake-build-debug --target MeshCraft -- -j$(nproc)

# Run
./cmake-build-debug/MeshCraft test/house.mc3.xml

SDL_RENDERER Backend

cmake -S . -B build-sdl -DMESH_CRAFT_GRAPHICS_BACKEND=SDL_RENDERER
cmake --build build-sdl --target MeshCraft -- -j$(nproc)
./build-sdl/MeshCraft

Web / WASM Build (Emscripten)

MeshCraft ships a convenience script build-web.sh for Emscripten builds.

# Activate the Emscripten SDK first:
source /path/to/emsdk/emsdk_env.sh

# Build
./build-web.sh

# Serve locally
cd cmake-build-web
python3 -m http.server 8080
# Open: http://localhost:8080/MeshCraft.html

The web build uses the EASYGL backend (WebGL 2) and preloads test files at /test. The cmake/web/pre.js script mounts IDBFS at /home/user for persistent storage across reloads.

Release Build

cmake -S . -B cmake-build-release \
      -DCMAKE_BUILD_TYPE=Release \
      -DMESH_CRAFT_GRAPHICS_BACKEND=EASYGL

cmake --build cmake-build-release --target MeshCraft -- -j$(nproc)

Building mc3togltf Separately

The mc3togltf converter is a standalone binary (no graphics deps). It must be built separately and placed at mc3togltf/build/mc3togltf for the File → Export GLB menu item to work.

cmake -S mc3togltf -B mc3togltf/build -DCMAKE_BUILD_TYPE=Release
cmake --build mc3togltf/build --parallel

# Usage
./mc3togltf/build/mc3togltf input.mc3.xml output.glb
./mc3togltf/build/mc3togltf input.mc3.xml output.gltf

Testing

# Run all tests
ctest --test-dir cmake-build-debug -V

# Individual test
ctest --test-dir cmake-build-debug -V -R smoke_test
ctest --test-dir cmake-build-debug -V -R mc3_roundtrip

Tests only run on UNIX (not Android or Emscripten). They require the MESH_CRAFT_BUILD_TESTING CMake option (enabled by default when BUILD_TESTING=ON).

Known Build Workaround

⚠️
CNA Object File Timestamp Issue

When CNA headers are newer than compiled object files, Ninja recompiles CNA, which may fail due to private-constructor errors in recent CNA commits. Apply this touch workaround before each build when CNA sources have changed:

find cmake-build-debug/CNA_dep/CMakeFiles -name "*.o" -exec touch {} \;
find /path/to/cna/include -name "*.hpp" -exec touch {} \;
touch cmake-build-debug/CNA_dep/SHARP_RUNTIME/libSHARP_RUNTIME.a
touch cmake-build-debug/CNA_dep/libCNA.a

This is a known ongoing limitation. The plain touch on the .a files alone is no longer sufficient — both the .o files and the CNA headers must be touched.

Common Build Problems

ProblemCauseFix
CMake can't find ../cnaSibling repos not clonedClone cna, sharp-runtime, and nova-3d next to mesh-craft
tinyxml2 duplicate targetsharp-runtime also bundles tinyxml2mc3/CMakeLists.txt already has a guard — ensure it creates the tinyxml2::tinyxml2 alias
No display / segfault on serverNo X11 or Wayland displayUse Xvfb: Xvfb :99 & DISPLAY=:99 ./MeshCraft …
FetchContent failsNo internet in CIAdd -DFETCHCONTENT_UPDATES_DISCONNECTED=ON and pre-populate the CMake cache
GLESv2 not foundMissing OpenGL ES dev packagessudo apt install libgles2-mesa-dev

Auto-Screenshot Mode

For CI or headless testing, the --screenshot <path.ppm> flag makes the editor render one frame and exit:

./cmake-build-debug/MeshCraft test/house.mc3.xml --screenshot /tmp/out.ppm
# MeshCraft renders for ~2 seconds then exits, writing a PPM screenshot