From 2bd310c99a6f7fec75d943ed07839db4e195c4ef Mon Sep 17 00:00:00 2001 From: Channing Conger Date: Fri, 8 May 2026 18:27:22 +0000 Subject: [PATCH] fix(v8): restore Linux sandbox artifact builds Keep non-Windows rusty-v8 consumers on the resolved 147.4.0 source-built graph. Avoid mixing LLVM's default libc++ headers into rusty-v8's custom libc++ build, propagate that configuration to external C++ deps, and export the musl-specific libc++ define through the shared header target. Also make checksum validation follow the remaining prebuilt asset version while the source-build migration is in progress. Co-authored-by: Codex --- .github/scripts/rusty_v8_bazel.py | 11 +++ .github/scripts/rusty_v8_module_bazel.py | 13 +++ .github/scripts/test_rusty_v8_bazel.py | 78 ++++++++++++++++++ MODULE.bazel | 1 + patches/BUILD.bazel | 1 + patches/llvm_rusty_v8_custom_libcxx.patch | 79 +++++++++++++++++++ patches/rules_cc_rusty_v8_custom_libcxx.patch | 17 +++- third_party/v8/BUILD.bazel | 33 ++++---- third_party/v8/README.md | 9 ++- third_party/v8/libcxx.BUILD.bazel | 2 +- third_party/v8/libcxxabi.BUILD.bazel | 2 +- 11 files changed, 222 insertions(+), 24 deletions(-) create mode 100644 patches/llvm_rusty_v8_custom_libcxx.patch diff --git a/.github/scripts/rusty_v8_bazel.py b/.github/scripts/rusty_v8_bazel.py index f380cc7a51..562accd58a 100644 --- a/.github/scripts/rusty_v8_bazel.py +++ b/.github/scripts/rusty_v8_bazel.py @@ -15,6 +15,7 @@ from pathlib import Path from rusty_v8_module_bazel import ( RustyV8ChecksumError, check_module_bazel, + rusty_v8_http_file_versions, update_module_bazel, ) @@ -172,6 +173,16 @@ def rusty_v8_checksum_manifest_path(version: str) -> Path: def command_version(version: str | None) -> str: if version is not None: return version + + manifest_versions = rusty_v8_http_file_versions(MODULE_BAZEL.read_text()) + if len(manifest_versions) == 1: + return manifest_versions[0] + if len(manifest_versions) > 1: + raise SystemExit( + "expected at most one rusty_v8 http_file version in MODULE.bazel, " + f"found: {manifest_versions}; pass --version explicitly" + ) + return resolved_v8_crate_version() diff --git a/.github/scripts/rusty_v8_module_bazel.py b/.github/scripts/rusty_v8_module_bazel.py index 7f474fc5d2..5d5dec08d5 100644 --- a/.github/scripts/rusty_v8_module_bazel.py +++ b/.github/scripts/rusty_v8_module_bazel.py @@ -9,6 +9,7 @@ from pathlib import Path SHA256_RE = re.compile(r"[0-9a-f]{64}") HTTP_FILE_BLOCK_RE = re.compile(r"(?ms)^http_file\(\n.*?^\)\n?") +HTTP_FILE_VERSION_RE = re.compile(r"^rusty_v8_([0-9]+)_([0-9]+)_([0-9]+)_") class RustyV8ChecksumError(ValueError): @@ -95,6 +96,18 @@ def rusty_v8_http_files(module_bazel: str, version: str) -> list[RustyV8HttpFile return entries +def rusty_v8_http_file_versions(module_bazel: str) -> list[str]: + versions = set() + for match in HTTP_FILE_BLOCK_RE.finditer(module_bazel): + name = string_field(match.group(0), "name") + if not name: + continue + version_match = HTTP_FILE_VERSION_RE.match(name) + if version_match: + versions.add(".".join(version_match.groups())) + return sorted(versions) + + def module_entry_set_errors( entries: list[RustyV8HttpFile], checksums: dict[str, str], diff --git a/.github/scripts/test_rusty_v8_bazel.py b/.github/scripts/test_rusty_v8_bazel.py index 66c69f9a5b..f516b871e3 100644 --- a/.github/scripts/test_rusty_v8_bazel.py +++ b/.github/scripts/test_rusty_v8_bazel.py @@ -13,6 +13,56 @@ import rusty_v8_module_bazel class RustyV8BazelTest(unittest.TestCase): + def test_non_windows_consumer_selectors_track_resolved_crate_version(self) -> None: + build_bazel = ( + rusty_v8_bazel.ROOT / "third_party" / "v8" / "BUILD.bazel" + ).read_text() + version_suffix = rusty_v8_bazel.resolved_v8_crate_version().replace(".", "_") + + for selector in [ + "aarch64_apple_darwin_bazel", + "aarch64_unknown_linux_gnu_bazel", + "aarch64_unknown_linux_musl_release_base", + "x86_64_apple_darwin_bazel", + "x86_64_unknown_linux_gnu_bazel", + "x86_64_unknown_linux_musl_release", + ]: + self.assertIn( + f":v8_{version_suffix}_{selector}", + build_bazel, + ) + + for selector in [ + "aarch64_apple_darwin", + "aarch64_unknown_linux_gnu", + "aarch64_unknown_linux_musl", + "x86_64_apple_darwin", + "x86_64_unknown_linux_gnu", + "x86_64_unknown_linux_musl", + ]: + self.assertIn( + f":src_binding_release_{selector}_{version_suffix}_release", + build_bazel, + ) + + def test_command_version_tracks_remaining_http_file_assets(self) -> None: + with TemporaryDirectory() as temp_dir: + module_bazel = Path(temp_dir) / "MODULE.bazel" + module_bazel.write_text( + textwrap.dedent( + """\ + http_file( + name = "rusty_v8_146_4_0_x86_64_unknown_linux_gnu_archive", + downloaded_file_path = "librusty_v8_release_x86_64-unknown-linux-gnu.a.gz", + urls = ["https://example.test/archive.gz"], + ) + """ + ) + ) + + with patch.object(rusty_v8_bazel, "MODULE_BAZEL", module_bazel): + self.assertEqual("146.4.0", rusty_v8_bazel.command_version(None)) + def test_artifact_bazel_configs_always_enable_upstream_libcxx(self) -> None: self.assertEqual( ["rusty-v8-upstream-libcxx"], @@ -246,6 +296,34 @@ class RustyV8BazelTest(unittest.TestCase): "146.4.0", ) + def test_rusty_v8_http_file_versions(self) -> None: + module_bazel = textwrap.dedent( + """\ + http_file( + name = "rusty_v8_146_4_0_x86_64_unknown_linux_gnu_archive", + downloaded_file_path = "archive.gz", + urls = ["https://example.test/archive.gz"], + ) + + http_file( + name = "rusty_v8_147_4_0_x86_64_unknown_linux_gnu_archive", + downloaded_file_path = "new-archive.gz", + urls = ["https://example.test/new-archive.gz"], + ) + + http_file( + name = "unrelated_archive", + downloaded_file_path = "other.gz", + urls = ["https://example.test/other.gz"], + ) + """ + ) + + self.assertEqual( + ["146.4.0", "147.4.0"], + rusty_v8_module_bazel.rusty_v8_http_file_versions(module_bazel), + ) + if __name__ == "__main__": unittest.main() diff --git a/MODULE.bazel b/MODULE.bazel index dac8ded4ff..4febc090a2 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -10,6 +10,7 @@ single_version_override( module_name = "llvm", patch_strip = 1, patches = [ + "//patches:llvm_rusty_v8_custom_libcxx.patch", "//patches:llvm_windows_symlink_extract.patch", ], ) diff --git a/patches/BUILD.bazel b/patches/BUILD.bazel index 3a5345de0f..72d6990790 100644 --- a/patches/BUILD.bazel +++ b/patches/BUILD.bazel @@ -4,6 +4,7 @@ exports_files([ "aws-lc-sys_windows_msvc_prebuilt_nasm.patch", "aws-lc-sys_windows_msvc_memcmp_probe.patch", "bzip2_windows_stack_args.patch", + "llvm_rusty_v8_custom_libcxx.patch", "llvm_windows_symlink_extract.patch", "rules_rust_windows_bootstrap_process_wrapper_linker.patch", "rules_rust_windows_build_script_runner_paths.patch", diff --git a/patches/llvm_rusty_v8_custom_libcxx.patch b/patches/llvm_rusty_v8_custom_libcxx.patch new file mode 100644 index 0000000000..c30a28ac63 --- /dev/null +++ b/patches/llvm_rusty_v8_custom_libcxx.patch @@ -0,0 +1,79 @@ +diff --git a/toolchain/BUILD.bazel b/toolchain/BUILD.bazel +index fa00156236..bf0ee9d368 100644 +--- a/toolchain/BUILD.bazel ++++ b/toolchain/BUILD.bazel +@@ -222,11 +222,16 @@ cc_args_list( + + # TODO(cerisier): extract those into proper semantic args list. + # TODO(zbarsky): This must match llvm/toolchains/llvm.bzl ++_DEFAULT_LIBCXX_HEADER_ARGS = select({ ++ "@@//third_party/v8:use_rusty_v8_custom_libcxx": [], ++ "//conditions:default": [ ++ "//toolchain/args:libcxx_headers_include_search_paths", ++ ], ++}) ++ + cc_args_list( + name = "linux_toolchain_args", +- args = [ +- "//toolchain/args:libcxx_headers_include_search_paths", +- ] + select({ ++ args = _DEFAULT_LIBCXX_HEADER_ARGS + select({ + "//platforms/config:musl": [ + "//toolchain/args/linux:kernel_headers_include_search_paths", + "//toolchain/args/linux:musl_libc_headers_include_search_paths", +@@ -252,8 +257,7 @@ cc_args_list( + # TODO(zbarsky): This must match llvm/toolchains/llvm.bzl + cc_args_list( + name = "windows_toolchain_args", +- args = [ +- "//toolchain/args:libcxx_headers_include_search_paths", ++ args = _DEFAULT_LIBCXX_HEADER_ARGS + [ + "//toolchain/args/windows:mingw_headers_include_search_paths", + ], + ) +diff --git a/toolchain/llvm/llvm.bzl b/toolchain/llvm/llvm.bzl +index d36d8b94bd..97aa879d4a 100644 +--- a/toolchain/llvm/llvm.bzl ++++ b/toolchain/llvm/llvm.bzl +@@ -186,16 +186,22 @@ def declare_llvm_targets(*, suffix = ""): + ], + ) + ++ default_libcxx_target_headers = select({ ++ "@@//third_party/v8:use_rusty_v8_custom_libcxx": [], ++ "//conditions:default": [ ++ "@llvm//runtimes/libcxx:libcxx_headers_include_search_directory", ++ "@llvm//runtimes/libcxx:libcxxabi_headers_include_search_directory", ++ ], ++ }) ++ + # This must match //toolchain:linux_toolchain_args + include_path( + name = "linux_target_headers", + srcs = [ + ":builtin_resource_dir", +- "@llvm//runtimes/libcxx:libcxx_headers_include_search_directory", +- "@llvm//runtimes/libcxx:libcxxabi_headers_include_search_directory", + "@kernel_headers//:kernel_headers_directory", + "@llvm//sanitizers:sanitizers_headers_include_search_directory", +- ] + select({ ++ ] + default_libcxx_target_headers + select({ + "@llvm//platforms/config:musl": [ + "@llvm//runtimes/musl:musl_headers_include_search_directory", + ], +@@ -210,13 +216,11 @@ def declare_llvm_targets(*, suffix = ""): + name = "windows_target_headers", + srcs = [ + ":builtin_resource_dir", +- "@llvm//runtimes/libcxx:libcxx_headers_include_search_directory", +- "@llvm//runtimes/libcxx:libcxxabi_headers_include_search_directory", + "@mingw//:mingw_generated_headers_crt_directory", + "@mingw//:mingw_w64_headers_include_directory", + "@mingw//:mingw_w64_headers_crt_directory", + "@mingw//:mingw_w64_winpthreads_include_directory", +- ], ++ ] + default_libcxx_target_headers, + ) + + include_path( diff --git a/patches/rules_cc_rusty_v8_custom_libcxx.patch b/patches/rules_cc_rusty_v8_custom_libcxx.patch index 1e4e7d9d53..3efda03525 100644 --- a/patches/rules_cc_rusty_v8_custom_libcxx.patch +++ b/patches/rules_cc_rusty_v8_custom_libcxx.patch @@ -1,7 +1,9 @@ diff --git a/cc/cc_library.bzl b/cc/cc_library.bzl +index c45c5fd954..2e3a01f12a 100644 --- a/cc/cc_library.bzl +++ b/cc/cc_library.bzl -@@ -16,4 +16,31 @@ +@@ -15,5 +15,39 @@ + load("@cc_compatibility_proxy//:proxy.bzl", _cc_library = "cc_library") +_RUSTY_V8_CUSTOM_LIBCXX_COPTS = select({ @@ -22,10 +24,17 @@ diff --git a/cc/cc_library.bzl b/cc/cc_library.bzl + "//conditions:default": [], +}) + ++_RUSTY_V8_CUSTOM_LIBCXX_REPOS = [ ++ # V8 and ICU are patched in-tree. These external C++ dependencies still ++ # build inside the artifact closure once the LLVM toolchain's default ++ # libc++ headers are suppressed. ++ "@abseil-cpp+", ++ "@v8++http_archive+highway", ++ "@v8++http_archive+simdutf", ++] ++ +def _should_use_rusty_v8_custom_libcxx(): -+ # V8 and ICU are patched in-tree. Abseil is the only external dependency -+ # that still exchanges STL types with the artifact objects. -+ return native.repository_name() == "@abseil-cpp+" ++ return native.repository_name() in _RUSTY_V8_CUSTOM_LIBCXX_REPOS + def cc_library(**kwargs): + if _should_use_rusty_v8_custom_libcxx(): diff --git a/third_party/v8/BUILD.bazel b/third_party/v8/BUILD.bazel index 9d26188348..190f11f095 100644 --- a/third_party/v8/BUILD.bazel +++ b/third_party/v8/BUILD.bazel @@ -139,34 +139,34 @@ alias( alias( name = "rusty_v8_archive_for_target", actual = select({ - "@rules_rs//rs/experimental/platforms/config:aarch64-apple-darwin": ":v8_146_4_0_aarch64_apple_darwin_bazel", + "@rules_rs//rs/experimental/platforms/config:aarch64-apple-darwin": ":v8_147_4_0_aarch64_apple_darwin_bazel", "@rules_rs//rs/experimental/platforms/config:aarch64-pc-windows-gnullvm": ":v8_146_4_0_aarch64_pc_windows_gnullvm", "@rules_rs//rs/experimental/platforms/config:aarch64-pc-windows-msvc": ":v8_146_4_0_aarch64_pc_windows_msvc", - "@rules_rs//rs/experimental/platforms/config:aarch64-unknown-linux-gnu": ":v8_146_4_0_aarch64_unknown_linux_gnu_bazel", - ":platform_aarch64_unknown_linux_musl": ":v8_146_4_0_aarch64_unknown_linux_musl_release_base", - "@rules_rs//rs/experimental/platforms/config:x86_64-apple-darwin": ":v8_146_4_0_x86_64_apple_darwin_bazel", + "@rules_rs//rs/experimental/platforms/config:aarch64-unknown-linux-gnu": ":v8_147_4_0_aarch64_unknown_linux_gnu_bazel", + ":platform_aarch64_unknown_linux_musl": ":v8_147_4_0_aarch64_unknown_linux_musl_release_base", + "@rules_rs//rs/experimental/platforms/config:x86_64-apple-darwin": ":v8_147_4_0_x86_64_apple_darwin_bazel", "@rules_rs//rs/experimental/platforms/config:x86_64-pc-windows-gnullvm": ":v8_146_4_0_x86_64_pc_windows_gnullvm", "@rules_rs//rs/experimental/platforms/config:x86_64-pc-windows-msvc": ":v8_146_4_0_x86_64_pc_windows_msvc", - "@rules_rs//rs/experimental/platforms/config:x86_64-unknown-linux-gnu": ":v8_146_4_0_x86_64_unknown_linux_gnu_bazel", - ":platform_x86_64_unknown_linux_musl": ":v8_146_4_0_x86_64_unknown_linux_musl_release", - "//conditions:default": ":v8_146_4_0_x86_64_unknown_linux_gnu_bazel", + "@rules_rs//rs/experimental/platforms/config:x86_64-unknown-linux-gnu": ":v8_147_4_0_x86_64_unknown_linux_gnu_bazel", + ":platform_x86_64_unknown_linux_musl": ":v8_147_4_0_x86_64_unknown_linux_musl_release", + "//conditions:default": ":v8_147_4_0_x86_64_unknown_linux_gnu_bazel", }), ) alias( name = "rusty_v8_binding_for_target", actual = select({ - "@rules_rs//rs/experimental/platforms/config:aarch64-apple-darwin": ":src_binding_release_aarch64_apple_darwin", + "@rules_rs//rs/experimental/platforms/config:aarch64-apple-darwin": ":src_binding_release_aarch64_apple_darwin_147_4_0_release", "@rules_rs//rs/experimental/platforms/config:aarch64-pc-windows-gnullvm": ":src_binding_release_aarch64_pc_windows_gnullvm", "@rules_rs//rs/experimental/platforms/config:aarch64-pc-windows-msvc": ":src_binding_release_aarch64_pc_windows_msvc", - "@rules_rs//rs/experimental/platforms/config:aarch64-unknown-linux-gnu": ":src_binding_release_aarch64_unknown_linux_gnu", - ":platform_aarch64_unknown_linux_musl": ":src_binding_release_aarch64_unknown_linux_musl", - "@rules_rs//rs/experimental/platforms/config:x86_64-apple-darwin": ":src_binding_release_x86_64_apple_darwin", + "@rules_rs//rs/experimental/platforms/config:aarch64-unknown-linux-gnu": ":src_binding_release_aarch64_unknown_linux_gnu_147_4_0_release", + ":platform_aarch64_unknown_linux_musl": ":src_binding_release_aarch64_unknown_linux_musl_147_4_0_release", + "@rules_rs//rs/experimental/platforms/config:x86_64-apple-darwin": ":src_binding_release_x86_64_apple_darwin_147_4_0_release", "@rules_rs//rs/experimental/platforms/config:x86_64-pc-windows-gnullvm": ":src_binding_release_x86_64_pc_windows_gnullvm", "@rules_rs//rs/experimental/platforms/config:x86_64-pc-windows-msvc": ":src_binding_release_x86_64_pc_windows_msvc", - "@rules_rs//rs/experimental/platforms/config:x86_64-unknown-linux-gnu": ":src_binding_release_x86_64_unknown_linux_gnu", - ":platform_x86_64_unknown_linux_musl": ":src_binding_release_x86_64_unknown_linux_musl", - "//conditions:default": ":src_binding_release_x86_64_unknown_linux_gnu", + "@rules_rs//rs/experimental/platforms/config:x86_64-unknown-linux-gnu": ":src_binding_release_x86_64_unknown_linux_gnu_147_4_0_release", + ":platform_x86_64_unknown_linux_musl": ":src_binding_release_x86_64_unknown_linux_musl_147_4_0_release", + "//conditions:default": ":src_binding_release_x86_64_unknown_linux_gnu_147_4_0_release", }), ) @@ -190,6 +190,11 @@ V8_STATIC_LIBRARY_FEATURES = [ cc_library( name = "rusty_v8_custom_libcxx_headers", + defines = select({ + ":platform_aarch64_unknown_linux_musl": ["ANDROID_HOST_MUSL"], + ":platform_x86_64_unknown_linux_musl": ["ANDROID_HOST_MUSL"], + "//conditions:default": [], + }), deps = [ "@rusty_v8_libcxx//:headers", "@rusty_v8_libcxxabi//:headers", diff --git a/third_party/v8/README.md b/third_party/v8/README.md index dc38cdc5da..df54fb7a7f 100644 --- a/third_party/v8/README.md +++ b/third_party/v8/README.md @@ -23,16 +23,17 @@ Current pinned versions: - Rust crate: `v8 = =147.4.0` - Embedded upstream V8 source for Bazel-produced release builds: `14.7.173.20` -When bumping the Rust crate version, keep the checked-in checksum manifest and -`MODULE.bazel` in sync: +When changing the remaining prebuilt `rusty_v8` `http_file` inputs, keep the +checked-in checksum manifest and `MODULE.bazel` in sync: ```bash python3 .github/scripts/rusty_v8_bazel.py update-module-bazel python3 .github/scripts/rusty_v8_bazel.py check-module-bazel ``` -The commands read `third_party/v8/rusty_v8_.sha256` by default -and validate every matching `rusty_v8_` `http_file` entry. +The commands default to the single `rusty_v8_*` `http_file` version still +present in `MODULE.bazel` and validate every matching entry. During the source +build rollout, that asset version can lag the resolved Rust crate version. CI runs the check command to block checksum drift. The consumer-facing selectors are: diff --git a/third_party/v8/libcxx.BUILD.bazel b/third_party/v8/libcxx.BUILD.bazel index 5550cfd0a2..71a8f8ddce 100644 --- a/third_party/v8/libcxx.BUILD.bazel +++ b/third_party/v8/libcxx.BUILD.bazel @@ -66,7 +66,7 @@ LIBCXX_SRCS = [ cc_library( name = "headers", hdrs = glob(["include/**"]), - includes = ["include"], + strip_include_prefix = "include", deps = ["@//third_party/v8/libcxx_config:headers"], ) diff --git a/third_party/v8/libcxxabi.BUILD.bazel b/third_party/v8/libcxxabi.BUILD.bazel index de4289b4dc..0645511db7 100644 --- a/third_party/v8/libcxxabi.BUILD.bazel +++ b/third_party/v8/libcxxabi.BUILD.bazel @@ -16,7 +16,7 @@ config_setting( cc_library( name = "headers", hdrs = glob(["include/**"]), - includes = ["include"], + strip_include_prefix = "include", ) cc_runtime_stage0_library(