FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
0139 — The environment library links the static FhSim::fhsim_vis, so it carries its own copy of the engine
ID 0139
Class ARCHITECTURE
Severity 2
Status blocked

Models: —

Found: 2026-10-27, while writing the fhsim v3 migration guide (fhsim FHSIM-0073, item 12); same pattern as fhsim_maritime MAR-0064

Decision needed: confirm the defect first (the test below), then choose how the library gets the rendering code: link only FhSim::simobject (as fhsim_base does), or keep fhsim_vis and accept a second engine in the library.

Evidence

  • src/environment/CMakeLists.txt:90-92: with visualization, target_link_libraries(${TARGET} PUBLIC FhSim::fhsim_vis) on the library environment. conanfile.py:17 is package_type = "shared-library", so environment is a shared library. The plugin fhsim_environment (MODULE, src/CMakeLists.txt:22-23) links environment.
  • The link is PUBLIC, so it also reaches the consumers that link environment: fhsim_marine_elements, fhsim_base, fhsim_fishery, fhsim_gauss (doc/agents/dependencies.md in fhsim_workspace).
  • fhsim: fhsim_vis is a static library that requires the component fhsim (conanfile.py:561), and fhsim is add_library(fhsim STATIC) (src/engine/CMakeLists.txt:1). So the library carries its own copy of the engine and of its static data.
  • fhsim's own module fhsim_vis_dll does not link fhsim_vis for this reason (src/visual/dll/module/CMakeLists.txt:16-18: "that would double-instantiate its static globals ... causing crashes").
  • fhsim_base renders without it: its plugin links only FhSim::simobject, which brings ogrederived with visualization (fhsim conanfile.py:476-491).
  • The rendering code here is in Environment.{h,cpp}, VisualField*.cpp and VisualWakeSources.{h,cpp}.

Not yet shown by a failing run: no crash or wrong value is known today.

Effect

A static object that should exist once (an engine singleton, a registry, a logger) exists twice: once in the host and once in the library. The library then reads or writes its own copy. In the worst case this crashes, as the fhsim comment says. Today it is only a risk; the library is also larger than it needs to be.

Possible fix

  1. Link environment only to FhSim::simobject, as fhsim_base does. Check which symbols it needs from fhsim_vis (nm -C --undefined-only on the library built without it).
  2. Keep the link and document why it is safe.

Fix this together with MAR-0064 (same choice).

Test that would prove it

Build with visualization and list the engine symbols the library defines (nm -C --defined-only libenvironment.so | grep FhSimMgr). Then a FhVis run of an environment example with a SimObject that reads a shared resource set by the host.

Risk

Low for the change itself. Option 1 changes the link interface that the four consumers see, so they need a downstream build with visualization.