diff --git a/platform/web/SCsub b/platform/web/SCsub index fea2fa7df95a..3d36a888d6dd 100644 --- a/platform/web/SCsub +++ b/platform/web/SCsub @@ -65,8 +65,8 @@ if env["dlink_enabled"]: # We use IDBFS. Since Emscripten 1.39.1 it needs to be linked explicitly. sys_env.Append(LIBS=["idbfs.js"]) # Configure it as a main module (dynamic linking support). - sys_env["CCFLAGS"].remove("SIDE_MODULE=2") - sys_env["LINKFLAGS"].remove("SIDE_MODULE=2") + sys_env["CCFLAGS"].remove("-sSIDE_MODULE=2") + sys_env["LINKFLAGS"].remove("-sSIDE_MODULE=2") sys_env.Append(CCFLAGS=["-s", "MAIN_MODULE=1"]) sys_env.Append(LINKFLAGS=["-s", "MAIN_MODULE=1"]) sys_env.Append(LINKFLAGS=["-s", "EXPORT_ALL=1"]) diff --git a/platform/web/detect.py b/platform/web/detect.py index a9be1471ae3a..1b15ff8e2ea8 100644 --- a/platform/web/detect.py +++ b/platform/web/detect.py @@ -107,13 +107,13 @@ def configure(env: "SConsEnvironment"): env["use_assertions"] = True if env["use_assertions"]: - env.Append(LINKFLAGS=["-s", "ASSERTIONS=1"]) + env.Append(LINKFLAGS=["-sASSERTIONS=1"]) if env.editor_build and env["initial_memory"] < 64: print("Note: Forcing `initial_memory=64` as it is required for the web editor.") env["initial_memory"] = 64 - env.Append(LINKFLAGS=["-s", "INITIAL_MEMORY=%sMB" % env["initial_memory"]]) + env.Append(LINKFLAGS=["-sINITIAL_MEMORY=%sMB" % env["initial_memory"]]) ## Copy env variables. env["ENV"] = os.environ @@ -142,7 +142,7 @@ def configure(env: "SConsEnvironment"): env.Append(CCFLAGS=["-fsanitize=leak"]) env.Append(LINKFLAGS=["-fsanitize=leak"]) if env["use_safe_heap"]: - env.Append(LINKFLAGS=["-s", "SAFE_HEAP=1"]) + env.Append(LINKFLAGS=["-sSAFE_HEAP=1"]) # Closure compiler if env["use_closure_compiler"]: @@ -204,29 +204,29 @@ def configure(env: "SConsEnvironment"): if env["opengl3"]: env.AppendUnique(CPPDEFINES=["GLES3_ENABLED"]) # This setting just makes WebGL 2 APIs available, it does NOT disable WebGL 1. - env.Append(LINKFLAGS=["-s", "MAX_WEBGL_VERSION=2"]) + env.Append(LINKFLAGS=["-sMAX_WEBGL_VERSION=2"]) # Allow use to take control of swapping WebGL buffers. - env.Append(LINKFLAGS=["-s", "OFFSCREEN_FRAMEBUFFER=1"]) + env.Append(LINKFLAGS=["-sOFFSCREEN_FRAMEBUFFER=1"]) # Breaking change since emscripten 3.1.51 # https://github.com/emscripten-core/emscripten/blob/main/ChangeLog.md#3151---121323 if cc_semver >= (3, 1, 51): # Enables the use of *glGetProcAddress() - env.Append(LINKFLAGS=["-s", "GL_ENABLE_GET_PROC_ADDRESS=1"]) + env.Append(LINKFLAGS=["-sGL_ENABLE_GET_PROC_ADDRESS=1"]) if env["javascript_eval"]: env.Append(CPPDEFINES=["JAVASCRIPT_EVAL_ENABLED"]) stack_size_opt = "STACK_SIZE" if cc_semver >= (3, 1, 25) else "TOTAL_STACK" - env.Append(LINKFLAGS=["-s", "%s=%sKB" % (stack_size_opt, env["stack_size"])]) + env.Append(LINKFLAGS=["-s%s=%sKB" % (stack_size_opt, env["stack_size"])]) if env["threads"]: # Thread support (via SharedArrayBuffer). env.Append(CPPDEFINES=["PTHREAD_NO_RENAME"]) - env.Append(CCFLAGS=["-s", "USE_PTHREADS=1"]) - env.Append(LINKFLAGS=["-s", "USE_PTHREADS=1"]) - env.Append(LINKFLAGS=["-s", "DEFAULT_PTHREAD_STACK_SIZE=%sKB" % env["default_pthread_stack_size"]]) - env.Append(LINKFLAGS=["-s", "PTHREAD_POOL_SIZE=8"]) - env.Append(LINKFLAGS=["-s", "WASM_MEM_MAX=2048MB"]) + env.Append(CCFLAGS=["-sUSE_PTHREADS=1"]) + env.Append(LINKFLAGS=["-sUSE_PTHREADS=1"]) + env.Append(LINKFLAGS=["-sDEFAULT_PTHREAD_STACK_SIZE=%sKB" % env["default_pthread_stack_size"]]) + env.Append(LINKFLAGS=["-sPTHREAD_POOL_SIZE=8"]) + env.Append(LINKFLAGS=["-sWASM_MEM_MAX=2048MB"]) elif env["proxy_to_pthread"]: print_warning('"threads=no" support requires "proxy_to_pthread=no", disabling proxy to pthread.') env["proxy_to_pthread"] = False @@ -248,8 +248,8 @@ def configure(env: "SConsEnvironment"): print_error("GDExtension support requires emscripten >= 3.1.14, detected: %s.%s.%s" % cc_semver) sys.exit(255) - env.Append(CCFLAGS=["-s", "SIDE_MODULE=2"]) - env.Append(LINKFLAGS=["-s", "SIDE_MODULE=2"]) + env.Append(CCFLAGS=["-sSIDE_MODULE=2"]) + env.Append(LINKFLAGS=["-sSIDE_MODULE=2"]) env.Append(CCFLAGS=["-fvisibility=hidden"]) env.Append(LINKFLAGS=["-fvisibility=hidden"]) env.extra_suffix = ".dlink" + env.extra_suffix @@ -259,37 +259,41 @@ def configure(env: "SConsEnvironment"): # Run the main application in a web worker if env["proxy_to_pthread"]: - env.Append(LINKFLAGS=["-s", "PROXY_TO_PTHREAD=1"]) + env.Append(LINKFLAGS=["-sPROXY_TO_PTHREAD=1"]) env.Append(CPPDEFINES=["PROXY_TO_PTHREAD_ENABLED"]) - env.Append(LINKFLAGS=["-s", "EXPORTED_RUNTIME_METHODS=['_emscripten_proxy_main']"]) + env.Append(LINKFLAGS=["-sEXPORTED_RUNTIME_METHODS=['_emscripten_proxy_main']"]) # https://github.com/emscripten-core/emscripten/issues/18034#issuecomment-1277561925 - env.Append(LINKFLAGS=["-s", "TEXTDECODER=0"]) + env.Append(LINKFLAGS=["-sTEXTDECODER=0"]) # BigInt support to pass object pointers between contexts needs_wasm_bigint = True if needs_wasm_bigint: - env.Append(LINKFLAGS=["-s", "WASM_BIGINT"]) + env.Append(LINKFLAGS=["-sWASM_BIGINT"]) # Reduce code size by generating less support code (e.g. skip NodeJS support). - env.Append(LINKFLAGS=["-s", "ENVIRONMENT=web,worker"]) + env.Append(LINKFLAGS=["-sENVIRONMENT=web,worker"]) # Wrap the JavaScript support code around a closure named Godot. - env.Append(LINKFLAGS=["-s", "MODULARIZE=1", "-s", "EXPORT_NAME='Godot'"]) + env.Append(LINKFLAGS=["-sMODULARIZE=1", "-sEXPORT_NAME='Godot'"]) + + # Force long jump mode to 'wasm' + env.Append(CCFLAGS=["-sSUPPORT_LONGJMP='wasm'"]) + env.Append(LINKFLAGS=["-sSUPPORT_LONGJMP='wasm'"]) # Allow increasing memory buffer size during runtime. This is efficient # when using WebAssembly (in comparison to asm.js) and works well for # us since we don't know requirements at compile-time. - env.Append(LINKFLAGS=["-s", "ALLOW_MEMORY_GROWTH=1"]) + env.Append(LINKFLAGS=["-sALLOW_MEMORY_GROWTH=1"]) # Do not call main immediately when the support code is ready. - env.Append(LINKFLAGS=["-s", "INVOKE_RUN=0"]) + env.Append(LINKFLAGS=["-sINVOKE_RUN=0"]) # callMain for manual start, cwrap for the mono version. - env.Append(LINKFLAGS=["-s", "EXPORTED_RUNTIME_METHODS=['callMain','cwrap']"]) + env.Append(LINKFLAGS=["-sEXPORTED_RUNTIME_METHODS=['callMain','cwrap']"]) # Add code that allow exiting runtime. - env.Append(LINKFLAGS=["-s", "EXIT_RUNTIME=1"]) + env.Append(LINKFLAGS=["-sEXIT_RUNTIME=1"]) # This workaround creates a closure that prevents the garbage collector from freeing the WebGL context. # We also only use WebGL2, and changing context version is not widely supported anyway. - env.Append(LINKFLAGS=["-s", "GL_WORKAROUND_SAFARI_GETCONTEXT_BUG=0"]) + env.Append(LINKFLAGS=["-sGL_WORKAROUND_SAFARI_GETCONTEXT_BUG=0"]) diff --git a/platform/web/js/engine/config.js b/platform/web/js/engine/config.js index a7134da6faa9..8c4e1b1b2480 100644 --- a/platform/web/js/engine/config.js +++ b/platform/web/js/engine/config.js @@ -271,12 +271,13 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused- */ Config.prototype.getModuleConfig = function (loadPath, response) { let r = response; + const gdext = this.gdextensionLibs; return { 'print': this.onPrint, 'printErr': this.onPrintError, 'thisProgram': this.executable, 'noExitRuntime': false, - 'dynamicLibraries': [`${loadPath}.side.wasm`], + 'dynamicLibraries': [`${loadPath}.side.wasm`].concat(this.gdextensionLibs), 'instantiateWasm': function (imports, onSuccess) { function done(result) { onSuccess(result['instance'], result['module']); @@ -300,6 +301,8 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused- return `${loadPath}.audio.worklet.js`; } else if (path.endsWith('.js')) { return `${loadPath}.js`; + } else if (path in gdext) { + return path; } else if (path.endsWith('.side.wasm')) { return `${loadPath}.side.wasm`; } else if (path.endsWith('.wasm')) { diff --git a/platform/web/js/engine/engine.js b/platform/web/js/engine/engine.js index 7e24ad9ae232..04c4c44c5eee 100644 --- a/platform/web/js/engine/engine.js +++ b/platform/web/js/engine/engine.js @@ -163,25 +163,19 @@ const Engine = (function () { me.rtenv['initConfig'](config); // Preload GDExtension libraries. - const libs = []; if (me.config.gdextensionLibs.length > 0 && !me.rtenv['loadDynamicLibrary']) { return Promise.reject(new Error('GDExtension libraries are not supported by this engine version. ' + 'Enable "Extensions Support" for your export preset and/or build your custom template with "dlink_enabled=yes".')); } - me.config.gdextensionLibs.forEach(function (lib) { - libs.push(me.rtenv['loadDynamicLibrary'](lib, { 'loadAsync': true })); - }); - return Promise.all(libs).then(function () { - return new Promise(function (resolve, reject) { - preloader.preloadedFiles.forEach(function (file) { - me.rtenv['copyToFS'](file.path, file.buffer); - }); - preloader.preloadedFiles.length = 0; // Clear memory - me.rtenv['callMain'](me.config.args); - initPromise = null; - me.installServiceWorker(); - resolve(); - }); + return new Promise(function (resolve, reject) { + for (const file of preloader.preloadedFiles) { + me.rtenv['copyToFS'](file.path, file.buffer); + } + preloader.preloadedFiles.length = 0; // Clear memory + me.rtenv['callMain'](me.config.args); + initPromise = null; + me.installServiceWorker(); + resolve(); }); }); }, diff --git a/thirdparty/thorvg/inc/config.h b/thirdparty/thorvg/inc/config.h index 699076fdf1a8..e2a61a9384ac 100644 --- a/thirdparty/thorvg/inc/config.h +++ b/thirdparty/thorvg/inc/config.h @@ -5,7 +5,9 @@ #define THORVG_SVG_LOADER_SUPPORT #define THORVG_PNG_LOADER_SUPPORT #define THORVG_JPG_LOADER_SUPPORT +#ifndef WEB_ENABLED #define THORVG_THREAD_SUPPORT +#endif // Added conditionally if webp module is enabled. //#define THORVG_WEBP_LOADER_SUPPORT diff --git a/thirdparty/thorvg/update-thorvg.sh b/thirdparty/thorvg/update-thorvg.sh index c980b89c4b60..c0034ba888eb 100755 --- a/thirdparty/thorvg/update-thorvg.sh +++ b/thirdparty/thorvg/update-thorvg.sh @@ -38,7 +38,9 @@ cat << EOF > ../inc/config.h #define THORVG_SVG_LOADER_SUPPORT #define THORVG_PNG_LOADER_SUPPORT #define THORVG_JPG_LOADER_SUPPORT +#ifndef WEB_ENABLED #define THORVG_THREAD_SUPPORT +#endif // Added conditionally if webp module is enabled. //#define THORVG_WEBP_LOADER_SUPPORT