subagent transcript

session 17f09f89
delegated task
Research how to cross-compile VTK 9.3.x (data-model modules only, NO rendering) to WebAssembly with Emscripten, and produce a concrete blocker+fix lis
▸ Magik
Research how to cross-compile VTK 9.3.x (data-model modules only, NO rendering) to WebAssembly with Emscripten, and produce a concrete blocker+fix list. This is for a real build in progress: VTK-9.3.1 configured with emcmake/Ninja, static libs, `-DVTK_GROUP_ENABLE_Rendering=DONT_WANT`, `-DVTK_SMP_IMPLEMENTATION_TYPE=Sequential`, `-DVTK_ENABLE_WRAPPING=OFF`, `-DVTK_WRAP_PYTHON=OFF`, modules CommonCore/CommonDataModel/CommonExecutionModel/CommonMath/Filters*/IOXML/IOLegacy, compiled with `-fwasm-exceptions -sWASM_LEGACY_EXCEPTIONS=0` (native wasm exceptions), single-threaded (no pthreads). Emscripten 4.0.12 / clang 22. Use WebSearch/WebFetch. Investigate and report CONCRETELY (with the exact CMake var, source file, or flag): 1. **CMake configure-time TRY_RUN / cross-compile checks**: VTK runs some `try_run` feature checks (e.g. `VTK_TEST_...`, endianness, `KWSYS_...`) that can't execute a wasm binary during configure. Which ones block an emscripten configure of the Common/Filters/IO modules, and how are they pre-seeded (the `..._EXITCODE`/`..._RUN_RESULT` cache vars, or emscripten node as `CMAKE_CROSSCOMPILING_EMULATOR`)? Does emcmake set the node emulator automatically so try_run works? 2. **Threading / vtkSMPTools**: with `VTK_SMP_IMPLEMENTATION_TYPE=Sequential`, are there residual `std::thread`/`std::mutex`/`std::atomic` uses in CommonCore (vtkSMPThreadLocal, vtkAtomic, vtkThreadedCallbackQueue, vtkConditionVariable) that break a `-sUSE_PTHREADS=0` single-threaded build? Which files/flags disable them (`VTK_USE_THREADS`?, `VTK_ENABLE_KOKKOS`?). 3. **vtkThreadedCallbackQueue / vtkConditionVariable**: known to reference pthread/std::thread. Is there a CMake option to exclude them, or do they need patching under emscripten? 4. **IO / filesystem / disk**: do IOXML/IOCore/IOLegacy have any host-FS assumptions that break MEMFS? (probably fine, but flag anything.) 5. **Prior art**: has anyone published a working emscripten VTK build (Kitware's `VTK::wasm`, the `vtk-wasm` npm, trame/vtk.js-adjacent C++ builds, FreeCAD or ParaViewWeb, OpenFOAM-wasm, or GitHub issues on gitlab.kitware.com)? Find the SPECIFIC CMake flag set they used for a data-model / no-rendering wasm build, and any patch commits. VTK added an official `VTK_WEBASSEMBLY_*` / emscripten path — which version, and what does it enable/require? 6. **Exceptions/RTTI**: does VTK require `-frtti` (it does use dynamic_cast heavily)? Any conflict with `-fwasm-exceptions`? Any `-sDISABLE_EXCEPTION_CATCHING` implications? 7. **setjmp/longjmp**: VTK's `vtkImageData`/png/jpeg (we exclude those) use libjpeg longjmp — since we exclude IO image modules, is the data-model subset longjmp-free? Flag any longjmp in the enabled modules. Return a prioritized, deduplicated list: each item = {area, the exact blocker, the exact fix (CMake var / flag / file patch), confidence, source URL}. Focus on what will actually break the Common/Filters/IO build — skip rendering/GL issues entirely (we don't build those). Do NOT modify any files or run builds — this is research only.
Fable
thinking
I need to dig into this properly by checking what VTK resources are available locally and searching for concrete information about WebAssembly cross-compilation. Let me start by exploring the filesystem and running some web searches in parallel to gather the details I need.
Fable
I'll research this thoroughly. Let me start by loading the web tools and checking if VTK source is available locally.
Fable
⚙ ToolSearch {"query": "select:WebSearch,WebFetch", "max_results": 5}
tool result
Fable
⚙ Bash {"command": "find / -maxdepth 6 -type d -iname 'VTK*' 2>/dev/null | head -50; echo \"---SMP---\"; find / -path '*Common/Core/vtkSMPTools*' 2>/dev/null | head; echo \"---VERSION---\"; find / -name 'vtkVersion.h' 2>/dev/null | head", "descrip…
tool result
/var/lib/pacman/local/vtk-9.6.2-1
/usr/lib/vtk
/usr/include/vtk
/opt/toolchains/src/VTK-9.3.1
/opt/toolchains/src/vtk-wasm-build
/opt/toolchains/src/VTK-9.3.1/Accelerators/Vtkm
/opt/toolchains/src/VTK-9.3.1/Rendering/VtkJS
/opt/toolchains/src/VTK-9.3.1/ThirdParty/vtkm
/opt/toolchains/src/OCCT-7_8_1/tests/vtk
/usr/include/vtk/vtkdiy2
/usr/include/vtk/vtkexodusII
/usr/include/vtk/vtkexprtk
/usr/include/vtk/vtkfides
/usr/include/vtk/vtkkissfft
/usr/include/vtk/vtkkwiml
/usr/include/vtk/vtkloguru
/u  …[truncated]
Fable
thinking
I've found a local VTK source tree at `/opt/toolchains/src/VTK-9.3.1` with an existing `vtk-wasm-build` directory, which means I can examine the actual source files and see what build configuration was already used. Let me check the wasm build directory first to understand the prior setup, then dig into the SMPTools implementation to understand what needs to be configured.
Fable
Excellent — there's a local VTK-9.3.1 source tree AND a `vtk-wasm-build` directory at `/opt/toolchains/src/`. This is gold for concrete answers. Let me investigate the existing build config and source in parallel with web research.
Fable
⚙ Bash {"command": "D=/opt/toolchains/src/vtk-wasm-build\necho \"===== ls build dir =====\"; ls -la $D 2>/dev/null | head -40\necho \"===== CMakeCache exists? =====\"; ls -la $D/CMakeCache.txt 2>/dev/null\necho \"===== grep key cache vars =====\";…
tool result
===== ls build dir =====
total 0
drwxr-xr-x 1 magik6k magik6k 104 Jul  7 01:04 .
drwx------ 1 magik6k magik6k 360 Jul  7 01:03 ..
drwxr-xr-x 1 magik6k magik6k 202 Jul  7 01:04 CMakeFiles
drwxr-xr-x 1 magik6k magik6k 144 Jul  7 01:04 Common
drwxr-xr-x 1 magik6k magik6k 120 Jul  7 01:04 Filters
drwxr-xr-x 1 magik6k magik6k  20 Jul  7 01:04 IO
drwxr-xr-x 1 magik6k magik6k   8 Jul  7 01:04 Parallel
drwxr-xr-x 1 m  …[truncated]
Fable
⚙ WebSearch {"query": "VTK WebAssembly Emscripten build data model no rendering CMake flags VTK_GROUP_ENABLE_Rendering"}
Fable
⚙ WebSearch {"query": "VTK Emscripten cross-compile try_run TRY_RUN_RESULT cache variable CMAKE_CROSSCOMPILING_EMULATOR node"}
tool result
Web search results for query: "VTK WebAssembly Emscripten build data model no rendering CMake flags VTK_GROUP_ENABLE_Rendering"

Links: [{"title":"Building using emscripten for WebAssembly - VTK documentation","url":"https://docs.vtk.org/en/latest/advanced/build_wasm_emscripten.html"},{"title":"Build Settings - VTK documentation","url":"https://docs.vtk.org/en/v9.5.0/build_instructions/build_settings.html"},{"title":"Building VTK-9 with Emscripten+GLES for rendering - Development - VTK","url":"h  …[truncated]
tool result
Web search results for query: "VTK Emscripten cross-compile try_run TRY_RUN_RESULT cache variable CMAKE_CROSSCOMPILING_EMULATOR node"

Links: [{"title":"Building using emscripten for WebAssembly - VTK documentation","url":"https://docs.vtk.org/en/latest/advanced/build_wasm_emscripten.html"},{"title":"CMAKE_CROSSCOMPILING_EMULATOR issue with Emscripten.cmake toolchain file · Issue #10028 · emscripten-core/emscripten","url":"https://github.com/emscripten-core/emscripten/issues/10028"},{"title":"VT  …[truncated]
Fable
thinking
The build directory seems to exist but CMakeCache.txt isn't showing up at the top level, so I'm going to dig deeper into the source files and continue investigating the vtk-wasm-build setup. I'm also noticing that `.zshrc` error message is just noise. Let me focus on examining how `try_run` works in C to understand what's happening here.

Now I'm looking at several threading and synchronization mechanisms in VTK — the SMP tools implementations, callback queues, condition variables, atomic operations, and how std::thread and mutex are used throughout Common/Core. I should also check for setjmp/longjmp usage in the enabled modules since those could be problematic for WebAssembly. The official   …
Fable
The build directory exists but I don't see a top-level CMakeCache yet. Let me dig deeper into the build dir and the actual source files, plus fetch the official VTK wasm doc.
Fable
⚙ Bash {"command": "D=/opt/toolchains/src/vtk-wasm-build\necho \"===== find CMakeCache anywhere =====\"; find $D -name 'CMakeCache.txt' 2>/dev/null\necho \"===== find any .cmake config / build.ninja =====\"; find $D -maxdepth 2 -name 'build.ninja'…
tool result
===== find CMakeCache anywhere =====
/opt/toolchains/src/vtk-wasm-build/CMakeCache.txt
===== find any .cmake config / build.ninja =====
/opt/toolchains/src/vtk-wasm-build/vtk-config-version.cmake
/opt/toolchains/src/vtk-wasm-build/CTestCustom.cmake
/opt/toolchains/src/vtk-wasm-build/vtk-config.cmake
/opt/toolchains/src/vtk-wasm-build/cmake_install.cmake
/opt/toolchains/src/vtk-wasm-build/build.ninja
/opt/toolchains/src/vtk-wasm-build/CMakeFiles/vtk-config.cmake
===== CMakeFiles listing =====
tot  …[truncated]
Fable
⚙ WebFetch {"url": "https://github.com/Kitware/VTK/blob/master/Documentation/docs/advanced/build_wasm_emscripten.md", "prompt": "Extract the exact CMake configure flags and toolchain settings recommended for building VTK for WebAssembly with Emscripte…
tool result
# VTK WebAssembly Build Configuration for Emscripten

Based on the documentation, here are the key CMake flags for building VTK with Emscripten:

## Core Configuration Variables

The document specifies these essential CMake settings:

- `"-DBUILD_SHARED_LIBS:BOOL=OFF"` - Static linking is required
- `"-DVTK_ENABLE_WEBGPU:BOOL=ON"` - WebGPU rendering support
- `"-DVTK_WEBASSEMBLY_64_BIT:BOOL=ON"` - Optional 64-bit addressing (wasm64)
- `"-DCMAKE_BUILD_TYPE=Release"` - Recommended build type

## O  …[truncated]
Fable
thinking
I've got the CMake build artifacts here — the cache file, configure log, and error log all exist, which means the configuration actually completed successfully. The build.ninja file confirms that too. Let me dig into those logs to see what was configured and what issues came up during the process.
Fable
There's a live, in-progress build with a real `CMakeCache.txt`, `CMakeError.log`, and `CMakeConfigureLog.yaml` (timestamps show it configured minutes ago). This is the actual build the task refers to. Let me extract the real config and errors.
Fable
⚙ Bash {"command": "D=/opt/toolchains/src/vtk-wasm-build\necho \"############ RELEVANT CMakeCache VARS ############\"\ngrep -iE 'CMAKE_CROSSCOMPILING|CROSSCOMPILING_EMULATOR|_EXITCODE|_RUN_RESULT|:INTERNAL=|WASM|EXCEPTION|SMP_IMPL|USE_THREADS|ENAB…
tool result
############ RELEVANT CMakeCache VARS ############
bswap_16:INTERNAL=
bswap_32:INTERNAL=
bswap_64:INTERNAL=
BUILD_SHARED_LIBS:BOOL=OFF
CMAKE_CACHEFILE_DIR:INTERNAL=/opt/toolchains/src/vtk-wasm-build
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=4
CMAKE_CACHE_MINOR_VERSION:INTERNAL=3
CMAKE_CACHE_PATCH_VERSION:INTERNAL=3
CMAKE_C_FLAGS:STRING=-fwasm-exceptions -sWASM_LEGACY_EXCEPTIONS=0
CMAKE_COMMAND:INTERNAL=/bin/cmake
CMAKE_CPACK_COMMAND:INTERNAL=/bin/cpack
CMAKE_CROSSCOMPILING_EMULATOR:UNINITIALIZED=/opt/t  …[truncated]
Fable
⚙ Bash {"command": "D=/opt/toolchains/src/vtk-wasm-build\necho \"############ CMakeError.log ############\"\ncat $D/CMakeFiles/CMakeError.log 2>/dev/null | head -200", "description": "Read CMake configure error log"}
tool result
############ CMakeError.log ############
Checking whether CXX compiler has environ in stdlib.h failed to compile with the following output:
Change Dir: '/opt/toolchains/src/vtk-wasm-build/Utilities/KWSys/vtksys/CMakeFiles/CMakeTmp'

Run Build Command(s): /bin/ninja -v cmTC_30cda
[1/2] /opt/toolchains/emsdk/upstream/emscripten/em++ -DTEST_KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H  -fwasm-exceptions -sWASM_LEGACY_EXCEPTIONS=0   -std=c++11 -fPIE -MD -MT CMakeFiles/cmTC_30cda.dir/kwsysPlatformTestsCXX.cxx.o  …[truncated]
Fable
thinking
The CMakeError.log failures are all expected platform-detection checks that are supposed to fail on certain systems — they're not actual problems, just feature flags being set to false. The key finding appears to be related to CMAKE_CROSSCOMPIL, though the thought cuts off there.

Looking at the cache variables and configuration output, the Emscripten toolchain is properly set up with node as the crosscompiling emulator, which means try_run should work. The configure step actually succeeded — build.ninja was generated and 58 makefiles were created. So the real issue must be happening during the actual compilation or linking phase. I need to dig into the threading-related source files, check   …
Fable
The CMakeError.log entries are all benign feature-detection `try_compile` failures (environ, st_mtimespec, ext/stdio_filebuf.h, __int64) — expected to fail on non-matching platforms; they just set feature vars false. Critically, the cache confirms `CMAKE_CROSSCOMPILING_EMULATOR=.../node` is set automatically by Emscripten.cmake, and `build.ninja` was generated, so configure succeeded. Now let me inspect the threading source and the rest of the config.
Fable
⚙ Bash {"command": "D=/opt/toolchains/src/vtk-wasm-build\necho \"############ SMP / THREAD / MODULE cache vars ############\"\ngrep -iE 'SMP|THREAD|KOKKOS|_ENABLE:|ATOMIC|PTHREAD|VTK_USE|VTK_MODULE_ENABLE_VTK_(Common|Filters|IO)|_RUN_RESULT|_EXITC…
tool result
############ SMP / THREAD / MODULE cache vars ############
//ADVANCED property for variable: VTK_MAX_THREADS
//ADVANCED property for variable: VTK_MODULE_ENABLE_VTK_CommonArchive
//ADVANCED property for variable: VTK_MODULE_ENABLE_VTK_CommonColor
//ADVANCED property for variable: VTK_MODULE_ENABLE_VTK_CommonComputationalGeometry
//ADVANCED property for variable: VTK_MODULE_ENABLE_VTK_CommonCore
//ADVANCED property for variable: VTK_MODULE_ENABLE_VTK_CommonDataModel
//ADVANCED property for variab  …[truncated]
Fable
⚙ Bash {"command": "S=/opt/toolchains/src/VTK-9.3.1\necho \"############ vtkSMPTools backends present ############\"\nls $S/Common/Core/SMP/ 2>/dev/null\nls $S/Common/Core/SMP/Sequential 2>/dev/null\necho\necho \"############ std::thread / std::mu…
tool result
############ vtkSMPTools backends present ############
Common
OpenMP
Sequential
STDThread
TBB
vtkSMPThreadLocalImpl.h
vtkSMPToolsImpl.cxx
vtkSMPToolsImpl.txx

############ std::thread / std::mutex / std::atomic / pthread grep in Common/Core (non-test) ############
/opt/toolchains/src/VTK-9.3.1/Common/Core/vtkAtomicMutex.h
/opt/toolchains/src/VTK-9.3.1/Common/Core/vtkCriticalSection.h
/opt/toolchains/src/VTK-9.3.1/Common/Core/vtkDebu  …[truncated]
Fable
thinking
Looking at the build configuration, I can see the enabled modules are organized across several categories: the Common modules handle geometry, core functionality, data models, execution, math, and system operations; the Filters modules cover extraction, general filtering, geometry, modeling, sources, and statistics; and the IO modules manage core I/O, legacy formats, and XML parsing. The SMP backends are about to be listed next. vtkOutputWindow and vtkStringManager both use std::mutex which compile fine, and I'm checking whether vtkThreadedCallbackQueue and vtkConditionVariable are actually present in the codebase. The real question is how emscripten handles pthread_create in single-threaded  …
Fable
Now I have the exact enabled module set and the threading files. Let me drill into the specific threading classes, the pthread config resolution, setjmp/longjmp, and whether the build has actually started compiling (existing error output).
Fable
⚙ Bash {"command": "S=/opt/toolchains/src/VTK-9.3.1; D=/opt/toolchains/src/vtk-wasm-build\necho \"############ vtkThreadedCallbackQueue / vtkConditionVariable presence ############\"\nls -la $S/Common/Core/vtkThreadedCallbackQueue* $S/Common/Core/…
tool result
############ vtkThreadedCallbackQueue / vtkConditionVariable presence ############
(eval):3: no matches found: /opt/toolchains/src/VTK-9.3.1/Common/Core/vtkThreadedCallbackQueue*

############ Is vtkThreadedCallbackQueue in the CommonCore build? (search build.ninja) ############
3
vtkThreadedCallbackQueue.cxx
vtkThreadedCallbackQueue.cxx.o
vtkThreadedCallbackQueue.cxx.o.d

############ How are threads configured? Look at generated vtkThreads.h / vtkConfigure ############
/opt/toolchains/src/vtk-  …[truncated]
Fable
⚙ Bash {"command": "S=/opt/toolchains/src/VTK-9.3.1\necho \"############ setjmp/longjmp in ENABLED modules only ############\"\nfor m in Common/Core Common/DataModel Common/ExecutionModel Common/Math Common/Misc Common/System Common/Transforms Com…
tool result
############ setjmp/longjmp in ENABLED modules only ############
(eval):4: no matches found: /opt/toolchains/src/VTK-9.3.1/Common/DataModel/*.c
(eval):4: no matches found: /opt/toolchains/src/VTK-9.3.1/Common/ExecutionModel/*.c
(eval):4: no matches found: /opt/toolchains/src/VTK-9.3.1/Common/Math/*.c
(eval):4: no matches found: /opt/toolchains/src/VTK-9.3.1/Common/Misc/*.c
(eval):4: no matches found: /opt/toolchains/src/VTK-9.3.1/Common/System/*.c
(eval):4: no matches found: /opt/toolchains/src/  …[truncated]
Fable
thinking
I'm seeing that vtkThreads.h defines VTK_USE_PTHREADS even in the emscripten build, which means vtkMultiThreader compiles with pthread support. This happens because emscripten's libc provides pthread symbols and CMake found threading available, so pthread_create gets called even in single-threaded emscripten builds without the -pthread flag.

The key distinction is that this is a runtime issue, not a compile issue. Without -pthread, emscripten provides stub pthread implementations where pthread_create returns EAGAIN and fails at runtime. The code still compiles and links fine because the headers and stub symbols are available, but when pthread_create actually runs and fails, vtkMultiThreader  …
Fable
Key findings so far: `vtkThreads.h` has `#define VTK_USE_PTHREADS` (emscripten's libc advertises pthread), SMP backend is Sequential (but `VTK_SMP_ENABLE_STDTHREAD 1`), `vtkThreadedCallbackQueue.cxx` IS compiled into CommonCore, and no setjmp/longjmp in first-party enabled modules. Let me confirm the threading source details, third-party setjmp, try_run behavior, and check whether the build has produced any compile errors yet.
Fable
⚙ Bash {"command": "S=/opt/toolchains/src/VTK-9.3.1\necho \"############ vtkThreadedCallbackQueue.h threading primitives ############\"\ngrep -nE '#include <(thread|mutex|condition_variable|atomic|future)>|std::thread|std::condition_variable|std::…
tool result
############ vtkThreadedCallbackQueue.h threading primitives ############

############ vtkMultiThreader: how many threads / hardware_concurrency / pthread_create ############
66:int vtkMultiThreader::GetGlobalDefaultNumberOfThreads()
139:  this->NumberOfThreads = vtkMultiThreader::GetGlobalDefaultNumberOfThreads();
261:  // We want to use pthread_create to start this->NumberOfThreads-1 additional
272:#if !defined(__CYGWIN__) && !defined(__EMSCRIPTEN__)
281:    int threadError = pthread_create(&  …[truncated]
Fable
⚙ Bash {"command": "S=/opt/toolchains/src/VTK-9.3.1\necho \"############ thirdparty dirs present ############\"\nls $S/ThirdParty/ | tr '\\n' ' '; echo\necho \"############ setjmp/longjmp across ALL thirdparty that could be linked by IO subset ###…
tool result
############ thirdparty dirs present ############
cgns cli11 diy2 doubleconversion eigen exodusII expat exprtk fast_float fides fmt freetype gl2ps glew h5part hdf5 imported.md ioss jpeg jsoncpp kissfft libharu libproj libxml  …[truncated]
Fable
thinking
I'm discovering that vtkMultiThreader in VTK 9.3.1 already has proper Emscripten guards around pthread_create, so it safely falls back to single-threaded execution on that platform—this resolves a major compatibility concern.

I'm also finding that vtkConditionVariable doesn't exist in this version (it was removed earlier), and the IO subset dependencies like expat, zlib, and others are all free of setjmp/longjmp calls, which is good news for Emscripten compatibility.

The real question now is whether vtkThreadedCallbackQueue has similar Emscripten protections or if it might still try to spawn std::thread without guards—I need to examine its source directly to see if it compiles cleanly in s  …
Fable
Critical finding: `vtkMultiThreader.cxx` already guards `pthread_create` with `#if !defined(__CYGWIN__) && !defined(__EMSCRIPTEN__)` — so it's emscripten-safe in 9.3.1. Also `vtkConditionVariable` does NOT exist in 9.3.1, and third-party expat/zlib/etc. are setjmp-free. The remaining unknown is `vtkThreadedCallbackQueue`, which has no emscripten guard. Let me read it and check the try_run configure log.
Fable
⚙ Bash {"command": "S=/opt/toolchains/src/VTK-9.3.1\necho \"############ vtkThreadedCallbackQueue.h : all includes + thread usage ############\"\ngrep -nE '#include|std::thread|std::atomic|std::mutex|std::condition|std::unique_lock|Threads|__EMSCR…
tool result
############ vtkThreadedCallbackQueue.h : all includes + thread usage ############

############ vtkThreadedCallbackQueue.cxx : thread spawn points ############
zshexit:1: parameter HISTDB_FD does not contain a file descriptor
Fable
⚙ Bash {"command": "D=/opt/toolchains/src/vtk-wasm-build\necho \"############ try_run / TestBigEndian / RUN_RESULT in ConfigureLog ############\"\ngrep -inE 'try_run|TRY_RUN|TestBigEndian|BIG_ENDIAN|RUN_RESULT|crosscompiling_emulator|checkTypeSize…
tool result
############ try_run / TestBigEndian / RUN_RESULT in ConfigureLog ############
1420:    kind: "try_run-v1"
1422:      - "/usr/share/cmake/Modules/Internal/CheckSourceRuns.cmake:95 (try_run)"

############ Any RUN_RESULT / EXITCODE cache entries (pre-seeded try_run) ############

############ endianness result in generated headers ############
/opt/toolchains/src/vtk-wasm-build/Common/Core/vtkEndian.h:14:/* #undef VTK_WORDS_BIGENDIAN */
/opt/toolchains/src/vtk-wasm-build/Common/Core/vtkEndian.h:1  …[truncated]
Fable
thinking
The grep for the header file came up empty, which is strange. Let me read the file directly to see what's actually in it—there might be a path issue or the includes might be formatted differently than expected. I also spotted a try_run call at line 95 in CheckSourceRuns.cmake that shows up in the ConfigureLog around line 1420, so I should investigate what that's attempting to do.

Looking at the endianness resolution, vtkEndian.h correctly shows little-endian for WebAssembly, which CMake determined without needing a cross-compile try_run since modern CMake uses compile-time checks. The fact that there are no _RUN_RESULT or _EXITCODE cache entries suggests the node emulator successfully ran a  …
Fable
Let me read `vtkThreadedCallbackQueue` directly (the grep came back empty, which is suspicious) and inspect the one `try_run` in the configure log, plus kick off prior-art web research.
Fable
⚙ Bash {"command": "S=/opt/toolchains/src/VTK-9.3.1\necho \"===== HEAD of vtkThreadedCallbackQueue.h =====\"; sed -n '1,60p' $S/Common/Core/vtkThreadedCallbackQueue.h 2>/dev/null\necho \"===== grep thread-ish in both files (fixed strings) =====\"\…
tool result
===== HEAD of vtkThreadedCallbackQueue.h =====
===== grep thread-ish in both files (fixed strings) =====
zshexit:1: parameter HISTDB_FD does not contain a file descriptor
Fable
⚙ Bash {"command": "D=/opt/toolchains/src/vtk-wasm-build\necho \"===== try_run region of CMakeConfigureLog.yaml (lines 1400-1480) =====\"\nsed -n '1400,1490p' $D/CMakeFiles/CMakeConfigureLog.yaml 2>/dev/null", "description": "Read the try_run entr…
tool result
===== try_run region of CMakeConfigureLog.yaml (lines 1400-1480) =====
      CMAKE_CXX_FLAGS: "-fwasm-exceptions -sWASM_LEGACY_EXCEPTIONS=0 -DFMT_USE_CHAR8_T=0 "
      CMAKE_CXX_FLAGS_DEBUG: "-g"
      CMAKE_CXX_STDLIB_MODULES_JSON: ""
      CMAKE_EXE_LINKER_FLAGS: " "
      CMAKE_MODULE_PATH: "/opt/toolchains/src/VTK-9.3.1/CMake/patches/99;/opt/toolchains/src/VTK-9.3.1/CMake;/opt/toolchains/emsdk/upstream/emscripten/cmake/Modules;/opt/toolchains/emsdk/upstream/emscripten/cmake/Modules;/opt/tool  …[truncated]
Fable
⚙ WebSearch {"query": "emscripten std::thread without -pthread USE_PTHREADS=0 link error stub pthread_create"}
tool result
Web search results for query: "emscripten std::thread without -pthread USE_PTHREADS=0 link error stub pthread_create"

Links: [{"title":"Pthreads support - Emscripten 6.0.3-git (dev) documentation","url":"https://emscripten.org/docs/porting/pthreads.html"},{"title":"Support -no-pthread linking flag · Issue #20720 · emscripten-core/emscripten","url":"https://github.com/emscripten-core/emscripten/issues/20720"},{"title":"pthread_create detected as undefined symbol with side module + -fexception +   …[truncated]
Fable
thinking
I found a critical issue — the VTK build is failing during the large file support check in CMakeLists.txt, where the C++ source compilation and linking succeeded but something downstream is blocking the build process.

The root cause is an exception handling mismatch: the test binary was compiled with `-fwasm-exceptions -sWASM_LEGACY_EXCEPTIONS=0`, which generates the new exnref opcode (0x1f), but the bundled Node.js (22.16.0) in emsdk doesn't enable `--experimental-wasm-exnref` by default. When Node tries to instantiate the test binary as the cross-compilation emulator, it fails with a WebAssembly compilation error because it doesn't recognize the opcode. This causes the try_run to exit wit  …
Fable
Major finding in the configure log: the one `try_run` VTK performs — **`VTK_REQUIRE_LARGE_FILE_SUPPORT`** (VTK top `CMakeLists.txt:130` via `check_cxx_source_runs`) — **compiled+linked fine but FAILED TO RUN under node**, with `Invalid opcode 0x1f (enable with --experimental-wasm-exnref)`. That's the exnref/legacy-EH mismatch: `-sWASM_LEGACY_EXCEPTIONS=0` emits new exnref EH, and emsdk's bundled node 22.16 doesn't enable it. So the try_run returns exit code 1 (bogus "failed"). Let me locate `vtkThreadedCallbackQueue` (zsh nullglob aborted my earlier greps) and count all try_runs.
Fable
⚙ Bash {"command": "S=/opt/toolchains/src/VTK-9.3.1; D=/opt/toolchains/src/vtk-wasm-build\necho \"===== real location of vtkThreadedCallbackQueue =====\"; find $S -name 'vtkThreadedCallbackQueue*' 2>/dev/null\necho \"===== total try_run entries in…
tool result
===== real location of vtkThreadedCallbackQueue =====
/opt/toolchains/src/VTK-9.3.1/Parallel/Core/vtkThreadedCallbackQueue.cxx
/opt/toolchains/src/VTK-9.3.1/Parallel/Core/vtkThreadedCallbackQueue.h
/opt/toolchains/src/VTK-9.3.1/Parallel/Core/vtkThreadedCallbackQueue.txx
===== total try_run entries in ConfigureLog =====
1
===== all try_run check names =====
"Performing Test VTK_REQUIRE_LARGE_FILE_SUPPORT"
===== what CMakeLists.txt:130 does with the result =====
10:  VTK_REQUIRE_LARGE_FILE_SUPPORT  …[truncated]
Fable
thinking
So `vtkThreadedCallbackQueue` is actually in the Parallel/Core module, not Common/Core—that's the `VTK::ParallelCore` module. Looking at the enabled modules in this build, ParallelCore isn't directly included, and while some of the Filters modules that depend on it could pull it in, those particular ones aren't enabled either.

But here's the thing: build.ninja actually references `vtkThreadedCallbackQueue.cxx.o` three times, which means ParallelCore is being compiled. My earlier grep pattern only searched for `vtk(Common|Filters|IO)` modules, so it wouldn't have caught ParallelCore. I need to verify whether ParallelCore is actually enabled and figure out what's pulling it in as a dependency  …
Fable
`vtkThreadedCallbackQueue` lives in **Parallel/Core** (VTK::ParallelCore), and `build.ninja` compiles it — so ParallelCore got pulled in as a dependency. And there is exactly ONE try_run in the whole configure (`VTK_REQUIRE_LARGE_FILE_SUPPORT`). Let me read the ThreadedCallbackQueue threading, confirm why ParallelCore is enabled, and check the LFS handling detail.
Fable
⚙ Read {"file_path": "/opt/toolchains/src/VTK-9.3.1/Parallel/Core/vtkThreadedCallbackQueue.h", "limit": 55}
tool result
1	// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2	// SPDX-License-Identifier: BSD-3-Clause
3	/**
4	 * @class vtkThreadedCallbackQueue
5	 * @brief simple threaded callback queue
6	 *
7	 * This callback queue executes pushed functions and functors on threads whose
8	 * purpose is to execute those functions.
9	 * By default, one thread is created by this class, so it is advised to set `NumberOfThreads`.
10	 * Upon destruction of an instance of this callback queu  …[truncated]
Fable
⚙ Bash {"command": "S=/opt/toolchains/src/VTK-9.3.1; D=/opt/toolchains/src/vtk-wasm-build\necho \"===== thread spawn in vtkThreadedCallbackQueue.cxx =====\"\ngrep -nF -e 'std::thread' -e 'emplace_back' -e '.join' -e 'hardware_concurrency' -e '__EM…
tool result
===== thread spawn in vtkThreadedCallbackQueue.cxx =====
142:        auto thread = std::thread(ThreadWorker(this, threadIndex));
191:    [](std::thread& thread) { thread.join(); });
243:          invokersToLaunch.emplace_back(std::move(dependent));
===== is ParallelCore enabled & why (which enabled module depends on it) =====
/opt/toolchains/src/VTK-9.3.1/Filters/AMR/vtk.module:24:  VTK::ParallelCore
/opt/toolchains/src/VTK-9.3.1/Filters/ParallelDIY2/vtk.module:27:  VTK::ParallelCore
/opt/toolch  …[truncated]
Fable
thinking
I'm tracing through the dependency chain to figure out what's actually pulling in ParallelCore. It depends on CommonCore, but something else must be enabling it. I need to check which of the enabled Filters might be bringing it in as a dependency. I'm not sure which enabled module pulls in ParallelCore, but that's less important than the actual issue: vtkThreadedCallbackQueue uses std::thread without any emscripten guards, and while it compiles and links under single-threaded emscripten (thanks to pthread stub symbols), the real question is whether it actually runs correctly in that environment.

The std::thread constructor calls pthread_create, which in the stub returns EAGAIN and causes st  …
Fable
Now let me nail down the remaining questions: the LFS result handling (Q1 consequence), RTTI defaults (Q6), and prior-art web research (Q5) plus confirming the std::thread stub link behavior.
Fable
⚙ Bash {"command": "S=/opt/toolchains/src/VTK-9.3.1; D=/opt/toolchains/src/vtk-wasm-build\necho \"===== CMakeLists.txt lines 120-160 (LFS handling) =====\"\nsed -n '120,160p' $S/CMakeLists.txt 2>/dev/null\necho \"===== how VTK_REQUIRE_LARGE_FILE_S…
tool result
===== CMakeLists.txt lines 120-160 (LFS handling) =====
# Add the Remote Subdirectory
if (VTK_ENABLE_REMOTE_MODULES)
  add_subdirectory(Remote)
endif ()

#-----------------------------------------------------------------------------
# Does VTK require support for 64 bit file systems
include(CheckCXXSourceRuns)
file(READ "${vtk_cmake_dir}/vtkRequireLargeFilesSupport.cxx"
  VTK_REQUIRE_LARGE_FILE_SUPPORT_FILE)
check_cxx_source_runs("${VTK_REQUIRE_LARGE_FILE_SUPPORT_FILE}"
  VTK_REQUIRE_LARGE_FILE_  …[truncated]
Fable
⚙ WebFetch {"url": "https://gitlab.kitware.com/vtk/vtk/-/issues/17986", "prompt": "Summarize the concrete Emscripten/WebAssembly build blockers and fixes discussed. Extract any exact CMake flags, cache variables that had to be pre-seeded for try_run c…
Fable
⚙ WebSearch {"query": "VTK wasm official WebAssembly support version 9.4 emscripten ParallelCore vtkThreadedCallbackQueue single thread pthread"}
tool result
I cannot provide the requested summary because the web page content provided is only an error message from a website access denial page (error code b3728715388cb593). 

The page contains no technical information about Emscripten, WebAssembly, VTK builds, CMake flags, threading implementations, or any of the other specific topics you're asking about.

To help you extract that information, you would need to provide the actual technical documentation or article content that discusses those build bl  …[truncated]
tool result
Web search results for query: "VTK wasm official WebAssembly support version 9.4 emscripten ParallelCore vtkThreadedCallbackQueue single thread pthread"

Links: [{"title":"Building using emscripten for WebAssembly - VTK documentation","url":"https://docs.vtk.org/en/latest/advanced/build_wasm_emscripten.html"},{"title":"Introducing WebAssembly support in VTK","url":"https://www.kitware.com/introducing-webassembly-support-in-vtk/"},{"title":"Using WebAssembly - VTK documentation","url":"https://do  …[truncated]
Fable
thinking
I'm finding that VTK itself handles cross-compilation for mobile devices by pre-setting cache variables like `VTK_REQUIRE_LARGE_FILE_SUPPORT` to bypass the normal detection process when building across platforms. So pre-seeding the cache variable avoids the try_run entirely, which is exactly what VTK's mobile toolchain does. The current build ran it anyway and got a false result (exit code 1), disabling LFS, but that's benign for WebAssembly since emscripten handles 64-bit file offsets natively. The real takeaway is this is the canonical cross-compile try_run problem, and the fix is straightforward: pre-seed the variable as documented. Now looking at RTTI support in VTK...

emscripten enable  …
Fable
Rich findings. Notably `CMake/vtkMobileDevices.cmake:4` shows VTK's OWN cross-compile pattern: it force-pre-seeds `VTK_REQUIRE_LARGE_FILE_SUPPORT` in the cache — the exact fix for the try_run. And VTK only forces `-qrtti` for IBM XL (no `-fno-rtti`), so RTTI stays on by default. Let me finalize Q4 (IO/FS assumptions), Q5 (official version + exact flags), and confirm the std::thread link behavior.
Fable
⚙ Bash {"command": "S=/opt/toolchains/src/VTK-9.3.1\necho \"===== IO host-FS assumptions in enabled IO modules (fopen/getenv/tmpnam/stat/mkdir/realpath) =====\"\ngrep -rnoE 'getenv|tmpnam|mkstemp|realpath|::stat\\(|mkdir|chdir|popen|system\\(' $S/…
tool result
===== IO host-FS assumptions in enabled IO modules (fopen/getenv/tmpnam/stat/mkdir/realpath) =====
--- vtksys SystemTools usage (portable, MEMFS-ok) count ---
12

===== what pulls in ParallelCore (reverse dep among enabled) =====
(if empty, ParallelCore came via a WANT/DEFAULT group or optional dep)
===== grep any OPTIONAL/ default group forcing ParallelCore =====
zshexit:1: parameter HISTDB_FD does not contain a file descriptor
Fable
⚙ WebFetch {"url": "https://raw.githubusercontent.com/Kitware/VTK/master/Documentation/docs/advanced/build_wasm_emscripten.md", "prompt": "List the EXACT emcmake cmake command and every -D CMake flag it uses for a VTK WebAssembly build. Include VTK_EN…
tool result
# VTK WebAssembly Build Commands

Based on the provided documentation, here are the exact `emcmake cmake` commands shown:

## wasm32 (macOS/Linux)
```sh
emcmake cmake \
  -S ${VTK_SOURCE_DIR} \
  -B ${VTK_BUILD_DIR} \
  -G "Ninja" \
  -DCMAKE_BUILD_TYPE=Release \
  "-DBUILD_SHARED_LIBS:BOOL=OFF" \
  "-DVTK_ENABLE_WEBGPU:BOOL=ON"
```

## wasm64 (macOS/Linux)
```sh
emcmake cmake \
  -S ${VTK_SOURCE_DIR} \
  -B ${VTK_BUILD_DIR} \
  -G "Ninja" \
  -DCMAKE_BUILD_TYPE=Release \
  "-DBUILD_SHARED_LIBS:  …[truncated]
Fable
thinking
The IO modules are safe for MEMFS since they rely on vtksys::SystemTools and standard C++ streams rather than direct system calls like getenv, fopen, or stat. This means the IOXML, IOCore, and IOLegacy modules don't make any assumptions about the host filesystem and should work correctly in a memory-based environment.

ParallelCore gets built as part of the StandAlone group since the user left the default group settings unchanged, which means vtkThreadedCallbackQueue will be compiled. However, since nothing in the enabled modules actually depends on it, the user could explicitly disable it with `-DVTK_MODULE_ENABLE_VTK_ParallelCore=DONT_WANT` to remove it from the build entirely without brea  …
Fable
IO modules use only `vtksys::SystemTools` (MEMFS-portable) — no raw getenv/fopen/tmpnam/realpath. ParallelCore is pulled in via the StandAlone group (nothing enabled hard-depends on it), so it's safely disableable. Let me pin the official-support version and confirm the node exnref/exception details.
Fable
⚙ WebFetch {"url": "https://www.kitware.com/introducing-webassembly-support-in-vtk/", "prompt": "Which VTK version first introduced official WebAssembly/Emscripten support, and what year? What CMake infrastructure (toolchain, VTK_WEBASSEMBLY_* variabl…
Fable
⚙ WebSearch {"query": "emscripten -fwasm-exceptions WASM_LEGACY_EXCEPTIONS=0 exnref node --experimental-wasm-exnref V8 invalid opcode 0x1f"}
tool result
# WebAssembly Support in VTK: Information Request

Based on the provided web page content, I cannot answer your questions with the specificity you've requested.

**What the article does discuss:**

The article, published August 15, 2025, focuses on recent efforts to improve WebAssembly support in VTK. It mentions that the team "reworked the CMake support code in VTK to use the Emscripten SDK" and notes that Emscripten supports both 32-bit and 64-bit memory configurations.

**What the article doe  …[truncated]
tool result
Web search results for query: "emscripten -fwasm-exceptions WASM_LEGACY_EXCEPTIONS=0 exnref node --experimental-wasm-exnref V8 invalid opcode 0x1f"

Links: [{"title":"failed to asynchronously prepare wasm: CompileError: WebAssembly.instantiate(): Compiling function #67 failed: Invalid opcode 0xfe (enable with --experimental-wasm-threads) · Issue #13152 · emscripten-core/emscripten","url":"https://github.com/emscripten-core/emscripten/issues/13152"},{"title":"Upstream: Safari - WebAssembly.instan  …[truncated]
Fable
thinking
So the `try_table` instruction (opcode 0x1f) is what the modern wasm-EH implementation uses, and Node 22.16 without the `--experimental-wasm-exnref` flag can't handle it—that's why the LFS try_run executed but exited with code 1. The Kitware blog post from August 2025 mentions they reworked the CMake support to use the Emscripten SDK directly, which is the modern VTK 9.4+ approach. For a data-model-only build, the user's strategy is sound since there's no official recipe published; the key lever is `GROUP_ENABLE_Rendering=DONT_WANT`, which they're already using.

I'm confident about the `DISABLE_EXCEPTION_CATCHING` behavior—it only affects the JS/Emscripten exception handling (`-fexceptions`  …
Fable
I have everything I need — the live build tree gave authoritative, file-level evidence, and web sources confirm the general behavior. Here is the prioritized, deduplicated blocker+fix list. --- ## VTK 9.3.1 → WASM (data-model subset): blocker + fix list Headline: I inspected the actual in-progress build at `/opt/toolchains/src/vtk-wasm-build`. **Configure already succeeded** (`build.ninja` generated, 58 makefiles, node auto-set as the crosscompile emulator). Almost every classic VTK-wasm hazard is already handled in 9.3.1 for exactly this module subset. There is essentially **one real configure quirk** and **one latent runtime concern**; the rest are non-issues I can rule out concretely. Evidence base (all confirmed on disk): enabled modules are Common{Core,DataModel,ExecutionModel,Math,Misc,System,Transforms,ComputationalGeometry}, Filters{Core,Extraction,General,Geometry,HyperTree,Modeling,Sources,Statistics,Verdict}, IO{Core,Legacy,XML,XMLParser}, **plus VTK::ParallelCore** (pulled in by the StandAlone group). Flags in cache: `CMAKE_CXX_FLAGS = -fwasm-exceptions -sWASM_LEGACY_EXCEPTIONS=0`, `BUILD_SHARED_LIBS=OFF`, toolchain `Emscripten.cmake`, `VTK_SMP_Sequential`. --- ### P1 — try_run mis-runs under node because new-EH (exnref) binaries won't instantiate - **Area:** CMake configure-time try_run / cross-compile. - **Blocker:** VTK performs exactly **one** `try_run` in this module subset: `VTK_REQUIRE_LARGE_FILE_SUPPORT` at `/opt/toolchains/src/VTK-9.3.1/CMakeLists.txt:130` (`check_cxx_source_runs`, source `CMake/vtkRequireLargeFilesSupport.cxx`). It **compiles+links fine** but **fails to execute** under the emsdk node emulator. Configure log shows: `runResult VTK_REQUIRE_LARGE_FILE_SUPPORT_EXITCODE ... stderr: Invalid opcode 0x1f (enable with --experimental-wasm-exnref)`. Cache now holds `VTK_REQUIRE_LARGE_FILE_SUPPORT_EXITCODE:INTERNAL=1` and `VTK_REQUIRE_LARGE_FILE_SUPPORT:INTERNAL=` (empty/false). Root cause is your own flags: `-sWASM_LEGACY_EXCEPTIONS=0` emits the new `try_table`/exnref EH (opcode `0x1f`), and the bundled node 22.16 doesn't enable exnref by default, so the emulator aborts on instantiate. So the feature check returns a **wrong "failed to run" answer** (LFS silently disabled). It did **not** abort configure, but any future required try_run gated this way would. - **Fix (pick one):** 1. Pre-seed the result in cache before configure — this is exactly VTK's own cross-compile pattern, see `/opt/toolchains/src/VTK-9.3.1/CMake/vtkMobileDevices.cmake:4`: `-DVTK_REQUIRE_LARGE_FILE_SUPPORT:INTERNAL=2` (any truthy value; VTK's mobile toolchain forces `2`). This skips the run entirely. 2. Or point the emulator at a node that enables the opcode: `-DCMAKE_CROSSCOMPILING_EMULATOR="/opt/toolchains/emsdk/node/22.16.0_64bit/bin/node;--experimental-wasm-exnref"`. That makes this (and any other) try_run execute correctly. - **Note:** emcmake **does** auto-set `CMAKE_CROSSCOMPILING_EMULATOR` to node (confirmed in cache: `/opt/toolchains/emsdk/node/22.16.0_64bit/bin/node`), so try_run generally works — the only failure is the EH-opcode mismatch above. Endianness is resolved at **compile time** (`vtkEndian.h` → little-endian, correct), no run needed; `CheckTypeSize`/`__int64`/`environ`/`st_mtimespec` failures in `CMakeError.log` are **benign** platform-probe `try_compile`s, not blockers. - **Confidence:** High (observed directly in this build's `CMakeConfigureLog.yaml`/cache). - **Sources:** [try_run cross-compiling (CMake)](https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html), [exnref / opcode 0x1f = try_table](https://github.com/WebAssembly/exception-handling/issues/280), plus in-tree `CMake/vtkMobileDevices.cmake` and `CMakeLists.txt:130`. --- ### P2 — vtkThreadedCallbackQueue uses std::thread with no `__EMSCRIPTEN__` guard (latent, not a build stopper) - **Area:** Threading / single-threaded (`-sUSE_PTHREADS=0`). - **Blocker:** `VTK::ParallelCore` is being built (pulled in via the StandAlone group — no enabled module hard-depends on it). It contains `/opt/toolchains/src/VTK-9.3.1/Parallel/Core/vtkThreadedCallbackQueue.cxx`, which does `std::thread(...)` (line 142) + `thread.join()` (line 191) and includes `<thread>/<mutex>/<condition_variable>/<atomic>`, with **no emscripten guard**. This **compiles and links** — without `-pthread`, Emscripten links the pthread stub (`library_pthread_stub`) so `std::thread` resolves. It only bites at **runtime** if the queue is actually instantiated and started (modern emscripten's stub `pthread_create` returns error/aborts single-threaded), which a pure data-model pipeline typically never does. - **Fix (optional, cleanest):** Drop the module entirely since nothing you enabled needs it: `-DVTK_MODULE_ENABLE_VTK_ParallelCore=NO` (or `DONT_WANT`). That removes `vtkThreadedCallbackQueue` from the build. Otherwise leave as-is (compiles/links fine) and just don't use it. (In VTK 9.4 this class moved Parallel/Core → Common/Core, so on 9.4+ you can't drop it this way.) - **Confidence:** High that it compiles/links; medium on the exact runtime-abort behavior (version-dependent). - **Sources:** [Emscripten pthreads (stub without -pthread)](https://emscripten.org/docs/porting/pthreads.html), [pthread_create single-thread abort #25738](https://github.com/emscripten-core/emscripten/issues/25738), [VTK docs: threads emulated single-thread without VTK_WEBASSEMBLY_THREADS](https://docs.vtk.org/en/latest/advanced/build_wasm_emscripten.html). --- ### Ruled-out (concretely NOT blockers) — so you don't chase them - **vtkMultiThreader (Q2/Q3):** already emscripten-safe in 9.3.1. `pthread_create` is guarded at `Parallel`... no — at `/opt/toolchains/src/VTK-9.3.1/Common/Core/vtkMultiThreader.cxx:272,400,483` by `#if !defined(__CYGWIN__) && !defined(__EMSCRIPTEN__)`, so it takes the serial path. `vtkThreads.h` defines `VTK_USE_PTHREADS` (harmless — headers/stub present). Confidence: High. - **vtkConditionVariable (Q3):** **does not exist** in VTK 9.3.1 (removed earlier). Nothing to patch. Confidence: High. - **vtkSMPTools/vtkAtomic/vtkCriticalSection (Q2):** `vtkSMP.h` = `VTK_SMP_Sequential` (no thread dispatch). `vtkAtomicMutex.h` (std::atomic), `vtkCriticalSection.h`/`vtkDebugLeaks`/`vtkOutputWindow`/`vtkStringToken` (std::mutex) all compile fine single-threaded (mutexes are effectively no-ops, atomics compile to plain ops). No `VTK_USE_THREADS`/`VTK_ENABLE_KOKKOS` toggles needed. Confidence: High. - **setjmp/longjmp (Q7):** **none** in any enabled first-party module dir, and **none** in the third-party libs the IO subset links (expat, zlib, doubleconversion, lz4, lzma, utf8, pugixml, fmt). The longjmp users (libjpeg/libpng under `ThirdParty/jpeg`,`/png`) exist on disk but are **not compiled** (IOImage disabled). The data-model + IOXML/IOLegacy subset is longjmp-free. Confidence: High. - **IO / filesystem (Q4):** IOCore/IOLegacy/IOXML/IOXMLParser use only `vtksys::SystemTools` + `std::ifstream/ofstream` — no raw `getenv/fopen/tmpnam/mkstemp/realpath/stat/mkdir/popen/system`. All MEMFS-safe. Confidence: High. - **RTTI / exceptions (Q6):** VTK adds **no** `-fno-rtti` (only `-qrtti=all` for IBM XL, at `CMake/vtkCompilerPlatformFlags.cmake:55`), so default RTTI stays on — `dynamic_cast` works. `-fwasm-exceptions` and RTTI don't conflict. `-sDISABLE_EXCEPTION_CATCHING` is **irrelevant** here: it only affects the legacy JS/`-fexceptions` EH mode; with `-fwasm-exceptions` catching is always on and that flag is a no-op. Confidence: High. Source: [Emscripten C++ exceptions](https://emscripten.org/docs/porting/exceptions.html). --- ### Prior art (Q5) - **Official path:** Kitware's WebAssembly rework is recent (Kitware blog dated Aug 2025; the `VTK_WEBASSEMBLY_THREADS` / `VTK_WEBASSEMBLY_64_BIT` CMake vars and the "use the Emscripten SDK" CMake rework land in the **9.4** line). The published `emcmake` recipe is rendering-oriented (`-DVTK_ENABLE_WEBGPU:BOOL=ON`, `-DVTK_WEBASSEMBLY_64_BIT:BOOL=ON`, `-DBUILD_SHARED_LIBS:BOOL=OFF`, `-DCMAKE_BUILD_TYPE=Release`). There is **no published data-model-only recipe** — the correct lever is exactly what you're doing (`VTK_GROUP_ENABLE_Rendering=DONT_WANT`). Data-model modules have compiled to wasm32-emscripten for years; the 9.4 work is mostly rendering/threads/wasm64. VTK 9.3.1 (your version) predates the CMake rework, which is why you're driving it manually — and, per above, it works. - **Sources:** [VTK build_wasm_emscripten docs](https://docs.vtk.org/en/latest/advanced/build_wasm_emscripten.html), [Kitware: Introducing WebAssembly support in VTK](https://www.kitware.com/introducing-webassembly-support-in-vtk/), [Kitware/vtk-wasm](https://github.com/Kitware/vtk-wasm), [VTK 9.4 release notes (ThreadedCallbackQueue moved to Common/Core)](https://github.com/Kitware/VTK/blob/master/Documentation/release/9.4.md). --- ### Bottom line Configure already passed; the build should compile and link with the current flag set. Do the P1 cache pre-seed (`-DVTK_REQUIRE_LARGE_FILE_SUPPORT:INTERNAL=2`, matching `vtkMobileDevices.cmake`) to make the LFS check correct and to harden against any future try_run hitting the exnref/node issue, and optionally add `-DVTK_MODULE_ENABLE_VTK_ParallelCore=NO` to shed the only unguarded `std::thread` user. Everything else in your questions (SMP threads, vtkMultiThreader, vtkConditionVariable, setjmp/longjmp, IO/MEMFS, RTTI, exception-catching flags) is already clean for this exact module subset.