diff --git a/emcc.py b/emcc.py index 341cdafbe3824..0e65b3d4f12fb 100644 --- a/emcc.py +++ b/emcc.py @@ -1310,7 +1310,7 @@ def consume_arg_file(): options.memory_profiler = True newargs[i] = '' settings_changes.append('EMSCRIPTEN_TRACING=1') - settings.JS_LIBRARIES.append('library_trace.js') + settings.JS_LIBRARIES.append('libtrace.js') elif check_flag('--emit-symbol-map'): options.emit_symbol_map = True settings.EMIT_SYMBOL_MAP = 1 diff --git a/eslint.config.mjs b/eslint.config.mjs index d4351c9f2ef39..d5386faa4a930 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -26,7 +26,7 @@ export default [{ '**/third_party/', '**/test/', 'src/polyfill/', - 'src/library*.js', + 'src/lib/', 'src/runtime_*.js', 'src/shell*.js', 'src/preamble*.js', diff --git a/src/jsifier.mjs b/src/jsifier.mjs index 65de64f18c13f..6099e29b6e83a 100644 --- a/src/jsifier.mjs +++ b/src/jsifier.mjs @@ -585,7 +585,7 @@ function(${args}) { return dep(); } // $noExitRuntime is special since there are conditional usages of it - // in library.js and library_pthread.js. These happen before deps are + // in libcore.js and libpthread.js. These happen before deps are // processed so depending on it via `__deps` doesn't work. if (dep === '$noExitRuntime') { error( diff --git a/src/library_addfunction.js b/src/lib/libaddfunction.js similarity index 100% rename from src/library_addfunction.js rename to src/lib/libaddfunction.js diff --git a/src/library_async.js b/src/lib/libasync.js similarity index 100% rename from src/library_async.js rename to src/lib/libasync.js diff --git a/src/library_atomic.js b/src/lib/libatomic.js similarity index 100% rename from src/library_atomic.js rename to src/lib/libatomic.js diff --git a/src/library_autodebug.js b/src/lib/libautodebug.js similarity index 100% rename from src/library_autodebug.js rename to src/lib/libautodebug.js diff --git a/src/library_bootstrap.js b/src/lib/libbootstrap.js similarity index 95% rename from src/library_bootstrap.js rename to src/lib/libbootstrap.js index 8f5ace600aeb2..6ac6208cf93e5 100644 --- a/src/library_bootstrap.js +++ b/src/lib/libbootstrap.js @@ -8,7 +8,7 @@ // it itself depends on the struct info information. #if !BOOTSTRAPPING_STRUCT_INFO -assert(false, "library_bootstrap.js only designed for use with BOOTSTRAPPING_STRUCT_INFO") +assert(false, "libbootstrap.js only designed for use with BOOTSTRAPPING_STRUCT_INFO") #endif assert(Object.keys(LibraryManager.library).length === 0); diff --git a/src/library_browser.js b/src/lib/libbrowser.js similarity index 99% rename from src/library_browser.js rename to src/lib/libbrowser.js index 721a27df7f996..48077e15ecd62 100644 --- a/src/library_browser.js +++ b/src/lib/libbrowser.js @@ -203,7 +203,7 @@ var LibraryBrowser = { alpha: false, #if MIN_WEBGL_VERSION >= 2 majorVersion: 2, -#elif MAX_WEBGL_VERSION >= 2 // library_browser.js defaults: use the WebGL version chosen at compile time (unless overridden below) +#elif MAX_WEBGL_VERSION >= 2 // libbrowser.js defaults: use the WebGL version chosen at compile time (unless overridden below) majorVersion: (typeof WebGL2RenderingContext != 'undefined') ? 2 : 1, #else majorVersion: 1, diff --git a/src/library_c_preprocessor.js b/src/lib/libc_preprocessor.js similarity index 100% rename from src/library_c_preprocessor.js rename to src/lib/libc_preprocessor.js diff --git a/src/library_ccall.js b/src/lib/libccall.js similarity index 100% rename from src/library_ccall.js rename to src/lib/libccall.js diff --git a/src/library.js b/src/lib/libcore.js similarity index 100% rename from src/library.js rename to src/lib/libcore.js diff --git a/src/library_dylink.js b/src/lib/libdylink.js similarity index 100% rename from src/library_dylink.js rename to src/lib/libdylink.js diff --git a/src/library_egl.js b/src/lib/libegl.js similarity index 100% rename from src/library_egl.js rename to src/lib/libegl.js diff --git a/src/embind/embind.js b/src/lib/libembind.js similarity index 99% rename from src/embind/embind.js rename to src/lib/libembind.js index e46658623d88e..62a11711938d9 100644 --- a/src/embind/embind.js +++ b/src/lib/libembind.js @@ -25,7 +25,7 @@ /*global throwInstanceAlreadyDeleted, shallowCopyInternalPointer*/ /*global RegisteredPointer_fromWireType, constNoSmartPtrRawPointerToWireType, nonConstNoSmartPtrRawPointerToWireType, genericPointerToWireType*/ -#include "embind_shared.js" +#include "libembind_shared.js" var LibraryEmbind = { $UnboundTypeError__postset: "UnboundTypeError = Module['UnboundTypeError'] = extendError(Error, 'UnboundTypeError');", diff --git a/src/embind/embind_gen.js b/src/lib/libembind_gen.js similarity index 99% rename from src/embind/embind_gen.js rename to src/lib/libembind_gen.js index 49a754549d9e9..557bf79dc027e 100644 --- a/src/embind/embind_gen.js +++ b/src/lib/libembind_gen.js @@ -2,7 +2,7 @@ // Emscripten is available under two separate licenses, the MIT license and the // University of Illinois/NCSA Open Source License. Both these licenses can be // found in the LICENSE file. -#include "embind_shared.js" +#include "libembind_shared.js" var LibraryEmbind = { diff --git a/src/embind/embind_shared.js b/src/lib/libembind_shared.js similarity index 100% rename from src/embind/embind_shared.js rename to src/lib/libembind_shared.js diff --git a/src/embind/emval.js b/src/lib/libemval.js similarity index 100% rename from src/embind/emval.js rename to src/lib/libemval.js diff --git a/src/library_eventloop.js b/src/lib/libeventloop.js similarity index 100% rename from src/library_eventloop.js rename to src/lib/libeventloop.js diff --git a/src/library_exceptions.js b/src/lib/libexceptions.js similarity index 100% rename from src/library_exceptions.js rename to src/lib/libexceptions.js diff --git a/src/library_exceptions_stub.js b/src/lib/libexceptions_stub.js similarity index 100% rename from src/library_exceptions_stub.js rename to src/lib/libexceptions_stub.js diff --git a/src/library_exports.js b/src/lib/libexports.js similarity index 100% rename from src/library_exports.js rename to src/lib/libexports.js diff --git a/src/library_fetch.js b/src/lib/libfetch.js similarity index 100% rename from src/library_fetch.js rename to src/lib/libfetch.js diff --git a/src/library_fetchfs.js b/src/lib/libfetchfs.js similarity index 100% rename from src/library_fetchfs.js rename to src/lib/libfetchfs.js diff --git a/src/library_formatString.js b/src/lib/libformatString.js similarity index 100% rename from src/library_formatString.js rename to src/lib/libformatString.js diff --git a/src/library_fs.js b/src/lib/libfs.js similarity index 99% rename from src/library_fs.js rename to src/lib/libfs.js index 2bfeb673589cb..84ce21a35b25d 100644 --- a/src/library_fs.js +++ b/src/lib/libfs.js @@ -12,19 +12,19 @@ addToLibrary({ '$intArrayFromString', '$stringToUTF8Array', '$lengthBytesUTF8', -#if LibraryManager.has('library_idbfs.js') +#if LibraryManager.has('libidbfs.js') '$IDBFS', #endif -#if LibraryManager.has('library_nodefs.js') +#if LibraryManager.has('libnodefs.js') '$NODEFS', #endif -#if LibraryManager.has('library_workerfs.js') +#if LibraryManager.has('libworkerfs.js') '$WORKERFS', #endif -#if LibraryManager.has('library_noderawfs.js') +#if LibraryManager.has('libnoderawfs.js') '$NODERAWFS', #endif -#if LibraryManager.has('library_proxyfs.js') +#if LibraryManager.has('libproxyfs.js') '$PROXYFS', #endif #if ASSERTIONS @@ -1510,16 +1510,16 @@ FS.staticInit(); FS.filesystems = { 'MEMFS': MEMFS, -#if LibraryManager.has('library_idbfs.js') +#if LibraryManager.has('libidbfs.js') 'IDBFS': IDBFS, #endif -#if LibraryManager.has('library_nodefs.js') +#if LibraryManager.has('libnodefs.js') 'NODEFS': NODEFS, #endif -#if LibraryManager.has('library_workerfs.js') +#if LibraryManager.has('libworkerfs.js') 'WORKERFS': WORKERFS, #endif -#if LibraryManager.has('library_proxyfs.js') +#if LibraryManager.has('libproxyfs.js') 'PROXYFS': PROXYFS, #endif }; diff --git a/src/library_fs_shared.js b/src/lib/libfs_shared.js similarity index 99% rename from src/library_fs_shared.js rename to src/lib/libfs_shared.js index 1c3c5f9aab310..440d33ffea971 100644 --- a/src/library_fs_shared.js +++ b/src/lib/libfs_shared.js @@ -13,7 +13,7 @@ addToLibrary({ $FS_handledByPreloadPlugin__internal: true, $FS_handledByPreloadPlugin__deps: ['$preloadPlugins'], $FS_handledByPreloadPlugin: (byteArray, fullname, finish, onerror) => { -#if LibraryManager.has('library_browser.js') +#if LibraryManager.has('libbrowser.js') // Ensure plugins are ready. if (typeof Browser != 'undefined') Browser.init(); #endif diff --git a/src/library_getvalue.js b/src/lib/libgetvalue.js similarity index 100% rename from src/library_getvalue.js rename to src/lib/libgetvalue.js diff --git a/src/library_glemu.js b/src/lib/libglemu.js similarity index 100% rename from src/library_glemu.js rename to src/lib/libglemu.js diff --git a/src/library_glew.js b/src/lib/libglew.js similarity index 100% rename from src/library_glew.js rename to src/lib/libglew.js diff --git a/src/library_glfw.js b/src/lib/libglfw.js similarity index 100% rename from src/library_glfw.js rename to src/lib/libglfw.js diff --git a/src/library_glut.js b/src/lib/libglut.js similarity index 100% rename from src/library_glut.js rename to src/lib/libglut.js diff --git a/src/library_html5.js b/src/lib/libhtml5.js similarity index 100% rename from src/library_html5.js rename to src/lib/libhtml5.js diff --git a/src/library_html5_webgl.js b/src/lib/libhtml5_webgl.js similarity index 99% rename from src/library_html5_webgl.js rename to src/lib/libhtml5_webgl.js index b228ede5416c1..4bf93c9f29185 100644 --- a/src/library_html5_webgl.js +++ b/src/lib/libhtml5_webgl.js @@ -626,7 +626,7 @@ function handleWebGLProxying(funcs) { handleWebGLProxying(LibraryHtml5WebGL); -#if LibraryManager.has('library_webgl.js') +#if LibraryManager.has('libwebgl.js') autoAddDeps(LibraryHtml5WebGL, '$GL'); #endif diff --git a/src/library_html5_webgpu.js b/src/lib/libhtml5_webgpu.js similarity index 100% rename from src/library_html5_webgpu.js rename to src/lib/libhtml5_webgpu.js diff --git a/src/library_icasefs.js b/src/lib/libicasefs.js similarity index 100% rename from src/library_icasefs.js rename to src/lib/libicasefs.js diff --git a/src/library_idbfs.js b/src/lib/libidbfs.js similarity index 100% rename from src/library_idbfs.js rename to src/lib/libidbfs.js diff --git a/src/library_idbstore.js b/src/lib/libidbstore.js similarity index 100% rename from src/library_idbstore.js rename to src/lib/libidbstore.js diff --git a/src/library_int53.js b/src/lib/libint53.js similarity index 100% rename from src/library_int53.js rename to src/lib/libint53.js diff --git a/src/library_jsfilefs.js b/src/lib/libjsfilefs.js similarity index 100% rename from src/library_jsfilefs.js rename to src/lib/libjsfilefs.js diff --git a/src/library_legacy.js b/src/lib/liblegacy.js similarity index 100% rename from src/library_legacy.js rename to src/lib/liblegacy.js diff --git a/src/library_little_endian_heap.js b/src/lib/liblittle_endian_heap.js similarity index 100% rename from src/library_little_endian_heap.js rename to src/lib/liblittle_endian_heap.js diff --git a/src/library_lz4.js b/src/lib/liblz4.js similarity index 100% rename from src/library_lz4.js rename to src/lib/liblz4.js diff --git a/src/library_math.js b/src/lib/libmath.js similarity index 100% rename from src/library_math.js rename to src/lib/libmath.js diff --git a/src/library_memfs.js b/src/lib/libmemfs.js similarity index 100% rename from src/library_memfs.js rename to src/lib/libmemfs.js diff --git a/src/library_memoryprofiler.js b/src/lib/libmemoryprofiler.js similarity index 100% rename from src/library_memoryprofiler.js rename to src/lib/libmemoryprofiler.js diff --git a/src/library_nodefs.js b/src/lib/libnodefs.js similarity index 100% rename from src/library_nodefs.js rename to src/lib/libnodefs.js diff --git a/src/library_nodepath.js b/src/lib/libnodepath.js similarity index 100% rename from src/library_nodepath.js rename to src/lib/libnodepath.js diff --git a/src/library_noderawfs.js b/src/lib/libnoderawfs.js similarity index 100% rename from src/library_noderawfs.js rename to src/lib/libnoderawfs.js diff --git a/src/library_openal.js b/src/lib/libopenal.js similarity index 100% rename from src/library_openal.js rename to src/lib/libopenal.js diff --git a/src/library_opfs.js b/src/lib/libopfs.js similarity index 100% rename from src/library_opfs.js rename to src/lib/libopfs.js diff --git a/src/library_path.js b/src/lib/libpath.js similarity index 100% rename from src/library_path.js rename to src/lib/libpath.js diff --git a/src/library_pipefs.js b/src/lib/libpipefs.js similarity index 100% rename from src/library_pipefs.js rename to src/lib/libpipefs.js diff --git a/src/library_promise.js b/src/lib/libpromise.js similarity index 100% rename from src/library_promise.js rename to src/lib/libpromise.js diff --git a/src/library_proxyfs.js b/src/lib/libproxyfs.js similarity index 100% rename from src/library_proxyfs.js rename to src/lib/libproxyfs.js diff --git a/src/library_pthread.js b/src/lib/libpthread.js similarity index 100% rename from src/library_pthread.js rename to src/lib/libpthread.js diff --git a/src/library_pthread_stub.js b/src/lib/libpthread_stub.js similarity index 100% rename from src/library_pthread_stub.js rename to src/lib/libpthread_stub.js diff --git a/src/library_sdl.js b/src/lib/libsdl.js similarity index 100% rename from src/library_sdl.js rename to src/lib/libsdl.js diff --git a/src/library_sigs.js b/src/lib/libsigs.js similarity index 100% rename from src/library_sigs.js rename to src/lib/libsigs.js diff --git a/src/library_sockfs.js b/src/lib/libsockfs.js similarity index 100% rename from src/library_sockfs.js rename to src/lib/libsockfs.js diff --git a/src/library_stack_trace.js b/src/lib/libstack_trace.js similarity index 100% rename from src/library_stack_trace.js rename to src/lib/libstack_trace.js diff --git a/src/library_strings.js b/src/lib/libstrings.js similarity index 100% rename from src/library_strings.js rename to src/lib/libstrings.js diff --git a/src/library_syscall.js b/src/lib/libsyscall.js similarity index 100% rename from src/library_syscall.js rename to src/lib/libsyscall.js diff --git a/src/library_time.js b/src/lib/libtime.js similarity index 100% rename from src/library_time.js rename to src/lib/libtime.js diff --git a/src/library_trace.js b/src/lib/libtrace.js similarity index 100% rename from src/library_trace.js rename to src/lib/libtrace.js diff --git a/src/library_tty.js b/src/lib/libtty.js similarity index 100% rename from src/library_tty.js rename to src/lib/libtty.js diff --git a/src/library_uuid.js b/src/lib/libuuid.js similarity index 100% rename from src/library_uuid.js rename to src/lib/libuuid.js diff --git a/src/library_wasi.js b/src/lib/libwasi.js similarity index 100% rename from src/library_wasi.js rename to src/lib/libwasi.js diff --git a/src/library_wasm_worker.js b/src/lib/libwasm_worker.js similarity index 100% rename from src/library_wasm_worker.js rename to src/lib/libwasm_worker.js diff --git a/src/library_wasmfs.js b/src/lib/libwasmfs.js similarity index 98% rename from src/library_wasmfs.js rename to src/lib/libwasmfs.js index fd238bc2767bd..2963bedd80305 100644 --- a/src/library_wasmfs.js +++ b/src/lib/libwasmfs.js @@ -50,19 +50,19 @@ FS.init(); '$FS_mkdirTree', '$FS_writeFile', '$FS_unlink', -#if LibraryManager.has('library_icasefs.js') +#if LibraryManager.has('libicasefs.js') '$ICASEFS', #endif -#if LibraryManager.has('library_nodefs.js') +#if LibraryManager.has('libnodefs.js') '$NODEFS', #endif -#if LibraryManager.has('library_opfs.js') +#if LibraryManager.has('libopfs.js') '$OPFS', #endif -#if LibraryManager.has('library_jsfilefs.js') +#if LibraryManager.has('libjsfilefs.js') '$JSFILEFS', #endif -#if LibraryManager.has('library_fetchfs.js') +#if LibraryManager.has('libfetchfs.js') '$FETCHFS', #endif 'malloc', @@ -482,7 +482,7 @@ FS.init(); // need some specific FS_* operations. When the FS object is present, it calls // into those FS_* methods as needed. // - // In contrast, the old JS FS (library_fs.js) does the opposite: it puts all + // In contrast, the old JS FS (libfs.js) does the opposite: it puts all // things on the FS object, and copies them to FS_* methods for use from JS // library code. Given that the JS FS is implemented entirely in JS, that // makes sense there (as almost all that FS object ends up needed anyhow all diff --git a/src/library_wasmfs_fetch.js b/src/lib/libwasmfs_fetch.js similarity index 100% rename from src/library_wasmfs_fetch.js rename to src/lib/libwasmfs_fetch.js diff --git a/src/library_wasmfs_js_file.js b/src/lib/libwasmfs_js_file.js similarity index 100% rename from src/library_wasmfs_js_file.js rename to src/lib/libwasmfs_js_file.js diff --git a/src/library_wasmfs_jsimpl.js b/src/lib/libwasmfs_jsimpl.js similarity index 100% rename from src/library_wasmfs_jsimpl.js rename to src/lib/libwasmfs_jsimpl.js diff --git a/src/library_wasmfs_node.js b/src/lib/libwasmfs_node.js similarity index 100% rename from src/library_wasmfs_node.js rename to src/lib/libwasmfs_node.js diff --git a/src/library_wasmfs_opfs.js b/src/lib/libwasmfs_opfs.js similarity index 100% rename from src/library_wasmfs_opfs.js rename to src/lib/libwasmfs_opfs.js diff --git a/src/library_webaudio.js b/src/lib/libwebaudio.js similarity index 100% rename from src/library_webaudio.js rename to src/lib/libwebaudio.js diff --git a/src/library_webgl.js b/src/lib/libwebgl.js similarity index 100% rename from src/library_webgl.js rename to src/lib/libwebgl.js diff --git a/src/library_webgl2.js b/src/lib/libwebgl2.js similarity index 100% rename from src/library_webgl2.js rename to src/lib/libwebgl2.js diff --git a/src/library_webgpu.js b/src/lib/libwebgpu.js similarity index 100% rename from src/library_webgpu.js rename to src/lib/libwebgpu.js diff --git a/src/library_websocket.js b/src/lib/libwebsocket.js similarity index 100% rename from src/library_websocket.js rename to src/lib/libwebsocket.js diff --git a/src/library_wget.js b/src/lib/libwget.js similarity index 100% rename from src/library_wget.js rename to src/lib/libwget.js diff --git a/src/library_workerfs.js b/src/lib/libworkerfs.js similarity index 100% rename from src/library_workerfs.js rename to src/lib/libworkerfs.js diff --git a/src/library_xlib.js b/src/lib/libxlib.js similarity index 100% rename from src/library_xlib.js rename to src/lib/libxlib.js diff --git a/src/modules.mjs b/src/modules.mjs index c28b6f6219787..f4de57738d428 100644 --- a/src/modules.mjs +++ b/src/modules.mjs @@ -5,6 +5,8 @@ */ import * as path from 'node:path'; +import * as fs from 'node:fs'; +import {fileURLToPath} from 'node:url'; import { isDecorator, @@ -27,6 +29,14 @@ import {preprocess, processMacros} from './parseTools.mjs'; // List of symbols that were added from the library. export const librarySymbols = []; +const srcDir = fileURLToPath(new URL('.', import.meta.url)); +const systemLibdir = path.join(srcDir, 'lib'); + +function isBeneath(childPath, parentPath) { + const relativePath = path.relative(parentPath, childPath); + return !relativePath.startsWith('..') && !path.isAbsolute(relativePath); +} + export const LibraryManager = { library: {}, // The JS and JS docs of each library definition indexed my mangled name. @@ -36,6 +46,15 @@ export const LibraryManager = { libraries: [], has(name) { + if (!path.isAbsolute(name)) { + // Out libraries used to be called `library_xxx.js` rather than + // `lib_xx.js`. In case we have external code using this function + // we check for the old form too. + if (name.startsWith('library_')) { + name = name.replace('library_', 'lib'); + } + name = path.join(systemLibdir, name); + } return this.libraries.includes(name); }, @@ -45,85 +64,85 @@ export const LibraryManager = { // Core system libraries (always linked against) let libraries = [ - 'library_int53.js', - 'library.js', - 'library_sigs.js', - 'library_ccall.js', - 'library_addfunction.js', - 'library_formatString.js', - 'library_getvalue.js', - 'library_math.js', - 'library_path.js', - 'library_strings.js', - 'library_html5.js', - 'library_stack_trace.js', - 'library_wasi.js', - 'library_eventloop.js', - 'library_promise.js', + 'libint53.js', + 'libcore.js', + 'libsigs.js', + 'libccall.js', + 'libaddfunction.js', + 'libformatString.js', + 'libgetvalue.js', + 'libmath.js', + 'libpath.js', + 'libstrings.js', + 'libhtml5.js', + 'libstack_trace.js', + 'libwasi.js', + 'libeventloop.js', + 'libpromise.js', ]; if (LINK_AS_CXX) { if (DISABLE_EXCEPTION_THROWING && !WASM_EXCEPTIONS) { - libraries.push('library_exceptions_stub.js'); + libraries.push('libexceptions_stub.js'); } else { - libraries.push('library_exceptions.js'); + libraries.push('libexceptions.js'); } } if (!MINIMAL_RUNTIME) { - libraries.push('library_browser.js'); - libraries.push('library_wget.js'); + libraries.push('libbrowser.js'); + libraries.push('libwget.js'); } if (!STANDALONE_WASM) { - libraries.push('library_time.js'); + libraries.push('libtime.js'); } if (EMSCRIPTEN_TRACING) { - libraries.push('library_memoryprofiler.js'); + libraries.push('libmemoryprofiler.js'); } if (AUTODEBUG) { - libraries.push('library_autodebug.js'); + libraries.push('libautodebug.js'); } if (!WASMFS) { - libraries.push('library_syscall.js'); + libraries.push('libsyscall.js'); } if (RELOCATABLE) { - libraries.push('library_dylink.js'); + libraries.push('libdylink.js'); } if (FILESYSTEM) { - libraries.push('library_fs_shared.js'); + libraries.push('libfs_shared.js'); if (WASMFS) { libraries.push( - 'library_wasmfs.js', - 'library_wasmfs_js_file.js', - 'library_wasmfs_jsimpl.js', - 'library_wasmfs_fetch.js', - 'library_wasmfs_node.js', - 'library_wasmfs_opfs.js', + 'libwasmfs.js', + 'libwasmfs_js_file.js', + 'libwasmfs_jsimpl.js', + 'libwasmfs_fetch.js', + 'libwasmfs_node.js', + 'libwasmfs_opfs.js', ); } else { // Core filesystem libraries (always linked against, unless -sFILESYSTEM=0 is specified) libraries.push( - 'library_fs.js', - 'library_memfs.js', - 'library_tty.js', - 'library_pipefs.js', // ok to include it by default since it's only used if the syscall is used - 'library_sockfs.js', // ok to include it by default since it's only used if the syscall is used + 'libfs.js', + 'libmemfs.js', + 'libtty.js', + 'libpipefs.js', // ok to include it by default since it's only used if the syscall is used + 'libsockfs.js', // ok to include it by default since it's only used if the syscall is used ); if (NODERAWFS) { // NODERAWFS requires NODEFS - if (!JS_LIBRARIES.includes('library_nodefs.js')) { - libraries.push('library_nodefs.js'); + if (!JS_LIBRARIES.includes('libnodefs.js')) { + libraries.push('libnodefs.js'); } - libraries.push('library_noderawfs.js'); - // NODERAWFS overwrites library_path.js - libraries.push('library_nodepath.js'); + libraries.push('libnoderawfs.js'); + // NODERAWFS overwrites libpath.js + libraries.push('libnodepath.js'); } } } @@ -131,79 +150,74 @@ export const LibraryManager = { // Additional JS libraries (without AUTO_JS_LIBRARIES, link to these explicitly via -lxxx.js) if (AUTO_JS_LIBRARIES) { libraries.push( - 'library_webgl.js', - 'library_html5_webgl.js', - 'library_openal.js', - 'library_glut.js', - 'library_xlib.js', - 'library_egl.js', - 'library_uuid.js', - 'library_glew.js', - 'library_idbstore.js', - 'library_async.js', + 'libwebgl.js', + 'libhtml5_webgl.js', + 'libopenal.js', + 'libglut.js', + 'libxlib.js', + 'libegl.js', + 'libuuid.js', + 'libglew.js', + 'libidbstore.js', + 'libasync.js', ); if (USE_SDL != 2) { - libraries.push('library_sdl.js'); + libraries.push('libsdl.js'); } } else { if (ASYNCIFY) { - libraries.push('library_async.js'); + libraries.push('libasync.js'); } if (USE_SDL == 1) { - libraries.push('library_sdl.js'); + libraries.push('libsdl.js'); } if (USE_SDL == 2) { - libraries.push('library_egl.js', 'library_webgl.js', 'library_html5_webgl.js'); + libraries.push('libegl.js', 'libwebgl.js', 'libhtml5_webgl.js'); } } if (USE_GLFW) { - libraries.push('library_glfw.js'); + libraries.push('libglfw.js'); } if (LZ4) { - libraries.push('library_lz4.js'); + libraries.push('liblz4.js'); } if (SHARED_MEMORY) { - libraries.push('library_atomic.js'); + libraries.push('libatomic.js'); } if (MAX_WEBGL_VERSION >= 2) { - // library_webgl2.js must be included only after library_webgl.js, so if we are - // about to include library_webgl2.js, first squeeze in library_webgl.js. - libraries.push('library_webgl.js'); - libraries.push('library_webgl2.js'); + // libwebgl2.js must be included only after libwebgl.js, so if we are + // about to include libwebgl2.js, first squeeze in libwebgl.js. + libraries.push('libwebgl.js'); + libraries.push('libwebgl2.js'); } if (GL_EXPLICIT_UNIFORM_LOCATION || GL_EXPLICIT_UNIFORM_BINDING) { - libraries.push('library_c_preprocessor.js'); + libraries.push('libc_preprocessor.js'); } if (LEGACY_GL_EMULATION) { - libraries.push('library_glemu.js'); + libraries.push('libglemu.js'); } if (USE_WEBGPU) { - libraries.push('library_webgpu.js'); - libraries.push('library_html5_webgpu.js'); + libraries.push('libwebgpu.js'); + libraries.push('libhtml5_webgpu.js'); } if (!STRICT) { - libraries.push('library_legacy.js'); + libraries.push('liblegacy.js'); } if (BOOTSTRAPPING_STRUCT_INFO) { - libraries = [ - 'library_bootstrap.js', - 'library_formatString.js', - 'library_strings.js', - 'library_int53.js', - ]; + libraries = ['libbootstrap.js', 'libformatString.js', 'libstrings.js', 'libint53.js']; } if (SUPPORT_BIG_ENDIAN) { - libraries.push('library_little_endian_heap.js'); + libraries.push('liblittle_endian_heap.js'); } // Add all user specified JS library files to the link. @@ -212,14 +226,23 @@ export const LibraryManager = { // own code. libraries.push(...JS_LIBRARIES); + // Resolve all filename to absolute paths + libraries = libraries.map((filename) => { + if (!path.isAbsolute(filename) && fs.existsSync(path.join(systemLibdir, filename))) { + filename = path.join(systemLibdir, filename); + } + return path.resolve(filename); + }); + // Deduplicate libraries to avoid processing any library file multiple times libraries = libraries.filter((item, pos) => libraries.indexOf(item) == pos); // Save the list for has() queries later. this.libraries = libraries; - for (var filename of libraries) { - const isUserLibrary = path.isAbsolute(filename); + for (let filename of libraries) { + const isUserLibrary = !isBeneath(filename, systemLibdir); + if (VERBOSE) { if (isUserLibrary) { printErr('processing user library: ' + filename); @@ -242,9 +265,6 @@ export const LibraryManager = { return true; }, }); - } else { - // System libraries are specified relatative to the `src` directory - filename = localFile(filename); } const oldFile = setCurrentFile(filename); try { diff --git a/src/parseTools.mjs b/src/parseTools.mjs index 02f3b43aca1fc..709fb77f31590 100644 --- a/src/parseTools.mjs +++ b/src/parseTools.mjs @@ -9,6 +9,7 @@ */ import * as path from 'node:path'; +import {existsSync} from 'node:fs'; import { addToCompileTimeContext, @@ -19,6 +20,7 @@ import { runInMacroContext, setCurrentFile, warn, + srcDir, } from './utility.mjs'; const FOUR_GB = 4 * 1024 * 1024 * 1024; @@ -40,6 +42,24 @@ export function processMacros(text, filename) { }); } +function findIncludeFile(filename, currentDir) { + if (path.isAbsolute(filename)) { + return existsSync(filname) ? filename : null; + } + + // Search for include files either relative to the including file, + // or in the src root directory. + const includePath = [currentDir, srcDir]; + for (const p of includePath) { + const f = path.join(p, filename); + if (existsSync(f)) { + return f; + } + } + + return null; +} + // Simple #if/else/endif preprocessing for a file. Checks if the // ident checked is true in our global. // Also handles #include x.js (similar to C #include ) @@ -125,11 +145,12 @@ export function preprocess(filename) { if (includeFile.startsWith('"')) { includeFile = includeFile.substr(1, includeFile.length - 2); } - // Include files are always relative to the current file being processed - if (!path.isAbsolute(includeFile)) { - includeFile = path.join(path.dirname(filename), includeFile); + const absPath = findIncludeFile(includeFile, path.dirname(filename)); + if (!absPath) { + error(`${filename}:${i + 1}: file not found: ${includeFile}`); + continue; } - const result = preprocess(includeFile); + const result = preprocess(absPath); if (result) { ret += `// include: ${includeFile}\n`; ret += result; @@ -886,7 +907,7 @@ function makeModuleReceiveWithVar(localName, moduleName, defaultValue, noAssert) function makeRemovedFSAssert(fsName) { assert(ASSERTIONS); const lower = fsName.toLowerCase(); - if (JS_LIBRARIES.includes(`library_${lower}.js`)) return ''; + if (JS_LIBRARIES.includes(path.resolve(path.join('lib', `lib${lower}.js`)))) return ''; return `var ${fsName} = '${fsName} is no longer included by default; build with -l${lower}.js';`; } diff --git a/src/postamble_minimal.js b/src/postamble_minimal.js index 1f573cd229858..a39967a4a87eb 100644 --- a/src/postamble_minimal.js +++ b/src/postamble_minimal.js @@ -84,7 +84,7 @@ function initRuntime(wasmExports) { // In non-fastcomp non-asm.js builds, grab wasm exports to outer scope // for emscripten_get_exported_function() to be able to access them. -#if LibraryManager.has('library_exports.js') +#if LibraryManager.has('libexports.js') var wasmExports; #endif @@ -138,7 +138,7 @@ if (!Module['wasm']) throw 'Must load WebAssembly Module in to variable Module.w WebAssembly.instantiate(Module['wasm'], imports).then((output) => { #endif -#if !LibraryManager.has('library_exports.js') +#if !LibraryManager.has('libexports.js') // If not using the emscripten_get_exported_function() API, keep the // `wasmExports` variable in local scope to this instantiate function to save // code size. (otherwise access it without to export it to outer scope) diff --git a/src/utility.mjs b/src/utility.mjs index c31d7fc986684..d31bbb2ace06d 100644 --- a/src/utility.mjs +++ b/src/utility.mjs @@ -233,11 +233,13 @@ export function read(filename) { // Use import.meta.dirname here once we drop support for node v18. const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); +export const srcDir = __dirname; + // Returns an absolute path for a file, resolving it relative to this script // (i.e. relative to the src/ directory). export function localFile(filename) { assert(!path.isAbsolute(filename)); - return path.join(__dirname, filename); + return path.join(srcDir, filename); } // Anything needed by the script that we load below must be added to the diff --git a/test/test_other.py b/test/test_other.py index 197af3ee369f3..ef38c5e4f9b49 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -4857,7 +4857,7 @@ def test_jslib_clobber_i(self): def test_jslib_bad_config(self): create_file('lib.js', ''' addToLibrary({ - foo__sig: 'ii', + foo__sig: 'ii', }); ''') err = self.expect_fail([EMCC, test_file('hello_world.c'), '--js-library=lib.js']) @@ -4927,6 +4927,24 @@ def test_postjs_errors(self): err = self.expect_fail([EMCC, test_file('hello_world.c'), '--post-js', 'post.js']) self.assertContained('post.js:2: #error This is an error', err) + def test_jslib_has_libarry(self): + create_file('libfoo.js', ''' + // libwasi.js should be included. + #if !LibraryManager.has('libwasi.js') + #error "oops 1" + #endif + + // Checking for the legacy name should also work + #if !LibraryManager.has('library_wasi.js') + #error "oops 2" + #endif + + #if LibraryManager.has('libbar.js') + #error "oops 3" + #endif + ''') + self.do_runf(test_file('hello_world.c'), emcc_args=['-L', '-lfoo.js']) + def test_EMCC_BUILD_DIR(self): # EMCC_BUILD_DIR env var contains the dir we were building in, when running the js compiler (e.g. when # running a js library). We force the cwd to be src/ for technical reasons, so this lets you find out @@ -11430,7 +11448,7 @@ def print_percent(actual, expected): # Tests the library_c_preprocessor.js functionality. @crossplatform def test_c_preprocessor(self): - self.do_runf('test_c_preprocessor.c', emcc_args=['--js-library', path_from_root('src/library_c_preprocessor.js')]) + self.do_runf('test_c_preprocessor.c', emcc_args=['--js-library', path_from_root('src/lib/libc_preprocessor.js')]) # Test that legacy settings that have been fixed to a specific value and their value can no longer be changed, def test_legacy_settings_forbidden_to_change(self): @@ -13145,7 +13163,7 @@ def test_gen_sig_info(self): # function is added or its signature changed. However it's easy to # rebaseline with --rebaseline. self.run_process([PYTHON, path_from_root('tools/maint/gen_sig_info.py'), '-o', 'out.js']) - self.assertFileContents(path_from_root('src/library_sigs.js'), read_file('out.js')) + self.assertFileContents(path_from_root('src/lib/libsigs.js'), read_file('out.js')) def test_gen_struct_info_env(self): # gen_struct_info.py builds C code in a very specific and low level way. We don't want diff --git a/tools/link.py b/tools/link.py index 5b97edc2c61dc..f71b583caffd0 100644 --- a/tools/link.py +++ b/tools/link.py @@ -220,7 +220,7 @@ def get_js_sym_info(): input_files.extend(read_file(jslib) for jslib in sorted(jslibs)) for jslib in settings.JS_LIBRARIES: if not os.path.isabs(jslib): - jslib = utils.path_from_root('src', jslib) + jslib = utils.path_from_root('src/lib', jslib) input_files.append(read_file(jslib)) content = '\n'.join(input_files) content_hash = hashlib.sha1(content.encode('utf-8')).hexdigest() @@ -646,7 +646,9 @@ def phase_linker_setup(options, state): # noqa: C901, PLR0912, PLR0915 To revalidate these numbers, run `ruff check --select=C901,PLR091`. """ system_libpath = '-L' + str(cache.get_lib_dir(absolute=True)) + system_js_path = '-L' + utils.path_from_root('src', 'lib') state.append_link_flag(system_libpath) + state.append_link_flag(system_js_path) # We used to do this check during on startup during `check_sanity`, but # we now only do it when linking, in order to reduce the overhead when @@ -1240,7 +1242,7 @@ def phase_linker_setup(options, state): # noqa: C901, PLR0912, PLR0915 state.append_link_flag('--no-whole-archive') settings.FILESYSTEM = 1 settings.SYSCALLS_REQUIRE_FILESYSTEM = 0 - settings.JS_LIBRARIES.append('library_wasmfs.js') + settings.JS_LIBRARIES.append('libwasmfs.js') if settings.ASSERTIONS: # used in assertion checks for unflushed content settings.REQUIRED_EXPORTS += ['wasmfs_flush'] @@ -1362,14 +1364,14 @@ def phase_linker_setup(options, state): # noqa: C901, PLR0912, PLR0915 if settings.PTHREADS: setup_pthreads() - settings.JS_LIBRARIES.append('library_pthread.js') + settings.JS_LIBRARIES.append('libpthread.js') if settings.PROXY_TO_PTHREAD: settings.PTHREAD_POOL_SIZE_STRICT = 0 settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$runtimeKeepalivePush'] else: if settings.PROXY_TO_PTHREAD: exit_with_error('-sPROXY_TO_PTHREAD requires -pthread to work!') - settings.JS_LIBRARIES.append('library_pthread_stub.js') + settings.JS_LIBRARIES.append('libpthread_stub.js') if settings.MEMORY64: # Any "pointers" passed to JS will now be i64's, in both modes. @@ -1383,7 +1385,7 @@ def phase_linker_setup(options, state): # noqa: C901, PLR0912, PLR0915 # set location of Wasm Worker bootstrap JS file if settings.WASM_WORKERS == 1: settings.WASM_WORKER_FILE = unsuffixed(os.path.basename(target)) + '.ww.js' - settings.JS_LIBRARIES.append('library_wasm_worker.js') + settings.JS_LIBRARIES.append('libwasm_worker.js') # Set min browser versions based on certain settings such as WASM_BIGINT, # PTHREADS, AUDIO_WORKLET @@ -1401,7 +1403,7 @@ def phase_linker_setup(options, state): # noqa: C901, PLR0912, PLR0915 if settings.AUDIO_WORKLET: if settings.AUDIO_WORKLET == 1: settings.AUDIO_WORKLET_FILE = unsuffixed(os.path.basename(target)) + '.aw.js' - settings.JS_LIBRARIES.append(shared.path_from_root('src', 'library_webaudio.js')) + settings.JS_LIBRARIES.append('libwebaudio.js') if not settings.MINIMAL_RUNTIME: # If we are in the audio worklet environment, we can only access the Module object # and not the global scope of the main JS script. Therefore we need to export @@ -1459,7 +1461,7 @@ def phase_linker_setup(options, state): # noqa: C901, PLR0912, PLR0915 # When not declaring wasm module exports in outer scope one by one, disable minifying # wasm module export names so that the names can be passed directly to the outer scope. - # Also, if using library_exports.js API, disable minification so that the feature can work. + # Also, if using libexports.js API, disable minification so that the feature can work. if not settings.DECLARE_ASM_MODULE_EXPORTS or state.has_link_flag('-lexports.js'): settings.MINIFY_WASM_EXPORT_NAMES = 0 @@ -2005,8 +2007,8 @@ def run_embind_gen(wasm_target, js_syms, extra_settings, linker_inputs): # Embind may be included multiple times, de-duplicate the list first. settings.JS_LIBRARIES = dedup_list(settings.JS_LIBRARIES) # Replace embind with the TypeScript generation version. - embind_index = settings.JS_LIBRARIES.index('embind/embind.js') - settings.JS_LIBRARIES[embind_index] = 'embind/embind_gen.js' + embind_index = settings.JS_LIBRARIES.index('libembind.js') + settings.JS_LIBRARIES[embind_index] = 'libembind_gen.js' if settings.MEMORY64: settings.MIN_NODE_VERSION = 160000 # Source maps haven't been generated yet and aren't needed to run embind_gen. @@ -2732,23 +2734,23 @@ def map_to_js_libs(library_name): """ # Some native libraries are implemented in Emscripten as system side JS libraries library_map = { - 'embind': ['embind/embind.js', 'embind/emval.js'], - 'EGL': ['library_egl.js'], - 'GL': ['library_webgl.js', 'library_html5_webgl.js'], - 'webgl.js': ['library_webgl.js', 'library_html5_webgl.js'], - 'GLESv2': ['library_webgl.js'], + 'embind': ['libembind.js', 'libemval.js'], + 'EGL': ['libegl.js'], + 'GL': ['libwebgl.js', 'libhtml5_webgl.js'], + 'webgl.js': ['libwebgl.js', 'libhtml5_webgl.js'], + 'GLESv2': ['libwebgl.js'], # N.b. there is no GLESv3 to link to (note [f] in https://www.khronos.org/registry/implementers_guide.html) - 'GLEW': ['library_glew.js'], - 'glfw': ['library_glfw.js'], - 'glfw3': ['library_glfw.js'], + 'GLEW': ['libglew.js'], + 'glfw': ['libglfw.js'], + 'glfw3': ['libglfw.js'], 'GLU': [], - 'glut': ['library_glut.js'], - 'openal': ['library_openal.js'], - 'X11': ['library_xlib.js'], - 'SDL': ['library_sdl.js'], - 'uuid': ['library_uuid.js'], - 'fetch': ['library_fetch.js'], - 'websocket': ['library_websocket.js'], + 'glut': ['libglut.js'], + 'openal': ['libopenal.js'], + 'X11': ['libxlib.js'], + 'SDL': ['libsdl.js'], + 'uuid': ['libuuid.js'], + 'fetch': ['libfetch.js'], + 'websocket': ['libwebsocket.js'], # These 4 libraries are separate under glibc but are all rolled into # libc with musl. For compatibility with glibc we just ignore them # completely. @@ -2777,12 +2779,6 @@ def map_to_js_libs(library_name): logger.debug('Mapping library `%s` to JS libraries: %s' % (library_name, libs)) return libs - # TODO(sbc): Remove this special handling for system libraries by renaming - # the system libraries from `library_foo.js` to `libfoo.js` (the latter is - # the more standard name by which `-l` flags resolve libraries). - if library_name.endswith('.js') and os.path.isfile(utils.path_from_root('src', f'library_{library_name}')): - return [f'library_{library_name}'] - return None diff --git a/tools/maint/gen_sig_info.py b/tools/maint/gen_sig_info.py index 170976326f166..421f21481e67b 100755 --- a/tools/maint/gen_sig_info.py +++ b/tools/maint/gen_sig_info.py @@ -6,7 +6,7 @@ """This tool extracts native/C signature information for JS library functions -It generates a file called `src/library_sigs.js` which contains `__sig` declarations +It generates a file called `src/libsigs.js` which contains `__sig` declarations for the majority of JS library functions. """ @@ -275,7 +275,7 @@ def strip_line(l): files = glob.glob('src/*.js') + glob.glob('src/**/*.js') for file in files: - if os.path.basename(file) != 'library_sigs.js': + if os.path.basename(file) != 'libsigs.js': lines = utils.read_file(file).splitlines() lines = [l for l in lines if not strip_line(l)] utils.write_file(file, '\n'.join(lines) + '\n') @@ -307,12 +307,12 @@ def extract_sig_info(sig_info, extra_settings=None, extra_cflags=None, cxx=False 'AUDIO_WORKLET': 1, 'WASM_WORKERS': 1, 'JS_LIBRARIES': [ - 'library_websocket.js', - 'library_exports.js', - 'library_webaudio.js', - 'library_fetch.js', - 'library_pthread.js', - 'library_trace.js', + 'libwebsocket.js', + 'libexports.js', + 'libwebaudio.js', + 'libfetch.js', + 'libpthread.js', + 'libtrace.js', ], 'SUPPORT_LONGJMP': 'emscripten' } @@ -376,7 +376,7 @@ def extract_sig_info(sig_info, extra_settings=None, extra_cflags=None, cxx=False def main(args): parser = argparse.ArgumentParser() - parser.add_argument('-o', '--output', default='src/library_sigs.js') + parser.add_argument('-o', '--output', default='src/libsigs.js') parser.add_argument('-r', '--remove', action='store_true', help='remove from JS library files any `__sig` entries that are part of the auto-generated file') parser.add_argument('-u', '--update', action='store_true', help='update with JS library files any `__sig` entries that are part of the auto-generated file') args = parser.parse_args() @@ -390,9 +390,9 @@ def main(args): 'BUILD_AS_WORKER': 1, 'LINK_AS_CXX': 1, 'AUTO_JS_LIBRARIES': 0}, cxx=True) - extract_sig_info(sig_info, {'WASM_WORKERS': 1, 'JS_LIBRARIES': ['library_wasm_worker.js']}) + extract_sig_info(sig_info, {'WASM_WORKERS': 1, 'JS_LIBRARIES': ['libwasm_worker.js']}) extract_sig_info(sig_info, {'USE_GLFW': 3}, ['-DGLFW3']) - extract_sig_info(sig_info, {'JS_LIBRARIES': ['embind/embind.js', 'embind/emval.js'], + extract_sig_info(sig_info, {'JS_LIBRARIES': ['libembind.js', 'libemval.js'], 'USE_SDL': 0, 'MAX_WEBGL_VERSION': 0, 'AUTO_JS_LIBRARIES': 0,