Buckets:
| # Copyright 2021 The Emscripten Authors. All rights reserved. | |
| # 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. | |
| import copy | |
| import difflib | |
| import os | |
| import re | |
| from typing import Any | |
| from . import diagnostics, utils | |
| from .utils import exit_with_error, path_from_root | |
| # Subset of settings that take a memory size (i.e. 1Gb, 64kb etc) | |
| MEM_SIZE_SETTINGS = { | |
| 'GLOBAL_BASE', | |
| 'STACK_SIZE', | |
| 'TOTAL_STACK', | |
| 'INITIAL_HEAP', | |
| 'INITIAL_MEMORY', | |
| 'MEMORY_GROWTH_LINEAR_STEP', | |
| 'MEMORY_GROWTH_GEOMETRIC_CAP', | |
| 'GL_MAX_TEMP_BUFFER_SIZE', | |
| 'MAXIMUM_MEMORY', | |
| 'DEFAULT_PTHREAD_STACK_SIZE', | |
| 'ASYNCIFY_STACK_SIZE', | |
| } | |
| PORTS_SETTINGS = { | |
| # All port-related settings are valid at compile time | |
| 'USE_SDL', | |
| 'USE_LIBPNG', | |
| 'USE_BULLET', | |
| 'USE_ZLIB', | |
| 'USE_BZIP2', | |
| 'USE_VORBIS', | |
| 'USE_COCOS2D', | |
| 'USE_ICU', | |
| 'USE_MODPLUG', | |
| 'USE_SDL_MIXER', | |
| 'USE_SDL_IMAGE', | |
| 'USE_SDL_TTF', | |
| 'USE_SDL_NET', | |
| 'USE_SDL_GFX', | |
| 'USE_LIBJPEG', | |
| 'USE_OGG', | |
| 'USE_REGAL', | |
| 'USE_BOOST_HEADERS', | |
| 'USE_HARFBUZZ', | |
| 'USE_MPG123', | |
| 'USE_GIFLIB', | |
| 'USE_FREETYPE', | |
| 'SDL2_MIXER_FORMATS', | |
| 'SDL2_IMAGE_FORMATS', | |
| 'USE_SQLITE3', | |
| } | |
| # Subset of settings that apply only when generating JS | |
| JS_ONLY_SETTINGS = { | |
| 'DEFAULT_LIBRARY_FUNCS_TO_INCLUDE', | |
| 'INCLUDE_FULL_LIBRARY', | |
| 'BUILD_AS_WORKER', | |
| 'STRICT_JS', | |
| 'SMALL_XHR_CHUNKS', | |
| 'MODULARIZE', | |
| 'EXPORT_ES6', | |
| 'EXPORT_NAME', | |
| 'DYNAMIC_EXECUTION', | |
| 'PTHREAD_POOL_SIZE', | |
| 'PTHREAD_POOL_SIZE_STRICT', | |
| 'PTHREAD_POOL_DELAY_LOAD', | |
| 'DEFAULT_PTHREAD_STACK_SIZE', | |
| } | |
| # Subset of settings that apply at compile time. | |
| # (Keep in sync with [compile] comments in settings.js) | |
| COMPILE_TIME_SETTINGS = { | |
| 'MEMORY64', | |
| 'INLINING_LIMIT', | |
| 'DISABLE_EXCEPTION_CATCHING', | |
| 'DISABLE_EXCEPTION_THROWING', | |
| 'WASM_LEGACY_EXCEPTIONS', | |
| 'MAIN_MODULE', | |
| 'SIDE_MODULE', | |
| 'LINKABLE', | |
| 'STRICT', | |
| 'EMSCRIPTEN_TRACING', | |
| 'PTHREADS', | |
| 'USE_PTHREADS', # legacy name of PTHREADS setting | |
| 'SHARED_MEMORY', | |
| 'SUPPORT_LONGJMP', | |
| 'WASM_OBJECT_FILES', | |
| 'WASM_WORKERS', | |
| # Internal settings used during compilation | |
| 'EXCEPTION_CATCHING_ALLOWED', | |
| 'WASM_EXCEPTIONS', | |
| 'LTO', | |
| 'OPT_LEVEL', | |
| 'DEBUG_LEVEL', | |
| }.union(PORTS_SETTINGS) | |
| # Unlike `LEGACY_SETTINGS`, deprecated settings can still be used | |
| # both on the command line and in the emscripten codebase. | |
| # | |
| # At some point in the future, once folks have stopped using these | |
| # settings we can move them to `LEGACY_SETTINGS`. | |
| # | |
| # All settings here should be tagged as `[deprecated]` in settings.js | |
| DEPRECATED_SETTINGS = { | |
| 'RUNTIME_LINKED_LIBS': 'you can simply list the libraries directly on the commandline now', | |
| 'CLOSURE_WARNINGS': 'use -Wclosure/-Wno-closure instead', | |
| 'LEGALIZE_JS_FFI': 'to disable JS type legalization use `-sWASM_BIGINT` or `-sSTANDALONE_WASM`', | |
| 'ASYNCIFY_EXPORTS': 'please use JSPI_EXPORTS instead', | |
| 'LINKABLE': 'under consideration for removal (https://github.com/emscripten-core/emscripten/issues/25262)', | |
| 'EXPORT_EXCEPTION_HANDLING_HELPERS': 'getExceptionMessage is exported anyway when ASSERTIONS or EXCEPTION_STACK_TRACES is set, which are set by default at -O0. At -O1 or above, you can export it separately by -sEXPORTED_RUNTIME_METHODS=getExceptionMessage,decrementExceptionRefcount.', | |
| 'DETERMINISTIC': 'under consideration for removal (https://github.com/emscripten-core/emscripten/issues/26647)', | |
| } | |
| # Settings that don't need to be externalized when serializing to json because they | |
| # are not used by the JS compiler. | |
| INTERNAL_SETTINGS = { | |
| 'SIDE_MODULE_IMPORTS', | |
| } | |
| # List of incompatible settings, of the form (SETTINGS_A, SETTING_B, OPTIONAL_REASON_FOR_INCOMPAT) | |
| INCOMPATIBLE_SETTINGS = [ | |
| ('MINIMAL_RUNTIME', 'MAIN_MODULE', None), | |
| ('WASM_WORKERS', 'MAIN_MODULE', 'dynamic linking is not supported with -sWASM_WORKERS'), | |
| ('WASM2JS', 'MAIN_MODULE', 'wasm2js does not support dynamic linking'), | |
| ('WASM2JS', 'SIDE_MODULE', 'wasm2js does not support dynamic linking'), | |
| ('MODULARIZE', 'NO_DECLARE_ASM_MODULE_EXPORTS', None), | |
| ('EVAL_CTORS', 'WASM2JS', None), | |
| # In Asyncify exports can be called more than once, and this seems to not | |
| # work properly yet (see test_emscripten_scan_registers). | |
| ('EVAL_CTORS', 'ASYNCIFY', None), | |
| ('PTHREADS_PROFILING', 'NO_ASSERTIONS', 'only works with ASSERTIONS enabled'), | |
| ('SOURCE_PHASE_IMPORTS', 'NO_EXPORT_ES6', None), | |
| ('STANDALONE_WASM', 'MINIMAL_RUNTIME', None), | |
| ('STRICT_JS', 'EXPORT_ES6', None), | |
| ('MINIMAL_RUNTIME_STREAMING_WASM_COMPILATION', 'MINIMAL_RUNTIME_STREAMING_WASM_INSTANTIATION', 'they are mutually exclusive'), | |
| ('MINIMAL_RUNTIME_STREAMING_WASM_COMPILATION', 'SINGLE_FILE', None), | |
| ('MINIMAL_RUNTIME_STREAMING_WASM_INSTANTIATION', 'SINGLE_FILE', None), | |
| ('SEPARATE_DWARF', 'WASM2JS', 'as there is no wasm file'), | |
| ('GL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS', 'NO_GL_SUPPORT_SIMPLE_ENABLE_EXTENSIONS', None), | |
| ('LEGACY_VM_SUPPORT', 'MEMORY64', None), | |
| ('CROSS_ORIGIN', 'NO_DYNAMIC_EXECUTION', None), | |
| ('CROSS_ORIGIN', 'NO_PTHREADS', None), | |
| ] | |
| EXPERIMENTAL_SETTINGS = { | |
| 'SPLIT_MODULE': '-sSPLIT_MODULE is experimental and subject to change', | |
| 'SOURCE_PHASE_IMPORTS': '-sSOURCE_PHASE_IMPORTS is experimental and not yet supported in browsers', | |
| 'JS_BASE64_API': '-sJS_BASE64_API is experimental and not yet supported in browsers', | |
| 'GROWABLE_ARRAYBUFFERS': '-sGROWABLE_ARRAYBUFFERS is experimental and not yet supported in browsers', | |
| 'SUPPORT_BIG_ENDIAN': '-sSUPPORT_BIG_ENDIAN is experimental, not all features are fully supported.', | |
| 'WASM_ESM_INTEGRATION': '-sWASM_ESM_INTEGRATION is still experimental and not yet supported in browsers', | |
| } | |
| # For renamed settings the format is: | |
| # [OLD_NAME, NEW_NAME] | |
| # For removed settings (which now effectively have a fixed value and can no | |
| # longer be changed) the format is: | |
| # [OPTION_NAME, POSSIBLE_VALUES, ERROR_EXPLANATION], where POSSIBLE_VALUES is | |
| # an array of values that will still be silently accepted by the compiler. | |
| # First element in the list is the canonical/fixed value going forward. | |
| # This allows existing build systems to keep specifying one of the supported | |
| # settings, for backwards compatibility. | |
| # When a setting has been removed, and we want to error on all values of it, | |
| # we can set POSSIBLE_VALUES to an impossible value (like "disallowed" for a | |
| # numeric setting, or -1 for a string setting). | |
| LEGACY_SETTINGS = [ | |
| ['BINARYEN', 'WASM'], | |
| ['TOTAL_STACK', 'STACK_SIZE'], | |
| ['BINARYEN_ASYNC_COMPILATION', 'WASM_ASYNC_COMPILATION'], | |
| ['UNALIGNED_MEMORY', [0], 'forced unaligned memory not supported in fastcomp'], | |
| ['FORCE_ALIGNED_MEMORY', [0], 'forced aligned memory is not supported in fastcomp'], | |
| ['PGO', [0], 'pgo no longer supported'], | |
| ['QUANTUM_SIZE', [4], 'altering the QUANTUM_SIZE is not supported'], | |
| ['FUNCTION_POINTER_ALIGNMENT', [2], 'Starting from Emscripten 1.37.29, no longer available (https://github.com/emscripten-core/emscripten/pull/6091)'], | |
| # Reserving function pointers is not needed - allowing table growth allows any number of new functions to be added. | |
| ['RESERVED_FUNCTION_POINTERS', 'ALLOW_TABLE_GROWTH'], | |
| ['BUILD_AS_SHARED_LIB', [0], 'Starting from Emscripten 1.38.16, no longer available (https://github.com/emscripten-core/emscripten/pull/7433)'], | |
| ['SAFE_SPLIT_MEMORY', [0], 'Starting from Emscripten 1.38.19, SAFE_SPLIT_MEMORY codegen is no longer available (https://github.com/emscripten-core/emscripten/pull/7465)'], | |
| ['SPLIT_MEMORY', [0], 'Starting from Emscripten 1.38.19, SPLIT_MEMORY codegen is no longer available (https://github.com/emscripten-core/emscripten/pull/7465)'], | |
| ['BINARYEN_METHOD', ['native-wasm'], 'Starting from Emscripten 1.38.23, Emscripten now always builds either to Wasm (-sWASM - default), or to JavaScript (-sWASM=0), other methods are not supported (https://github.com/emscripten-core/emscripten/pull/7836)'], | |
| ['BINARYEN_TRAP_MODE', [-1], 'The wasm backend does not support a trap mode (it always clamps, in effect)'], | |
| ['PRECISE_I64_MATH', [1, 2], 'Starting from Emscripten 1.38.26, PRECISE_I64_MATH is always enabled (https://github.com/emscripten-core/emscripten/pull/7935)'], | |
| ['MEMFS_APPEND_TO_TYPED_ARRAYS', [1], 'Starting from Emscripten 1.38.26, MEMFS_APPEND_TO_TYPED_ARRAYS=0 is no longer supported. MEMFS no longer supports using JS arrays for file data (https://github.com/emscripten-core/emscripten/pull/7918)'], | |
| ['ERROR_ON_MISSING_LIBRARIES', [1], 'missing libraries are always an error now'], | |
| ['EMITTING_JS', [1], 'The new STANDALONE_WASM flag replaces this (replace EMITTING_JS=0 with STANDALONE_WASM=1)'], | |
| ['SKIP_STACK_IN_SMALL', [0, 1], 'SKIP_STACK_IN_SMALL is no longer needed as the backend can optimize it directly'], | |
| ['SAFE_STACK', [0], 'Replace SAFE_STACK=1 with STACK_OVERFLOW_CHECK=2'], | |
| ['MEMORY_GROWTH_STEP', 'MEMORY_GROWTH_LINEAR_STEP'], | |
| ['ELIMINATE_DUPLICATE_FUNCTIONS', [0, 1], 'Duplicate function elimination for wasm is handled automatically by binaryen'], | |
| ['ELIMINATE_DUPLICATE_FUNCTIONS_DUMP_EQUIVALENT_FUNCTIONS', [0], 'Duplicate function elimination for wasm is handled automatically by binaryen'], | |
| ['ELIMINATE_DUPLICATE_FUNCTIONS_PASSES', [5], 'Duplicate function elimination for wasm is handled automatically by binaryen'], | |
| ['WASM_OBJECT_FILES', [1], 'For LTO, use -flto or -fto=thin instead. Otherwise, Wasm object files are the default'], | |
| ['TOTAL_MEMORY', 'INITIAL_MEMORY'], | |
| ['WASM_MEM_MAX', 'MAXIMUM_MEMORY'], | |
| ['BINARYEN_MEM_MAX', 'MAXIMUM_MEMORY'], | |
| ['BINARYEN_PASSES', [''], 'Use BINARYEN_EXTRA_PASSES to add additional passes'], | |
| ['SWAPPABLE_ASM_MODULE', [0], 'Fully swappable asm modules are no longer supported'], | |
| ['ASM_JS', [1], 'asm.js output is not supported anymore'], | |
| ['FINALIZE_ASM_JS', [0, 1], 'asm.js output is not supported anymore'], | |
| ['ASYNCIFY_WHITELIST', 'ASYNCIFY_ONLY'], | |
| ['ASYNCIFY_BLACKLIST', 'ASYNCIFY_REMOVE'], | |
| ['EXCEPTION_CATCHING_WHITELIST', 'EXCEPTION_CATCHING_ALLOWED'], | |
| ['SEPARATE_ASM', [0], 'Separate asm.js only made sense for fastcomp with asm.js output'], | |
| ['SEPARATE_ASM_MODULE_NAME', [''], 'Separate asm.js only made sense for fastcomp with asm.js output'], | |
| ['FAST_UNROLLED_MEMCPY_AND_MEMSET', [0, 1], 'The wasm backend implements memcpy/memset in C'], | |
| ['DOUBLE_MODE', [0, 1], 'The wasm backend always implements doubles normally'], | |
| ['PRECISE_F32', [0, 1, 2], 'The wasm backend always implements floats normally'], | |
| ['ALIASING_FUNCTION_POINTERS', [0, 1], 'The wasm backend always uses a single index space for function pointers, in a single Table'], | |
| ['AGGRESSIVE_VARIABLE_ELIMINATION', [0, 1], 'Wasm ignores asm.js-specific optimization flags'], | |
| ['SIMPLIFY_IFS', [1], 'Wasm ignores asm.js-specific optimization flags'], | |
| ['DEAD_FUNCTIONS', [[]], 'The wasm backend does not support dead function removal'], | |
| ['WASM_BACKEND', [-1], 'Only the wasm backend is now supported (note that setting it as -s has never been allowed anyhow)'], | |
| ['EXPORT_BINDINGS', [0, 1], 'No longer needed'], | |
| ['RUNNING_JS_OPTS', [0], 'Fastcomp cared about running JS which could alter asm.js validation, but not upstream'], | |
| ['EXPORT_FUNCTION_TABLES', [0], 'No longer needed'], | |
| ['BINARYEN_SCRIPTS', [''], 'No longer needed'], | |
| ['WARN_UNALIGNED', [0, 1], 'No longer needed'], | |
| ['ASM_PRIMITIVE_VARS', [[]], 'No longer needed'], | |
| ['WORKAROUND_IOS_9_RIGHT_SHIFT_BUG', [0], 'Wasm2JS does not support iPhone 4s, iPad 2, iPad 3, iPad Mini 1, Pod Touch 5 (devices with end-of-life at iOS 9.3.5) and older'], | |
| ['RUNTIME_FUNCS_TO_IMPORT', [[]], 'No longer needed'], | |
| ['LIBRARY_DEPS_TO_AUTOEXPORT', [[]], 'No longer needed'], | |
| ['EMIT_EMSCRIPTEN_METADATA', [0], 'No longer supported'], | |
| ['SHELL_FILE', [''], 'No longer supported'], | |
| ['LLD_REPORT_UNDEFINED', [1], 'Disabling is no longer supported'], | |
| ['MEM_INIT_METHOD', [0], 'No longer supported'], | |
| ['USE_PTHREADS', [0, 1], 'No longer needed. Use -pthread instead'], | |
| ['USES_DYNAMIC_ALLOC', [1], 'No longer supported. Use -sMALLOC=none'], | |
| ['REVERSE_DEPS', ['auto', 'all', 'none'], 'No longer needed'], | |
| ['RUNTIME_LOGGING', 'RUNTIME_DEBUG'], | |
| ['MIN_EDGE_VERSION', [0x7FFFFFFF], 'No longer supported'], | |
| ['MIN_IE_VERSION', [0x7FFFFFFF], 'No longer supported'], | |
| ['WORKAROUND_OLD_WEBGL_UNIFORM_UPLOAD_IGNORED_OFFSET_BUG', [0], 'No longer supported'], | |
| ['AUTO_ARCHIVE_INDEXES', [0, 1], 'No longer needed'], | |
| ['USE_ES6_IMPORT_META', [1], 'Disabling is no longer supported'], | |
| ['EXTRA_EXPORTED_RUNTIME_METHODS', [[]], 'No longer supported, use EXPORTED_RUNTIME_METHODS'], | |
| ['SUPPORT_ERRNO', [0], 'No longer supported'], | |
| ['DEMANGLE_SUPPORT', [0], 'No longer supported'], | |
| ['MAYBE_WASM2JS', [0], 'No longer supported (use -sWASM=2)'], | |
| ['HEADLESS', [0], 'No longer supported, use headless browsers or Node.js with JSDOM'], | |
| ['USE_OFFSET_COVERTER', [0], 'No longer supported, not needed with modern v8 versions'], | |
| ['ASYNCIFY_LAZY_LOAD_CODE', [0], 'No longer supported'], | |
| ['USE_WEBGPU', [0], 'No longer supported; replaced by --use-port=emdawnwebgpu, which implements a newer (but incompatible) version of webgpu.h - see tools/ports/emdawnwebgpu.py'], | |
| ['PROXY_TO_WORKER', [0], 'No longer supported'], | |
| ['NODEJS_CATCH_EXIT', [0], 'No longer supported'], | |
| ['NODEJS_CATCH_REJECTION', [0], 'No longer supported'], | |
| ['POLYFILL_OLD_MATH_FUNCTIONS', [0], 'No longer supported'], | |
| ['RELOCATABLE', [0], 'No longer supported'], | |
| ['WASM_JS_TYPES', [0], 'No longer supported'], | |
| ['DETERMINISTIC', [0], 'No longer supported'], | |
| ] | |
| user_settings: dict[str, str] = {} | |
| def default_setting(name, new_default): | |
| if name not in user_settings: | |
| setattr(settings, name, new_default) | |
| class SettingsManager: | |
| attrs: dict[str, Any] = {} | |
| defaults: dict[str, tuple] = {} | |
| types: dict[str, Any] = {} | |
| allowed_settings: set[str] = set() | |
| legacy_settings: dict[str, tuple] = {} | |
| alt_names: dict[str, str] = {} | |
| internal_settings: set[str] = set() | |
| def __init__(self): | |
| self.attrs.clear() | |
| self.legacy_settings.clear() | |
| self.defaults.clear() | |
| self.alt_names.clear() | |
| self.internal_settings.clear() | |
| self.allowed_settings.clear() | |
| # Load the JS defaults into python. | |
| def read_js_settings(filename, attrs): | |
| settings = utils.read_file(filename) | |
| # Use a bunch of regexs to convert the file from JS to python | |
| # TODO(sbc): This is kind hacky and we should probably convert | |
| # this file in format that python can read directly (since we | |
| # no longer read this file from JS at all). | |
| settings = settings.replace('//', '#') | |
| settings = re.sub(r'var ([\w\d]+)', r'attrs["\1"]', settings) | |
| settings = re.sub(r'=\s+false\s*;', '= False', settings) | |
| settings = re.sub(r'=\s+true\s*;', '= True', settings) | |
| exec(settings, {'attrs': attrs}) | |
| internal_attrs = {} | |
| read_js_settings(path_from_root('src/settings.js'), self.attrs) | |
| read_js_settings(path_from_root('src/settings_internal.js'), internal_attrs) | |
| self.attrs.update(internal_attrs) | |
| self.infer_types() | |
| strict_override = False | |
| if 'EMCC_STRICT' in os.environ: | |
| strict_override = int(os.environ.get('EMCC_STRICT')) | |
| # Special handling for LEGACY_SETTINGS. See src/setting.js for more | |
| # details | |
| for legacy in LEGACY_SETTINGS: | |
| if len(legacy) == 2: | |
| name, new_name = legacy | |
| self.legacy_settings[name] = (None, 'setting renamed to ' + new_name) | |
| self.alt_names[name] = new_name | |
| self.alt_names[new_name] = name | |
| default_value = self.attrs[new_name] | |
| else: | |
| name, fixed_values, err = legacy | |
| self.legacy_settings[name] = (fixed_values, err) | |
| default_value = fixed_values[0] | |
| assert name not in self.attrs, 'legacy setting (%s) cannot also be a regular setting' % name | |
| if not strict_override: | |
| self.attrs[name] = default_value | |
| self.internal_settings.update(internal_attrs.keys()) | |
| # Stash a deep copy of all settings in self.defaults. This allows us to detect which settings | |
| # have local mods. | |
| self.defaults.update(copy.deepcopy(self.attrs)) | |
| if strict_override: | |
| self.attrs['STRICT'] = strict_override | |
| def infer_types(self): | |
| for key, value in self.attrs.items(): | |
| self.types[key] = type(value) | |
| def dict(self): | |
| return self.attrs | |
| def external_dict(self, skip_keys={}): # noqa | |
| external_settings = {} | |
| for key, value in self.dict().items(): | |
| if value != self.defaults.get(key) and key not in INTERNAL_SETTINGS and key not in skip_keys: | |
| external_settings[key] = value # noqa: PERF403 | |
| if not self.attrs['STRICT']: | |
| # When not running in strict mode we also externalize all legacy settings | |
| # (Since the external tools do process LEGACY_SETTINGS themselves) | |
| for key in self.legacy_settings: | |
| external_settings[key] = self.attrs[key] | |
| return external_settings | |
| def keys(self): | |
| return self.attrs.keys() | |
| def limit_settings(self, allowed): | |
| self.allowed_settings.clear() | |
| if allowed: | |
| self.allowed_settings.update(allowed) | |
| def __getattr__(self, attr): | |
| if self.allowed_settings: | |
| assert attr in self.allowed_settings, f"internal error: attempt to read setting '{attr}' while in limited settings mode" | |
| if attr in self.attrs: | |
| return self.attrs[attr] | |
| else: | |
| raise AttributeError(f"no such setting: '{attr}'") | |
| def __setattr__(self, name, value): | |
| if self.allowed_settings: | |
| assert name in self.allowed_settings, f"internal error: attempt to write setting '{name}' while in limited settings mode" | |
| if name == 'STRICT' and value: | |
| for a in self.legacy_settings: | |
| self.attrs.pop(a, None) | |
| if name in self.legacy_settings: | |
| # TODO(sbc): Rather then special case this we should have STRICT turn on the | |
| # legacy-settings warning below | |
| if self.attrs['STRICT']: | |
| exit_with_error('legacy setting used in strict mode: %s', name) | |
| fixed_values, error_message = self.legacy_settings[name] | |
| if fixed_values and value not in fixed_values: | |
| exit_with_error(f'invalid command line setting `-s{name}={value}`: {error_message}') | |
| diagnostics.warning('legacy-settings', 'use of legacy setting: %s (%s)', name, error_message) | |
| if name in self.alt_names: | |
| alt_name = self.alt_names[name] | |
| self.attrs[alt_name] = value | |
| if name not in self.attrs: | |
| msg = "Attempt to set a non-existent setting: '%s'\n" % name | |
| valid_keys = set(self.attrs.keys()).difference(self.internal_settings) | |
| suggestions = difflib.get_close_matches(name, valid_keys) | |
| suggestions = [s for s in suggestions if s not in self.legacy_settings] | |
| suggestions = ', '.join(suggestions) | |
| if suggestions: | |
| msg += ' - did you mean one of %s?\n' % suggestions | |
| msg += " - perhaps a typo in emcc's -sX=Y notation?\n" | |
| msg += ' - (see src/settings.js for valid values)' | |
| exit_with_error(msg) | |
| self.check_type(name, value) | |
| self.attrs[name] = value | |
| def check_type(self, name, value): | |
| # These settings have a variable type so cannot be easily type checked. | |
| if name in {'EXECUTABLE', 'SUPPORT_LONGJMP', 'PTHREAD_POOL_SIZE', 'SEPARATE_DWARF', 'LTO', 'MODULARIZE'}: | |
| return | |
| expected_type = self.types.get(name) | |
| if not expected_type: | |
| return | |
| # Allow integers 1 and 0 for type `bool` | |
| if expected_type == bool: | |
| if value in (1, 0): # noqa: PLR6201 | |
| value = bool(value) | |
| if value in ('True', 'False', 'true', 'false'): # noqa: PLR6201 | |
| exit_with_error(f'attempt to set `{name}` to `{value}`; use 1/0 to set boolean settings') | |
| if type(value) is not expected_type: | |
| exit_with_error(f'setting `{name}` expects `{expected_type.__name__}` but got `{type(value).__name__}`') | |
| def __getitem__(self, key): | |
| return self.attrs[key] | |
| def __setitem__(self, key, value): | |
| self.attrs[key] = value | |
| def backup(self): | |
| return copy.deepcopy(self.attrs) | |
| def restore(self, previous): | |
| self.attrs.update(previous) | |
| settings = SettingsManager() | |
Xet Storage Details
- Size:
- 20.4 kB
- Xet hash:
- 692bddb551b65c89b07c57259ac1cdd9105f61e052db8d0a630d3397a0aeb982
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.