Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Web] Fix thread+dlink builds with emscripten 3.1.61+git #93143

Merged
merged 4 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions platform/web/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -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"])
Expand Down
54 changes: 29 additions & 25 deletions platform/web/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"]:
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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'"])
adamscott marked this conversation as resolved.
Show resolved Hide resolved

# 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"])
5 changes: 4 additions & 1 deletion platform/web/js/engine/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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']);
Expand All @@ -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')) {
Expand Down
24 changes: 9 additions & 15 deletions platform/web/js/engine/engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
});
},
Expand Down
2 changes: 2 additions & 0 deletions thirdparty/thorvg/inc/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions thirdparty/thorvg/update-thorvg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading