FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
0002 — copySimObjectLibraries uses hasVis where bundlesVisualization is meant
ID 0002
Class BUG
Severity 2
Status blocked
Models
Found 2026-09-20 audit of 581b8091
Decision needed Should --no-bundled-vis against a visualization-enabled playpen bundle the plain SimObject modules (making the flag mean "export a headless FMU"), or should it be refused outright as an unsupported combination?

Evidence

src/fmu/fhFMUexport/ResourceBundler.cpp:413 computes the flag that describes what the FMU will actually contain:

const bool bundlesVisualization = hasVis && !options.noBundledVis;

and passes it to FmuPortMappingReader::Read, which uses it as the start value of the built-in visualization parameter (FmuPortMappingReader.cpp:24-33).

ResourceBundler.cpp:440 then passes plain hasVis — not bundlesVisualization — to copySimObjectLibraries:

if (!copySimObjectLibraries(modelName, paths, plat, layout, liblist, hasVis, options.verbose)) {

and copySimObjectLibraries uses that argument to choose the filename suffix (ResourceBundler.cpp:288-292):

const std::string vis = hasVis ? "Vis" : "";

Meanwhile copyFhSimDlls honours noBundledVis and skips fhVisDll (ResourceBundler.cpp:232-234), and copyOgreLibraries is not called at all (ResourceBundler.cpp:436).

Effect

Exporting with --no-bundled-vis from a playpen that does have visualization produces an FMU containing:

  • fhSimDll but no fhVisDll,
  • no Ogre libraries and no patched resources/plugins.cfg,
  • but the **Vis-suffixed SimObject modules** in binaries/<platform>/SimObjectLibraries/.

The Vis-suffixed modules are built against the visualization build of the engine. With neither fhVisDll nor Ogre present, loading them is expected to fail at the host's first Instantiate, i.e. the export succeeds and the FMU is broken at run time — the failure mode copySimObjectLibraries' own up-front existence check was written to prevent for the missing-library case.

This is not hit by the test suite: tests/cmake/fmu_export.cmake passes --no-bundled-vis only in configurations built without visualization, where hasVis is false and the two expressions agree.

Possible fix

  1. Pass bundlesVisualization instead of hasVis at ResourceBundler.cpp:440. The flag then means "export a headless FMU from whichever playpen you have", which matches its documented description in doc/user/using-the-api/fmu-export.md ("Skip bundling the visualization/Ogre binaries in the FMU, <strong>and</strong> export the <tt>visualization</tt> parameter with a start value of <tt>false</tt>"). Requires that a Vis playpen also carries the plain SimObject modules; if it does not, the existence check fails the export cleanly instead of producing a broken FMU.
  2. Refuse the combination: error when hasVis && options.noBundledVis, directing the user to a NoVis playpen. Smaller change, but removes a documented capability.

Option 1 is the one the documentation already promises. Which is correct depends on whether a visualization-enabled playpen ships both suffixed and plain SimObject modules — that is the owner question above.

Test that would prove it

Build a playpen with visualization enabled. Export any model with --no-bundled-vis, unzip the result, and assert that binaries/<platform>/SimObjectLibraries/ contains no file whose stem ends in Vis. The assertion fails at HEAD. A run-time proof is to import the FMU with fmpy and call Instantiate, which should fail to resolve the visualization symbols.

Risk

Option 1 changes what --no-bundled-vis produces for anyone exporting from a Vis playpen. Since that output is believed broken today, no working workflow should depend on it — but that belief is exactly what the test above must confirm before the change lands.