diff --git a/doc/changelog.dox b/doc/changelog.dox index 2f15e84ec8..8e2ed4bf6d 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -189,6 +189,11 @@ See also: allocation function, which changed signature in 2.0.5 and caused runtime failures when `-s ASSERTIONS` was enabled. A public stable API is now used instead, see [mosra/magnum#483](https://github.com/mosra/magnum/pull/483). +- Not too long after the above, Emscripten 2.0.10 doesn't export `dynCall()` + anymore, which caused @ref Platform::EmscriptenApplication to fail at + runtime with an error about `dynCall()` not being defined. A workaround was + put in place that uses `dynCall()` internals, which should be present + always. - Because hardcoding canvas size using @ref Platform::EmscriptenApplication::Configuration::setSize() "Platform::Application::Configuration::setSize()" on WebGL is usually a wrong thing to do, both diff --git a/src/Magnum/Platform/EmscriptenApplication.cpp b/src/Magnum/Platform/EmscriptenApplication.cpp index 978b147d4d..ae75cab592 100644 --- a/src/Magnum/Platform/EmscriptenApplication.cpp +++ b/src/Magnum/Platform/EmscriptenApplication.cpp @@ -799,9 +799,35 @@ void EmscriptenApplication::redraw() { var drawEvent = function() { var id = window.requestAnimationFrame(drawEvent); - /* Call our callback via function pointer returning int with two - int params */ - if(!dynCall('ii', $0, [$1])) { + /* Call our callback via function pointer taking an int and + returning int as well. This used to be + + if(!dynCall('ii', $0, [$1])) { + + but since 2.0.10 the dynCall isn't exported by default anymore: + https://github.com/emscripten-core/emscripten/commit/496967e00735c1523299e116dc692572d3d6d082 + and making it exported again doing so involves crazy shit with + CMake 3.13-only features and a ton of backslashes: + + target_link_options(MagnumEmscriptenApplication INTERFACE + "SHELL:-s \"DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=['\${xylophone}dynCall']\"" + "SHELL:-s \"EXPORTED_FUNCTIONS=['_main', 'dynCall']\"") + + (the ${xylophone} is needed because CMake expands that to + `\$${xylophone}dynCall` for some reason, which then the shell + collapses to `$dynCall` (assuming a $xylophone env var doesn't + exist, which it shoulndn't, but also it's 2021 and so everything + is possible), and no amount of \\\\$$$ helps avoiding that + xylophone); but doing so means we forever hardcode what + functions are exported and thus whatever extra Emscripten needs + to export will be overriden by this, causing only pain and + misery. + + So instead we rely on the implementation details of dynCall, + which are actually really simple: + https://github.com/emscripten-core/emscripten/blob/496967e00735c1523299e116dc692572d3d6d082/src/library.js#L3730-L3747 + and PRAY it doesn't change again in the future. */ + if(!wasmTable.get($0).apply(null, [$1])) { window.cancelAnimationFrame(id); } };