diff --git a/.github/scripts/rusty_v8_bazel.py b/.github/scripts/rusty_v8_bazel.py index 41a733a971..33455b93a1 100644 --- a/.github/scripts/rusty_v8_bazel.py +++ b/.github/scripts/rusty_v8_bazel.py @@ -11,7 +11,6 @@ import subprocess import sys import tempfile import tomllib -import urllib.request from pathlib import Path from rusty_v8_module_bazel import ( @@ -28,71 +27,6 @@ STATIC_RUNTIME_ARCHIVE_LABELS = [ "@llvm//runtimes/libcxx:libcxx.static", "@llvm//runtimes/libcxx:libcxxabi.static", ] -DARWIN_RUNTIME_ARCHIVE_MEMBERS = [ - "algorithm.o", - "any.o", - "atomic.o", - "barrier.o", - "bind.o", - "call_once.o", - "charconv.o", - "chrono.o", - "condition_variable.o", - "condition_variable_destructor.o", - "error_category.o", - "exception.o", - "directory_iterator.o", - "filesystem_error.o", - "operations.o", - "path.o", - "functional.o", - "future.o", - "hash.o", - "ios.o", - "ios.instantiations.o", - "iostream.o", - "locale.o", - "memory.o", - "mutex.o", - "mutex_destructor.o", - "new_handler.o", - "new_helpers.o", - "optional.o", - "random.o", - "random_shuffle.o", - "regex.o", - "d2fixed.o", - "d2s.o", - "f2s.o", - "shared_mutex.o", - "stdexcept.o", - "string.o", - "strstream.o", - "system_error.o", - "thread.o", - "typeinfo.o", - "valarray.o", - "variant.o", - "vector.o", - "verbose_abort.o", - "new.o", - "abort_message.o", - "cxa_aux_runtime.o", - "cxa_default_handlers.o", - "cxa_exception.o", - "cxa_exception_storage.o", - "cxa_handlers.o", - "cxa_personality.o", - "cxa_vector.o", - "cxa_virtual.o", - "fallback_malloc.o", - "private_typeinfo.o", - "stdlib_exception.o", - "stdlib_stdexcept.o", - "stdlib_typeinfo.o", - "cxa_guard.o", - "cxa_demangle.o", -] LLVM_AR_LABEL = "@llvm//tools:llvm-ar" LLVM_RANLIB_LABEL = "@llvm//tools:llvm-ranlib" RELEASE_ARTIFACT_PROFILE = "release" @@ -265,18 +199,7 @@ def staged_checksums_name(target: str, artifact_profile: str) -> str: def needs_merged_runtime_archive(target: str, source_path: Path) -> bool: return source_path.suffix == ".a" and target.endswith( - ("-apple-darwin", "-unknown-linux-gnu", "-unknown-linux-musl") - ) - - -def needs_built_runtime_archives(target: str) -> bool: - return target.endswith(("-unknown-linux-gnu", "-unknown-linux-musl")) - - -def upstream_rusty_v8_archive_url(target: str, version: str) -> str: - return ( - "https://github.com/denoland/rusty_v8/releases/download/" - f"v{version}/librusty_v8_release_{target}.a.gz" + ("-unknown-linux-gnu", "-unknown-linux-musl") ) @@ -384,113 +307,62 @@ def merged_built_runtime_archive( ) -def downloaded_darwin_runtime_archive( - target: str, - version: str, - llvm_ar: Path, -) -> Path: - temp_dir = Path(tempfile.mkdtemp(prefix="rusty-v8-darwin-runtime-")) - compressed_archive = temp_dir / f"librusty_v8_release_{target}.a.gz" - source_archive = temp_dir / f"librusty_v8_release_{target}.a" - runtime_archive = temp_dir / f"libcxx_runtime_{target}.a" - - with urllib.request.urlopen(upstream_rusty_v8_archive_url(target, version)) as src: - with compressed_archive.open("wb") as dst: - shutil.copyfileobj(src, dst) - with gzip.open(compressed_archive, "rb") as src: - with source_archive.open("wb") as dst: - shutil.copyfileobj(src, dst) - - listed_members = subprocess.run( - [str(llvm_ar), "t", str(source_archive)], - cwd=ROOT, - check=True, - capture_output=True, - text=True, - ).stdout.splitlines() - missing_members = [ - member for member in DARWIN_RUNTIME_ARCHIVE_MEMBERS if member not in listed_members - ] - if missing_members: - raise SystemExit( - f"missing Darwin runtime members in {source_archive}: {missing_members}" - ) - - subprocess.run( - [ - str(llvm_ar), - "x", - str(source_archive), - *DARWIN_RUNTIME_ARCHIVE_MEMBERS, - ], - cwd=temp_dir, - check=True, - ) - merge_commands = "\n".join( - [ - f"create {runtime_archive}", - *[f"addmod {temp_dir / member}" for member in DARWIN_RUNTIME_ARCHIVE_MEMBERS], - "save", - "end", - ] - ) - subprocess.run( - [str(llvm_ar), "-M"], - cwd=ROOT, - check=True, - input=merge_commands, - text=True, - ) - return runtime_archive +def upstream_release_pair_paths(source_root: Path, target: str) -> tuple[Path, Path]: + lib_name = "rusty_v8.lib" if target.endswith("-pc-windows-msvc") else "librusty_v8.a" + gn_out = source_root / "target" / target / "release" / "gn_out" + return gn_out / "obj" / lib_name, gn_out / "src_binding.rs" -def merged_darwin_runtime_archive( - platform: str, +def stage_artifacts( target: str, lib_path: Path, - compilation_mode: str = "fastbuild", - bazel_configs: list[str] | None = None, -) -> Path: - llvm_ar = host_runnable_bazel_output_file( - platform, - LLVM_AR_LABEL, - compilation_mode, - bazel_configs, - ) - version = resolved_v8_crate_version() - runtime_archive = downloaded_darwin_runtime_archive(target, version, llvm_ar) - return merged_archive( - platform, - lib_path, - [runtime_archive], - compilation_mode, - bazel_configs, - ) + binding_path: Path, + output_dir: Path, + sandbox: bool, +) -> None: + missing_paths = [str(path) for path in [lib_path, binding_path] if not path.exists()] + if missing_paths: + raise SystemExit(f"missing release outputs for {target}: {missing_paths}") + + output_dir.mkdir(parents=True, exist_ok=True) + artifact_profile = SANDBOX_ARTIFACT_PROFILE if sandbox else RELEASE_ARTIFACT_PROFILE + staged_library = output_dir / staged_archive_name(target, lib_path, artifact_profile) + staged_binding = output_dir / staged_binding_name(target, artifact_profile) + + with lib_path.open("rb") as src, staged_library.open("wb") as dst: + with gzip.GzipFile( + filename="", + mode="wb", + fileobj=dst, + compresslevel=6, + mtime=0, + ) as gz: + shutil.copyfileobj(src, gz) + + shutil.copyfile(binding_path, staged_binding) + + staged_checksums = output_dir / staged_checksums_name(target, artifact_profile) + with staged_checksums.open("w", encoding="utf-8") as checksums: + for path in [staged_library, staged_binding]: + digest = hashlib.sha256() + with path.open("rb") as artifact: + for chunk in iter(lambda: artifact.read(1024 * 1024), b""): + digest.update(chunk) + checksums.write(f"{digest.hexdigest()} {path.name}\n") + + print(staged_library) + print(staged_binding) + print(staged_checksums) -def runtime_merged_archive( - platform: str, +def stage_upstream_release_pair( + source_root: Path, target: str, - lib_path: Path, - compilation_mode: str = "fastbuild", - bazel_configs: list[str] | None = None, -) -> Path: - if target.endswith("-apple-darwin"): - return merged_darwin_runtime_archive( - platform, - target, - lib_path, - compilation_mode, - bazel_configs, - ) - if not needs_built_runtime_archives(target): - raise SystemExit(f"unsupported runtime merge target: {target}") - return merged_built_runtime_archive( - platform, - lib_path, - compilation_mode, - bazel_configs, - ) + output_dir: Path, + sandbox: bool = False, +) -> None: + lib_path, binding_path = upstream_release_pair_paths(source_root, target) + stage_artifacts(target, lib_path, binding_path, output_dir, sandbox) def stage_release_pair( @@ -518,40 +390,12 @@ def stage_release_pair( except StopIteration as exc: raise SystemExit(f"missing Rust binding output for {target}") from exc - output_dir.mkdir(parents=True, exist_ok=True) - artifact_profile = SANDBOX_ARTIFACT_PROFILE if sandbox else RELEASE_ARTIFACT_PROFILE - staged_library = output_dir / staged_archive_name(target, lib_path, artifact_profile) - staged_binding = output_dir / staged_binding_name(target, artifact_profile) source_archive = ( - runtime_merged_archive(platform, target, lib_path, compilation_mode, bazel_configs) + merged_built_runtime_archive(platform, lib_path, compilation_mode, bazel_configs) if needs_merged_runtime_archive(target, lib_path) else lib_path ) - - with source_archive.open("rb") as src, staged_library.open("wb") as dst: - with gzip.GzipFile( - filename="", - mode="wb", - fileobj=dst, - compresslevel=6, - mtime=0, - ) as gz: - shutil.copyfileobj(src, gz) - - shutil.copyfile(binding_path, staged_binding) - - staged_checksums = output_dir / staged_checksums_name(target, artifact_profile) - with staged_checksums.open("w", encoding="utf-8") as checksums: - for path in [staged_library, staged_binding]: - digest = hashlib.sha256() - with path.open("rb") as artifact: - for chunk in iter(lambda: artifact.read(1024 * 1024), b""): - digest.update(chunk) - checksums.write(f"{digest.hexdigest()} {path.name}\n") - - print(staged_library) - print(staged_binding) - print(staged_checksums) + stage_artifacts(target, source_archive, binding_path, output_dir, sandbox) def parse_args() -> argparse.Namespace: @@ -575,6 +419,14 @@ def parse_args() -> argparse.Namespace: choices=["fastbuild", "opt", "dbg"], ) + stage_upstream_release_pair_parser = subparsers.add_parser( + "stage-upstream-release-pair" + ) + stage_upstream_release_pair_parser.add_argument("--source-root", type=Path, required=True) + stage_upstream_release_pair_parser.add_argument("--target", required=True) + stage_upstream_release_pair_parser.add_argument("--output-dir", required=True) + stage_upstream_release_pair_parser.add_argument("--sandbox", action="store_true") + subparsers.add_parser("resolved-v8-crate-version") check_module_bazel_parser = subparsers.add_parser("check-module-bazel") @@ -610,6 +462,14 @@ def main() -> int: sandbox=args.sandbox, ) return 0 + if args.command == "stage-upstream-release-pair": + stage_upstream_release_pair( + source_root=args.source_root, + target=args.target, + output_dir=Path(args.output_dir), + sandbox=args.sandbox, + ) + return 0 if args.command == "resolved-v8-crate-version": print(resolved_v8_crate_version()) return 0 diff --git a/.github/scripts/test_rusty_v8_bazel.py b/.github/scripts/test_rusty_v8_bazel.py index e2f7c17d1b..5d68336980 100644 --- a/.github/scripts/test_rusty_v8_bazel.py +++ b/.github/scripts/test_rusty_v8_bazel.py @@ -4,6 +4,7 @@ from __future__ import annotations import textwrap import unittest +from tempfile import TemporaryDirectory from pathlib import Path from unittest.mock import Mock from unittest.mock import patch @@ -59,12 +60,17 @@ class RustyV8BazelTest(unittest.TestCase): def test_needs_merged_runtime_archive(self) -> None: for target in [ - "x86_64-apple-darwin", "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl", ]: self.assertTrue(rusty_v8_bazel.needs_merged_runtime_archive(target, Path("v8.a"))) + self.assertFalse( + rusty_v8_bazel.needs_merged_runtime_archive( + "x86_64-apple-darwin", + Path("v8.a"), + ) + ) self.assertFalse( rusty_v8_bazel.needs_merged_runtime_archive( "x86_64-pc-windows-msvc", @@ -72,59 +78,68 @@ class RustyV8BazelTest(unittest.TestCase): ) ) - def test_needs_built_runtime_archives(self) -> None: - for target in [ - "x86_64-unknown-linux-gnu", - "x86_64-unknown-linux-musl", - ]: - self.assertTrue(rusty_v8_bazel.needs_built_runtime_archives(target)) - - self.assertFalse(rusty_v8_bazel.needs_built_runtime_archives("x86_64-apple-darwin")) - self.assertFalse(rusty_v8_bazel.needs_built_runtime_archives("x86_64-pc-windows-msvc")) - - def test_upstream_rusty_v8_archive_url(self) -> None: + def test_upstream_release_pair_paths(self) -> None: self.assertEqual( ( - "https://github.com/denoland/rusty_v8/releases/download/" - "v147.4.0/librusty_v8_release_x86_64-apple-darwin.a.gz" + Path( + "/tmp/rusty_v8/target/x86_64-apple-darwin/release/gn_out/obj/" + "librusty_v8.a" + ), + Path( + "/tmp/rusty_v8/target/x86_64-apple-darwin/release/gn_out/" + "src_binding.rs" + ), ), - rusty_v8_bazel.upstream_rusty_v8_archive_url( + rusty_v8_bazel.upstream_release_pair_paths( + Path("/tmp/rusty_v8"), "x86_64-apple-darwin", - "147.4.0", - ), - ) - - @patch("rusty_v8_bazel.merged_built_runtime_archive") - @patch("rusty_v8_bazel.merged_darwin_runtime_archive") - def test_runtime_merged_archive_dispatches_by_target( - self, - merged_darwin_runtime_archive: Mock, - merged_built_runtime_archive: Mock, - ) -> None: - merged_darwin_runtime_archive.return_value = Path("/tmp/darwin.a") - merged_built_runtime_archive.return_value = Path("/tmp/linux.a") - - self.assertEqual( - Path("/tmp/darwin.a"), - rusty_v8_bazel.runtime_merged_archive( - "macos_amd64", - "x86_64-apple-darwin", - Path("/tmp/v8.a"), ), ) self.assertEqual( - Path("/tmp/linux.a"), - rusty_v8_bazel.runtime_merged_archive( - "linux_amd64", - "x86_64-unknown-linux-gnu", - Path("/tmp/v8.a"), + ( + Path( + "/tmp/rusty_v8/target/x86_64-pc-windows-msvc/release/gn_out/" + "obj/rusty_v8.lib" + ), + Path( + "/tmp/rusty_v8/target/x86_64-pc-windows-msvc/release/gn_out/" + "src_binding.rs" + ), ), - ) - with self.assertRaisesRegex(SystemExit, "unsupported runtime merge target"): - rusty_v8_bazel.runtime_merged_archive( - "windows_amd64", + rusty_v8_bazel.upstream_release_pair_paths( + Path("/tmp/rusty_v8"), "x86_64-pc-windows-msvc", - Path("/tmp/v8.a"), + ), + ) + + def test_stage_upstream_release_pair(self) -> None: + with TemporaryDirectory() as source_dir, TemporaryDirectory() as output_dir: + source_root = Path(source_dir) + gn_out = ( + source_root + / "target" + / "aarch64-apple-darwin" + / "release" + / "gn_out" + ) + (gn_out / "obj").mkdir(parents=True) + (gn_out / "obj" / "librusty_v8.a").write_bytes(b"archive") + (gn_out / "src_binding.rs").write_text("binding") + + rusty_v8_bazel.stage_upstream_release_pair( + source_root, + "aarch64-apple-darwin", + Path(output_dir), + sandbox=True, + ) + + self.assertEqual( + { + "librusty_v8_ptrcomp_sandbox_release_aarch64-apple-darwin.a.gz", + "src_binding_ptrcomp_sandbox_release_aarch64-apple-darwin.rs", + "rusty_v8_ptrcomp_sandbox_release_aarch64-apple-darwin.sha256", + }, + {path.name for path in Path(output_dir).iterdir()}, ) @patch("rusty_v8_bazel.ensure_bazel_output_files") diff --git a/.github/workflows/rusty-v8-release.yml b/.github/workflows/rusty-v8-release.yml index ff376f18b7..24c63bf703 100644 --- a/.github/workflows/rusty-v8-release.yml +++ b/.github/workflows/rusty-v8-release.yml @@ -64,62 +64,60 @@ jobs: matrix: include: - runner: ubuntu-24.04 - bazel_config: ci-v8 - platform: linux_amd64 + producer: upstream sandbox: true target: x86_64-unknown-linux-gnu variant: ptrcomp-sandbox - runner: ubuntu-24.04-arm - bazel_config: ci-v8 - platform: linux_arm64 + producer: upstream sandbox: true target: aarch64-unknown-linux-gnu variant: ptrcomp-sandbox - - runner: macos-15-xlarge - bazel_config: ci-macos - platform: macos_amd64 + - runner: macos-15-large + producer: upstream sandbox: true target: x86_64-apple-darwin variant: ptrcomp-sandbox - - runner: macos-15-xlarge - bazel_config: ci-macos - platform: macos_arm64 + - runner: macos-15 + producer: upstream sandbox: true target: aarch64-apple-darwin variant: ptrcomp-sandbox - runner: ubuntu-24.04 + producer: bazel bazel_config: ci-v8 platform: linux_amd64_musl sandbox: false target: x86_64-unknown-linux-musl variant: release - runner: ubuntu-24.04-arm + producer: bazel bazel_config: ci-v8 platform: linux_arm64_musl sandbox: false target: aarch64-unknown-linux-musl variant: release - runner: ubuntu-24.04 + producer: bazel bazel_config: ci-v8 platform: linux_amd64_musl sandbox: true target: x86_64-unknown-linux-musl variant: ptrcomp-sandbox - runner: ubuntu-24.04-arm + producer: bazel bazel_config: ci-v8 platform: linux_arm64_musl sandbox: true target: aarch64-unknown-linux-musl variant: ptrcomp-sandbox - - runner: ubuntu-24.04 - bazel_config: ci-v8 - platform: windows_amd64 + - runner: windows-2022 + producer: upstream sandbox: true target: x86_64-pc-windows-msvc variant: ptrcomp-sandbox - - runner: ubuntu-24.04-arm - bazel_config: ci-v8 - platform: windows_arm64 + - runner: windows-2022 + producer: upstream sandbox: true target: aarch64-pc-windows-msvc variant: ptrcomp-sandbox @@ -130,6 +128,7 @@ jobs: persist-credentials: false - name: Set up Bazel + if: matrix.producer == 'bazel' uses: ./.github/actions/setup-bazel-ci with: target: ${{ matrix.target }} @@ -139,7 +138,76 @@ jobs: with: python-version: "3.12" + - name: Configure git for upstream checkout + if: matrix.producer == 'upstream' + shell: bash + run: git config --global core.symlinks true + + - name: Check out upstream rusty_v8 + if: matrix.producer == 'upstream' + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + repository: denoland/rusty_v8 + ref: v${{ needs.metadata.outputs.v8_version }} + path: upstream-rusty-v8 + submodules: recursive + + - name: Set up upstream Rust toolchain + if: matrix.producer == 'upstream' + uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0 + with: + toolchain: "1.91.0" + targets: ${{ matrix.target }} + + - name: Install Clang for upstream Linux build + if: matrix.producer == 'upstream' && runner.os == 'Linux' + shell: bash + run: | + set -euo pipefail + + echo "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main" | sudo tee /etc/apt/sources.list.d/llvm-toolchain-noble-19.list + curl https://apt.llvm.org/llvm-snapshot.gpg.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/llvm-snapshot.gpg >/dev/null + sudo apt-get update + sudo apt-get install -y lld-19 clang-19 clang-tools-19 clang-tidy-19 clang-format-19 libclang-19-dev + echo "LIBCLANG_PATH=/usr/lib/llvm-19/lib" >> "${GITHUB_ENV}" + + - name: Set LIBCLANG_PATH for upstream macOS build + if: matrix.producer == 'upstream' && runner.os == 'macOS' + shell: bash + run: | + set -euo pipefail + xcode_clang_lib="$(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/lib" + echo "LIBCLANG_PATH=${xcode_clang_lib}" >> "${GITHUB_ENV}" + + - name: Install Chromium clang for ARM64 MSVC cross build + if: matrix.producer == 'upstream' && matrix.target == 'aarch64-pc-windows-msvc' + shell: bash + working-directory: upstream-rusty-v8 + run: python3 tools/clang/scripts/update.py + + - name: Build upstream rusty_v8 release pair + if: matrix.producer == 'upstream' + env: + TARGET: ${{ matrix.target }} + shell: bash + working-directory: upstream-rusty-v8 + run: | + set -euo pipefail + + cargo_args=( + build + --locked + --release + --target "${TARGET}" + ) + if [[ "${{ matrix.sandbox }}" == "true" ]]; then + cargo_args+=(--features v8_enable_sandbox) + fi + + V8_FROM_SOURCE=true cargo "${cargo_args[@]}" + - name: Build Bazel V8 release pair + if: matrix.producer == 'bazel' env: BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} PLATFORM: ${{ matrix.platform }} @@ -183,26 +251,38 @@ jobs: - name: Stage release pair env: PLATFORM: ${{ matrix.platform }} + PRODUCER: ${{ matrix.producer }} SANDBOX: ${{ matrix.sandbox }} TARGET: ${{ matrix.target }} shell: bash run: | set -euo pipefail - stage_args=( - --platform "${PLATFORM}" - --target "${TARGET}" - --compilation-mode opt - --output-dir "dist/${TARGET}" - ) - if [[ "${SANDBOX}" == "true" ]]; then - stage_args+=(--sandbox) + if [[ "${PRODUCER}" == "upstream" ]]; then + stage_args=( + --source-root upstream-rusty-v8 + --target "${TARGET}" + --output-dir "dist/${TARGET}" + ) + if [[ "${SANDBOX}" == "true" ]]; then + stage_args+=(--sandbox) + fi + python3 .github/scripts/rusty_v8_bazel.py stage-upstream-release-pair "${stage_args[@]}" else - stage_args+=(--bazel-config v8-release-compat) + stage_args=( + --platform "${PLATFORM}" + --target "${TARGET}" + --compilation-mode opt + --output-dir "dist/${TARGET}" + ) + if [[ "${SANDBOX}" == "true" ]]; then + stage_args+=(--sandbox) + else + stage_args+=(--bazel-config v8-release-compat) + fi + python3 .github/scripts/rusty_v8_bazel.py stage-release-pair "${stage_args[@]}" fi - python3 .github/scripts/rusty_v8_bazel.py stage-release-pair "${stage_args[@]}" - - name: Upload staged artifacts uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: diff --git a/.github/workflows/v8-canary.yml b/.github/workflows/v8-canary.yml index 42e9845821..d3c7c9ea48 100644 --- a/.github/workflows/v8-canary.yml +++ b/.github/workflows/v8-canary.yml @@ -70,53 +70,63 @@ jobs: matrix: include: - runner: ubuntu-24.04 - bazel_config: ci-v8 - platform: linux_amd64 + producer: upstream sandbox: true target: x86_64-unknown-linux-gnu variant: ptrcomp-sandbox - runner: ubuntu-24.04-arm - bazel_config: ci-v8 - platform: linux_arm64 + producer: upstream sandbox: true target: aarch64-unknown-linux-gnu variant: ptrcomp-sandbox - - runner: macos-15-xlarge - bazel_config: ci-macos - platform: macos_amd64 + - runner: macos-15-large + producer: upstream sandbox: true target: x86_64-apple-darwin variant: ptrcomp-sandbox - - runner: macos-15-xlarge - bazel_config: ci-macos - platform: macos_arm64 + - runner: macos-15 + producer: upstream sandbox: true target: aarch64-apple-darwin variant: ptrcomp-sandbox - runner: ubuntu-24.04 + producer: bazel bazel_config: ci-v8 platform: linux_amd64_musl sandbox: false target: x86_64-unknown-linux-musl variant: release - runner: ubuntu-24.04 + producer: bazel bazel_config: ci-v8 platform: linux_amd64_musl sandbox: true target: x86_64-unknown-linux-musl variant: ptrcomp-sandbox - runner: ubuntu-24.04-arm + producer: bazel bazel_config: ci-v8 platform: linux_arm64_musl sandbox: false target: aarch64-unknown-linux-musl variant: release - runner: ubuntu-24.04-arm + producer: bazel bazel_config: ci-v8 platform: linux_arm64_musl sandbox: true target: aarch64-unknown-linux-musl variant: ptrcomp-sandbox + - runner: windows-2022 + producer: upstream + sandbox: true + target: x86_64-pc-windows-msvc + variant: ptrcomp-sandbox + - runner: windows-2022 + producer: upstream + sandbox: true + target: aarch64-pc-windows-msvc + variant: ptrcomp-sandbox steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -125,6 +135,7 @@ jobs: persist-credentials: false - name: Set up Bazel + if: matrix.producer == 'bazel' uses: ./.github/actions/setup-bazel-ci with: target: ${{ matrix.target }} @@ -134,7 +145,76 @@ jobs: with: python-version: "3.12" + - name: Configure git for upstream checkout + if: matrix.producer == 'upstream' + shell: bash + run: git config --global core.symlinks true + + - name: Check out upstream rusty_v8 + if: matrix.producer == 'upstream' + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + repository: denoland/rusty_v8 + ref: v${{ needs.metadata.outputs.v8_version }} + path: upstream-rusty-v8 + submodules: recursive + + - name: Set up upstream Rust toolchain + if: matrix.producer == 'upstream' + uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0 + with: + toolchain: "1.91.0" + targets: ${{ matrix.target }} + + - name: Install Clang for upstream Linux build + if: matrix.producer == 'upstream' && runner.os == 'Linux' + shell: bash + run: | + set -euo pipefail + + echo "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main" | sudo tee /etc/apt/sources.list.d/llvm-toolchain-noble-19.list + curl https://apt.llvm.org/llvm-snapshot.gpg.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/llvm-snapshot.gpg >/dev/null + sudo apt-get update + sudo apt-get install -y lld-19 clang-19 clang-tools-19 clang-tidy-19 clang-format-19 libclang-19-dev + echo "LIBCLANG_PATH=/usr/lib/llvm-19/lib" >> "${GITHUB_ENV}" + + - name: Set LIBCLANG_PATH for upstream macOS build + if: matrix.producer == 'upstream' && runner.os == 'macOS' + shell: bash + run: | + set -euo pipefail + xcode_clang_lib="$(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/lib" + echo "LIBCLANG_PATH=${xcode_clang_lib}" >> "${GITHUB_ENV}" + + - name: Install Chromium clang for ARM64 MSVC cross build + if: matrix.producer == 'upstream' && matrix.target == 'aarch64-pc-windows-msvc' + shell: bash + working-directory: upstream-rusty-v8 + run: python3 tools/clang/scripts/update.py + + - name: Build upstream rusty_v8 release pair + if: matrix.producer == 'upstream' + env: + TARGET: ${{ matrix.target }} + shell: bash + working-directory: upstream-rusty-v8 + run: | + set -euo pipefail + + cargo_args=( + build + --locked + --release + --target "${TARGET}" + ) + if [[ "${{ matrix.sandbox }}" == "true" ]]; then + cargo_args+=(--features v8_enable_sandbox) + fi + + V8_FROM_SOURCE=true cargo "${cargo_args[@]}" + - name: Build Bazel V8 release pair + if: matrix.producer == 'bazel' env: BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} PLATFORM: ${{ matrix.platform }} @@ -176,26 +256,38 @@ jobs: - name: Stage release pair env: PLATFORM: ${{ matrix.platform }} + PRODUCER: ${{ matrix.producer }} SANDBOX: ${{ matrix.sandbox }} TARGET: ${{ matrix.target }} shell: bash run: | set -euo pipefail - stage_args=( - --platform "${PLATFORM}" - --target "${TARGET}" - --output-dir "dist/${TARGET}" - ) - if [[ "${SANDBOX}" == "true" ]]; then - stage_args+=(--sandbox) + if [[ "${PRODUCER}" == "upstream" ]]; then + stage_args=( + --source-root upstream-rusty-v8 + --target "${TARGET}" + --output-dir "dist/${TARGET}" + ) + if [[ "${SANDBOX}" == "true" ]]; then + stage_args+=(--sandbox) + fi + python3 .github/scripts/rusty_v8_bazel.py stage-upstream-release-pair "${stage_args[@]}" else - stage_args+=(--bazel-config v8-release-compat) + stage_args=( + --platform "${PLATFORM}" + --target "${TARGET}" + --output-dir "dist/${TARGET}" + ) + if [[ "${SANDBOX}" == "true" ]]; then + stage_args+=(--sandbox) + else + stage_args+=(--bazel-config v8-release-compat) + fi + python3 .github/scripts/rusty_v8_bazel.py stage-release-pair "${stage_args[@]}" fi - python3 .github/scripts/rusty_v8_bazel.py stage-release-pair "${stage_args[@]}" - - - name: Upload staged musl artifacts + - name: Upload staged artifacts uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: v8-canary-${{ needs.metadata.outputs.v8_version }}-${{ matrix.variant }}-${{ matrix.target }} diff --git a/third_party/v8/README.md b/third_party/v8/README.md index dae87f45d9..2d15a1b3dc 100644 --- a/third_party/v8/README.md +++ b/third_party/v8/README.md @@ -57,8 +57,11 @@ their raw names: - `src_binding_ptrcomp_sandbox_release_.rs` The dedicated publishing workflow is `.github/workflows/rusty-v8-release.yml`. -Every tagged run builds the current musl release pairs from source and keeps the -release artifacts as the statically linked form: +For GNU Linux, Darwin, and Windows MSVC, the workflow checks out the exact +upstream `denoland/rusty_v8` tag and uses its `V8_FROM_SOURCE=true` Cargo/GN +build to produce sandbox-profile artifacts with the same archive shape upstream +publishes. Musl remains an extra platform that upstream does not publish, so +tagged runs still build the current musl release pairs with our Bazel producer: - `//third_party/v8:rusty_v8_release_pair_x86_64_unknown_linux_musl` - `//third_party/v8:rusty_v8_release_pair_aarch64_unknown_linux_musl` @@ -76,12 +79,11 @@ The same run also builds the matching sandbox pair targets: If a tagged run targets an existing GitHub release, publication amends only the sandbox-profile files and leaves the current release-profile assets unchanged. -Unix sandbox archives are staged with matching static libc++ and libc++abi -runtime objects merged in so Cargo consumers can link them with the `v8` crate's -default `use_custom_libcxx` feature. Linux artifacts use the hermetic LLVM -runtime builds directly; Darwin artifacts reuse the matching runtime members -from the upstream `rusty_v8` archive because the upstream release already ships -those custom libc++ objects for Apple targets. +The upstream-shaped GNU, Darwin, and MSVC builds let GN fold custom libc++ into +the final archive the same way `rusty_v8` does for its own releases. Musl +sandbox archives still merge the matching static libc++ and libc++abi runtime +libraries after the Bazel build so Cargo consumers can link them with the `v8` +crate's default `use_custom_libcxx` feature. Cargo musl builds use `RUSTY_V8_ARCHIVE` plus a downloaded `RUSTY_V8_SRC_BINDING_PATH` to point at those `openai/codex` release assets