diff --git a/.circleci/config.yml b/.circleci/config.yml index 4f64f4e80a7b1..662e159eebed2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -796,6 +796,54 @@ jobs: core2.test_exceptions_wasm core2.test_pthread_unhandledrejection" - upload-test-results + test-llvm-stable: + executor: focal + environment: + LANG: "C.UTF-8" + EMTEST_SKIP_V8: "1" + steps: + - run: + name: install llvm + command: | + echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-19 main" >> /etc/apt/sources.list + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - + apt-get update + apt-get install -q -y clang-19 lld-19 + - checkout + - run: + name: submodule update + command: git submodule update --init + - pip-install + - install-emsdk + - install-rust + - run: + name: configure LLVM + command: echo "LLVM_ROOT='/usr/lib/llvm-19/bin'" >> ~/emsdk/.emscripten + - run: apt-get install -q -y ninja-build scons ccache + - run-tests: + extra-cflags: "-Wno-experimental" + # Would it make sense use a `@no_llvm_stable` decorator instead of + # listed in these here? + test_targets: "--skip-slow + core2.test_hello_world + other + skip:other.test_*code_size* + skip:other.test_*codesize* + skip:other.test_*memory64* + skip:other.test_*wasm64* + skip:other.test_fp16* + skip:other.test_wasm_worker* + skip:other.test_shared_memory* + skip:other.test_gen_struct_info* + skip:other.test_wasm_features + skip:other.test_post_link + skip:other.test_reproduce + skip:other.test_dylink_pthread_warning + skip:other.test_argument_missing + skip:other.test_embind_tsgen_worker_env + skip:other.test_explicit_target + skip:other.test_unistd_seek_wasmfs + " test-other: executor: focal environment: @@ -1029,3 +1077,4 @@ workflows: - test-node-compat - test-windows - test-mac-arm64 + - test-llvm-stable diff --git a/ChangeLog.md b/ChangeLog.md index 7bf5e0fca0385..c53994c3a04f0 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -52,6 +52,9 @@ See docs/process.md for more on how version tagging works. - The `POLYFILL_OLD_MATH_FUNCTIONS` setting was removed. The browser versions that require these polyfills are no longer supported by emscripten so the polyfills should never be needed. (#23262) +- Initial support was added for running emscripten with LLVM stable (currently + v19). This is currently experimental. (#23311) + 3.1.74 - 12/14/24 ----------------- diff --git a/emcc.py b/emcc.py index 1ce16b7d0d299..b62001d16f9cd 100644 --- a/emcc.py +++ b/emcc.py @@ -385,6 +385,14 @@ def get_clang_flags(user_args): if '-mbulk-memory' not in user_args: flags.append('-mbulk-memory') + if shared.is_llvm_stable(): + # LLVM 19 doesn't enable these features by default, but we want + # them on-by-default, like they are on LLVM tot. + if '-mbulk-memory' not in user_args: + flags.append('-mbulk-memory') + if '-mnontrapping-fptoint' not in user_args: + flags.append('-mnontrapping-fptoint') + if settings.RELOCATABLE and '-fPIC' not in user_args: flags.append('-fPIC') diff --git a/tools/shared.py b/tools/shared.py index 9ccd2354f83e1..e6efb89f3b0e7 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -60,6 +60,7 @@ # This version currently matches the node version that we ship with emsdk # which means that we can say for sure that this version is well supported. MINIMUM_NODE_VERSION = (16, 20, 0) +EXPECTED_LLVM_STABLE_VERSION = 19 EXPECTED_LLVM_VERSION = 20 # These get set by setup_temp_dirs @@ -298,9 +299,18 @@ def get_clang_version(): return m and m.group(1) +def is_llvm_stable(): + if SKIP_SUBPROCS: + return False + return get_clang_version().startswith('%d.' % EXPECTED_LLVM_STABLE_VERSION) + + def check_llvm_version(): + if is_llvm_stable(): + diagnostics.warning('experimental', f'Use of emscripten with LLVM stable (v{EXPECTED_LLVM_STABLE_VERSION}) is currently experimental, not all features are supported') actual = get_clang_version() - if actual.startswith('%d.' % EXPECTED_LLVM_VERSION): + expected = [EXPECTED_LLVM_VERSION, EXPECTED_LLVM_STABLE_VERSION] + if any(actual.startswith('%d.' % e) for e in expected): return True # When running in CI environment we also silently allow the next major # version of LLVM here so that new versions of LLVM can be rolled in @@ -308,7 +318,7 @@ def check_llvm_version(): if 'BUILDBOT_BUILDNUMBER' in os.environ: if actual.startswith('%d.' % (EXPECTED_LLVM_VERSION + 1)): return True - diagnostics.warning('version-check', 'LLVM version for clang executable "%s" appears incorrect (seeing "%s", expected "%s")', CLANG_CC, actual, EXPECTED_LLVM_VERSION) + diagnostics.warning('version-check', f'LLVM version for clang executable "{CLANG_CC}" appears incorrect (seeing "{actual}", expected "{EXPECTED_LLVM_VERSION}" or "{EXPECTED_LLVM_STABLE_VERSION}")') return False