From 09f38d987a09d29aec19a3983e697637e7c09722 Mon Sep 17 00:00:00 2001 From: Carlo van Driesten Date: Sun, 26 Jul 2026 16:58:59 +0000 Subject: [PATCH 1/4] fix(build): support Emscripten as a target platform Emscripten defines __unix__ but not __linux__, and is matched by none of the existing platform branches. All three files below therefore fall through to their #error fallback, so the library cannot be compiled to WebAssembly at all: - cpp/openScenarioLib/src/common/ExportDefinitions.h - cpp/expressionsLib/inc/OscExprExportDefs.h - cpp/openScenarioLib/src/loader/FileResourceLocator.cpp Add an __EMSCRIPTEN__ branch to the two symbol-visibility chains (no visibility attribute is needed, as for __APPLE__), and accept __EMSCRIPTEN__ in the POSIX branch of FileResourceLocator, which already handles Linux and macOS identically and needs no change beyond the guard. Verified that the preprocessor chains resolve under -D__EMSCRIPTEN__ and that the existing Windows, Linux and macOS branches are reached exactly as before. Signed-off-by: Carlo van Driesten --- cpp/expressionsLib/inc/OscExprExportDefs.h | 2 ++ cpp/openScenarioLib/src/common/ExportDefinitions.h | 2 ++ cpp/openScenarioLib/src/loader/FileResourceLocator.cpp | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/cpp/expressionsLib/inc/OscExprExportDefs.h b/cpp/expressionsLib/inc/OscExprExportDefs.h index 1f24fbc3..4b34379e 100644 --- a/cpp/expressionsLib/inc/OscExprExportDefs.h +++ b/cpp/expressionsLib/inc/OscExprExportDefs.h @@ -35,6 +35,8 @@ # endif #elif defined(__APPLE__) # define OSC_EXPR_EXP +#elif defined(__EMSCRIPTEN__) +# define OSC_EXPR_EXP #else # error "OPENSCENARIOLIB: Operating system not supported." #endif // _WIN32 diff --git a/cpp/openScenarioLib/src/common/ExportDefinitions.h b/cpp/openScenarioLib/src/common/ExportDefinitions.h index 2b0dfb2d..0e46f766 100644 --- a/cpp/openScenarioLib/src/common/ExportDefinitions.h +++ b/cpp/openScenarioLib/src/common/ExportDefinitions.h @@ -19,6 +19,8 @@ # endif #elif defined(__APPLE__) # define OPENSCENARIOLIB_EXP +#elif defined(__EMSCRIPTEN__) +# define OPENSCENARIOLIB_EXP #else # error "OPENSCENARIOLIB: Operating system not supported." #endif // _WIN32 diff --git a/cpp/openScenarioLib/src/loader/FileResourceLocator.cpp b/cpp/openScenarioLib/src/loader/FileResourceLocator.cpp index 7a9e7600..b8d7d6ad 100644 --- a/cpp/openScenarioLib/src/loader/FileResourceLocator.cpp +++ b/cpp/openScenarioLib/src/loader/FileResourceLocator.cpp @@ -41,7 +41,7 @@ namespace NET_ASAM_OPENSCENARIO } auto infile = std::make_shared(result.c_str(), std::ios::binary); -#elif defined (__linux__) || defined (__APPLE__) +#elif defined (__linux__) || defined (__APPLE__) || defined (__EMSCRIPTEN__) auto infile = std::make_shared(symbolicFilename, std::ios::binary); #else # error "Operating system not supported." From 65abbab9ec53ea4475c17896799957dc773957ad Mon Sep 17 00:00:00 2001 From: Carlo van Driesten Date: Mon, 27 Jul 2026 07:57:52 +0200 Subject: [PATCH 2/4] fix(build): support Emscripten in the vendored ghc::filesystem copy cpp/externalLibs/Filesystem/filesystem.hpp is a vendored copy of gulrak/filesystem v1.3.2 (GHC_FILESYSTEM_VERSION 10302L), which predates that library's Emscripten support. Emscripten defines __unix__ but not __linux__, and none of the branches in the GHC_OS_DETECTED chain match it, so the header stops at #error "Operating system currently not supported!" and the library cannot be compiled to WebAssembly. Map __EMSCRIPTEN__ onto the existing GHC_OS_LINUX branch: Emscripten's POSIX layer provides everything that branch selects. The new #elif is unreachable unless __EMSCRIPTEN__ is defined, so no existing platform changes preprocessor state and no behaviour changes for any current target. Upstream ghc::filesystem handles Emscripten natively as of v1.5.x (it defines GHC_OS_WEB), so bumping the vendored copy would remove the need for this edit. This commit is the minimal alternative to that bump. Signed-off-by: Carlo van Driesten --- cpp/externalLibs/Filesystem/filesystem.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cpp/externalLibs/Filesystem/filesystem.hpp b/cpp/externalLibs/Filesystem/filesystem.hpp index 1f0fe392..f92b9c3d 100644 --- a/cpp/externalLibs/Filesystem/filesystem.hpp +++ b/cpp/externalLibs/Filesystem/filesystem.hpp @@ -64,6 +64,8 @@ #define GHC_OS_SYS5R4 #elif defined(BSD) #define GHC_OS_BSD +#elif defined(__EMSCRIPTEN__) +#define GHC_OS_LINUX #else #error "Operating system currently not supported!" #endif From f35423991efd0cf3f58f5471ba42dab2d6eb9067 Mon Sep 17 00:00:00 2001 From: Carlo van Driesten Date: Mon, 27 Jul 2026 08:59:12 +0200 Subject: [PATCH 3/4] fix(loader): pass injected parameters through the import loader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit XmlScenarioImportLoader::Load(messageLogger, injectedParameters) forwards to the inner loader's single-argument overload, so the injected parameter map is dropped before parameter resolution ever sees it. Every embedder that resolves catalogs loses parameter injection silently — including openScenarioReader, which reads its -p parameter file, echoes the parameters it found, and then resolves the scenario as if none had been given, because CheckFile always goes through ExecuteImportParsingV1_x. Forward the map to the inner loader. The same line is affected in all four version loaders (v1_0, v1_1, v1_2, v1_3); the non-import XmlScenarioLoaderFactory path was already correct, which is why the behaviour depends on whether catalogs are resolved. Signed-off-by: Carlo van Driesten --- .../src/v1_0/loader/XmlScenarioImportLoaderV1_0.cpp | 2 +- .../src/v1_1/loader/XmlScenarioImportLoaderV1_1.cpp | 2 +- .../src/v1_2/loader/XmlScenarioImportLoaderV1_2.cpp | 2 +- .../src/v1_3/loader/XmlScenarioImportLoaderV1_3.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cpp/openScenarioLib/src/v1_0/loader/XmlScenarioImportLoaderV1_0.cpp b/cpp/openScenarioLib/src/v1_0/loader/XmlScenarioImportLoaderV1_0.cpp index 8942eff2..9ace8ca4 100644 --- a/cpp/openScenarioLib/src/v1_0/loader/XmlScenarioImportLoaderV1_0.cpp +++ b/cpp/openScenarioLib/src/v1_0/loader/XmlScenarioImportLoaderV1_0.cpp @@ -50,7 +50,7 @@ namespace NET_ASAM_OPENSCENARIO std::shared_ptr XmlScenarioImportLoader::Load(std::shared_ptr messageLogger, std::map& injectedParameters) { - auto openScenario = std::static_pointer_cast(_innerScenarioLoader->Load(messageLogger)->GetAdapter(typeid(IOpenScenario).name())); + auto openScenario = std::static_pointer_cast(_innerScenarioLoader->Load(messageLogger, injectedParameters)->GetAdapter(typeid(IOpenScenario).name())); if (messageLogger->GetMessagesFilteredByWorseOrEqualToErrorLevel(ErrorLevel::ERROR).empty()) { diff --git a/cpp/openScenarioLib/src/v1_1/loader/XmlScenarioImportLoaderV1_1.cpp b/cpp/openScenarioLib/src/v1_1/loader/XmlScenarioImportLoaderV1_1.cpp index fcd5963d..82dbc2fc 100644 --- a/cpp/openScenarioLib/src/v1_1/loader/XmlScenarioImportLoaderV1_1.cpp +++ b/cpp/openScenarioLib/src/v1_1/loader/XmlScenarioImportLoaderV1_1.cpp @@ -51,7 +51,7 @@ namespace NET_ASAM_OPENSCENARIO std::shared_ptr XmlScenarioImportLoader::Load(std::shared_ptr messageLogger, std::map& injectedParameters) { - auto openScenario = std::static_pointer_cast(_innerScenarioLoader->Load(messageLogger)->GetAdapter(typeid(IOpenScenario).name())); + auto openScenario = std::static_pointer_cast(_innerScenarioLoader->Load(messageLogger, injectedParameters)->GetAdapter(typeid(IOpenScenario).name())); if (messageLogger->GetMessagesFilteredByWorseOrEqualToErrorLevel(ErrorLevel::ERROR).empty()) { diff --git a/cpp/openScenarioLib/src/v1_2/loader/XmlScenarioImportLoaderV1_2.cpp b/cpp/openScenarioLib/src/v1_2/loader/XmlScenarioImportLoaderV1_2.cpp index 566df15d..4abfe617 100644 --- a/cpp/openScenarioLib/src/v1_2/loader/XmlScenarioImportLoaderV1_2.cpp +++ b/cpp/openScenarioLib/src/v1_2/loader/XmlScenarioImportLoaderV1_2.cpp @@ -52,7 +52,7 @@ namespace NET_ASAM_OPENSCENARIO std::shared_ptr XmlScenarioImportLoader::Load(std::shared_ptr messageLogger, std::map& injectedParameters) { - auto openScenario = std::static_pointer_cast(_innerScenarioLoader->Load(messageLogger)->GetAdapter(typeid(IOpenScenario).name())); + auto openScenario = std::static_pointer_cast(_innerScenarioLoader->Load(messageLogger, injectedParameters)->GetAdapter(typeid(IOpenScenario).name())); if (messageLogger->GetMessagesFilteredByWorseOrEqualToErrorLevel(ErrorLevel::ERROR).empty()) { diff --git a/cpp/openScenarioLib/src/v1_3/loader/XmlScenarioImportLoaderV1_3.cpp b/cpp/openScenarioLib/src/v1_3/loader/XmlScenarioImportLoaderV1_3.cpp index 3062b272..d0c268e9 100644 --- a/cpp/openScenarioLib/src/v1_3/loader/XmlScenarioImportLoaderV1_3.cpp +++ b/cpp/openScenarioLib/src/v1_3/loader/XmlScenarioImportLoaderV1_3.cpp @@ -52,7 +52,7 @@ namespace NET_ASAM_OPENSCENARIO std::shared_ptr XmlScenarioImportLoader::Load(std::shared_ptr messageLogger, std::map& injectedParameters) { - auto openScenario = std::static_pointer_cast(_innerScenarioLoader->Load(messageLogger)->GetAdapter(typeid(IOpenScenario).name())); + auto openScenario = std::static_pointer_cast(_innerScenarioLoader->Load(messageLogger, injectedParameters)->GetAdapter(typeid(IOpenScenario).name())); if (messageLogger->GetMessagesFilteredByWorseOrEqualToErrorLevel(ErrorLevel::ERROR).empty()) { From e40188b0585dadbc4b35fe7d10748030672e8f57 Mon Sep 17 00:00:00 2001 From: Carlo van Driesten Date: Mon, 27 Jul 2026 07:59:31 +0200 Subject: [PATCH 4/4] Shim FE_OVERFLOW/FE_UNDERFLOW to 0 under Emscripten (carry-only) Emscripten's does not define these macros, so EvaluatorListener.cpp does not compile for a WebAssembly target. Shimming them to 0 makes the surrounding feclearexcept/fetestexcept calls no-ops, which means overflow/underflow detection in the expression evaluator is disabled in this build. That is a correctness trade-off rather than a portability fix, so it is not offered upstream as a pull request. It is raised as upstream issue #229 (EvaluatorListener uses FE_OVERFLOW/FE_UNDERFLOW, which Emscripten's does not provide) and carried here until upstream decides the contract for targets without an FP-exception environment. Signed-off-by: Carlo van Driesten --- cpp/expressionsLib/src/EvaluatorListener.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cpp/expressionsLib/src/EvaluatorListener.cpp b/cpp/expressionsLib/src/EvaluatorListener.cpp index e00b2fdc..45476350 100644 --- a/cpp/expressionsLib/src/EvaluatorListener.cpp +++ b/cpp/expressionsLib/src/EvaluatorListener.cpp @@ -26,6 +26,18 @@ #include #include +#if defined(__EMSCRIPTEN__) +// WASM has no floating-point exception environment; FE_OVERFLOW/FE_UNDERFLOW +// are not provided by Emscripten's . Shim to 0 so feclearexcept/ +// fetestexcept compile to no-ops (overflow/underflow detection is disabled). +# ifndef FE_OVERFLOW +# define FE_OVERFLOW 0 +# endif +# ifndef FE_UNDERFLOW +# define FE_UNDERFLOW 0 +# endif +#endif + namespace OscExpression {