deno: build librusty_v8 from source

This commit is contained in:
Mynacol
2026-04-17 14:33:56 +02:00
committed by Mynacol
parent 7730a67fc1
commit 5898d99924
9 changed files with 250 additions and 176 deletions
@@ -0,0 +1,13 @@
Submodule build contains modified content
diff --git a/build/rust/allocator/lib.rs b/build/rust/allocator/lib.rs
index 4b834e322..1970d664e 100644
--- a/build/rust/allocator/lib.rs
+++ b/build/rust/allocator/lib.rs
@@ -87,7 +87,6 @@ mod both_allocators {
/// rustc-generated shims we must define this symbol, since we are opting in
/// to unstable functionality. See https://github.com/rust-lang/rust/issues/123015
#[rustc_std_internal_symbol]
- #[linkage = "weak"]
fn __rust_no_alloc_shim_is_unstable_v2() {}
#[cfg(not(RUST_ALLOCATOR_NIGHTLY_CAPABILITY))]
+168 -11
View File
@@ -1,12 +1,169 @@
# auto-generated file -- DO NOT EDIT!
{ fetchLibrustyV8 }:
fetchLibrustyV8 {
version = "147.0.0";
shas = {
x86_64-linux = "sha256-PXLRowkOBRVWeonQDTN6e4BQlSLK/kobCX7eE0Y1NLY=";
aarch64-linux = "sha256-6jaFVmmYYOZNZmk6UHUAGyibSBQn51Ie57hB7CIZBFI=";
x86_64-darwin = "sha256-yTrxJ5ABXg1r0myZqy4J3m/ivYdXnsgG089PrD5cMhY=";
aarch64-darwin = "sha256-HVr7hNzZk4qQTct2Px7DvSJAnyq1duJCqJawY475SR4=";
{
lib,
fetchFromGitHub,
fetchpatch,
rustPlatform,
rustc,
rustc-unwrapped,
rust-bindgen,
rust-analyzer,
rustfmt,
cargo,
clippy,
llvmPackages ? rustc.llvmPackages,
pkg-config,
stdenv,
glib,
glibc,
icu,
python3,
gn,
ninja,
xcbuild,
apple-sdk_15,
symlinkJoin,
deno,
}:
let
rustToolchain = symlinkJoin {
name = "rusty-v8-rust-toolchain";
paths = [
rustc
rustc-unwrapped
rust-bindgen
rust-analyzer
rustfmt
cargo
clippy
llvmPackages.libclang.lib
];
postBuild = ''
mkdir -p "$out/lib/rustlib/src/rust"
cp -r '${rustPlatform.rustcSrc}'/* "$out/lib/rustlib/src/rust/"
chmod u+w "$out/lib/rustlib/src/rust/library/"
ln -s '${rustPlatform.rustVendorSrc}' "$out/lib/rustlib/src/rust/library/vendor"
'';
};
}
clangBasePath = symlinkJoin {
name = "rusty-v8-llvm-toolchain";
paths = [
llvmPackages.clang-unwrapped.lib
llvmPackages.clang
llvmPackages.llvm
llvmPackages.lld
];
postBuild =
if stdenv.targetPlatform.isDarwin then
''
dir="$out/lib/clang/${lib.versions.major llvmPackages.clang.version}/lib/darwin/"
mkdir -p "$dir"
ln -s ${llvmPackages.compiler-rt}/lib/darwin/libclang_rt.osx* "$dir/libclang_rt.osx${stdenv.hostPlatform.extensions.staticLibrary}"
''
else
''
dir="$out/lib/clang/${lib.versions.major llvmPackages.clang.version}/lib/${stdenv.hostPlatform.config}/"
mkdir -p "$dir"
ln -s ${llvmPackages.compiler-rt}/lib/linux/libclang_rt.builtins-* "$dir/libclang_rt.builtins${stdenv.hostPlatform.extensions.staticLibrary}"
'';
};
in
rustPlatform.buildRustPackage (finalAttrs: {
pname = "rusty-v8";
version = "147.1.0";
src = fetchFromGitHub {
owner = "denoland";
repo = "rusty_v8";
tag = "v${finalAttrs.version}";
fetchSubmodules = true;
hash = "sha256-USCQtK5pJBpU1FTLMQ/bNwJXnVNkdX/EtCWqs2kVL50=";
};
patches = [
./librusty_v8_no_downloads.patch
(fetchpatch {
name = "chromium-146-revert-Update-fsanitizer=array-bounds-config.patch";
# https://chromium-review.googlesource.com/c/chromium/src/+/7539408
url = "https://chromium.googlesource.com/chromium/src/+/acb47d9a6b56c4889a2ed4216e9968cfc740086c^!?format=TEXT";
decode = "base64 -d";
revert = true;
includes = [ "build/config/compiler/BUILD.gn" ];
hash = "sha256-0yEK66IEyS8xABDHY4W8oIvl4Ga1JfL1wxQy8PhXyqI=";
})
./librusty_v8_revert_-fno-lifetime-dse.patch
]
++ lib.optionals stdenv.targetPlatform.isDarwin [
./librusty_v8-darwin-fix-__rust_no_alloc_shim_is_unstable_v2.patch
];
cargoHash = "sha256-FKwXdms9j+izRKsm5TKJ8Ct8lvBuG/tYXfNzVsbs8cM=";
nativeBuildInputs = [
llvmPackages.clang
python3
pkg-config
llvmPackages.lld
]
++ lib.optionals stdenv.targetPlatform.isLinux [
glibc
]
++ lib.optionals stdenv.targetPlatform.isDarwin [
xcbuild
];
buildInputs = [
glib
icu
]
++ lib.optionals stdenv.targetPlatform.isDarwin [
apple-sdk_15
];
env = {
V8_FROM_SOURCE = 1;
PYTHON = "python3";
NINJA = lib.getExe ninja;
GN = lib.getExe gn;
RUSTC_BOOTSTRAP = 1;
EXTRA_GN_ARGS = lib.concatStringsSep " " (
[
"use_sysroot=false" # prevent download of debian sysroot
"clang_version=\"${lib.versions.major llvmPackages.clang.version}\""
"rustc_version=\"${rustc.version}\""
"rust_sysroot_absolute=\"${rustToolchain}\""
"rust_bindgen_root=\"${rustToolchain}\""
"use_chromium_rust_toolchain=true"
# To accomodate our newer rustc compiler
"removed_rust_stdlib_libs=[\"adler\"]"
"added_rust_stdlib_libs=[\"adler2\"]"
]
++ lib.optional stdenv.targetPlatform.isDarwin "mac_deployment_target=\"${stdenv.targetPlatform.darwinMinVersion}\""
);
LIBCLANG_PATH = lib.makeLibraryPath [ llvmPackages.libclang ];
CLANG_BASE_PATH = clangBasePath;
};
buildFeatures = [ "simdutf" ];
checkFlags = [
# These tests probably fail due to a more recent rustc version (upstream: 1.89.0, here: 1.93.0)
"--skip=ui"
"--skip=scope"
];
installPhase = ''
runHook preInstall
cp target/*/release/gn_out/obj/librusty_v8${stdenv.hostPlatform.extensions.staticLibrary} $out
runHook postInstall
'';
meta = {
description = "Rust bindings for the V8 JavaScript engine";
homepage = "https://github.com/denoland/rusty_v8";
license = lib.licenses.mit;
maintainers = deno.meta.maintainers;
platforms = deno.meta.platforms;
};
})
@@ -0,0 +1,30 @@
diff --git a/build.rs b/build.rs
index 970e88bb..afb92e8a 100644
--- a/build.rs
+++ b/build.rs
@@ -251,7 +251,6 @@ fn build_v8(is_asan: bool) {
download_ninja_gn_binaries();
}
- download_rust_toolchain();
// `#[cfg(...)]` attributes don't work as expected from build.rs -- they refer to the configuration
// of the host system which the build.rs script will be running on. In short, `cfg!(target_<os/arch>)`
@@ -461,17 +460,6 @@ fn maybe_clone_repo(dest: &str, repo: &str) {
}
fn maybe_install_sysroot(arch: &str) {
- let sysroot_path = format!("build/linux/debian_sid_{arch}-sysroot");
- if !PathBuf::from(sysroot_path).is_dir() {
- assert!(
- Command::new(python())
- .arg("./build/linux/sysroot_scripts/install-sysroot.py")
- .arg(format!("--arch={arch}"))
- .status()
- .unwrap()
- .success()
- );
- }
}
fn download_ninja_gn_binaries() {
@@ -0,0 +1,19 @@
Submodule build contains modified content
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index ff8022f04..59699e1d4 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -625,13 +625,6 @@ config("compiler") {
]
}
- # The performance improvement does not seem worth the risk. See
- # https://crbug.com/484082200 for background and https://crrev.com/c/7593035
- # for discussion.
- if (!is_wasm) {
- cflags += [ "-fno-lifetime-dse" ]
- }
-
# TODO(hans): Remove this once Clang generates better optimized debug info
# by default. https://crbug.com/765793
cflags += [
+2 -4
View File
@@ -9,9 +9,7 @@
protobuf,
installShellFiles,
makeBinaryWrapper,
librusty_v8 ? callPackage ./librusty_v8.nix {
inherit (callPackage ./fetchers.nix { }) fetchLibrustyV8;
},
librusty_v8 ? callPackage ./librusty_v8.nix { },
libffi,
sqlite,
lld,
@@ -252,7 +250,7 @@ rustPlatform.buildRustPackage (finalAttrs: {
'';
passthru = {
updateScript = ./update/update.ts;
updateScript = ./update.sh;
tests = callPackage ./tests { };
inherit librusty_v8;
};
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p nix-update curl yq
old_version="$(nix-instantiate --raw --eval -A deno.version)"
nix-update deno
new_version="$(nix-instantiate --raw --eval -A deno.version)"
if [ "$old_version" = "$new_version" ]; then
echo "No deno update, nothing to do"
exit 0
fi
new_v8_version="$(curl -sL "https://raw.githubusercontent.com/denoland/deno/refs/tags/v$new_version/Cargo.lock" | \
tomlq -r ".package[] | select(.name == \"v8\") | .version")"
nix-update deno.librusty_v8 "--version=$new_v8_version"
-51
View File
@@ -1,51 +0,0 @@
interface GHRelease {
tag_name: string;
}
const decode = (buffer: Uint8Array) => new TextDecoder("utf-8").decode(buffer);
export const run = async (command: string, args: string[]) => {
const cmd = new Deno.Command(command, { args });
const { code, stdout, stderr } = await cmd.output();
if (code !== 0) {
const error = decode(stderr).trimEnd();
// Known error we can ignore
if (error.includes("'allow-unsafe-native-code-during-evaluation'")) {
// Extract the target sha256 out of the error
const target = " got: sha256:";
const match = error
.split("\n")
.find((l) => l.includes(target))
?.split(target)[1];
if (typeof match !== "undefined") {
return match;
}
}
throw new Error(error);
}
return decode(stdout).trimEnd();
};
// Exports
export const versionRegExp = /\d+\.\d+\.\d+/;
export const sha256RegExp = /[a-z0-9]{52}|sha256-.{44}/;
export const getExistingVersion = async (filePath: string) =>
read(filePath).then(
(s) => s.match(genValueRegExp("version", versionRegExp))?.shift() || "",
);
export const getLatestVersion = (owner: string, repo: string) =>
fetch(`https://api.github.com/repos/${owner}/${repo}/releases`)
.then((res) => res.json())
.then((res: GHRelease[]) => res[0].tag_name);
// The (?<=) and (?=) allow replace to only change inside
// Match the regex passed in or empty
export const genValueRegExp = (key: string, regex: RegExp) =>
new RegExp(`(?<=${key} = ")(${regex.source}|)(?=")`);
export const logger = (name: string) => (...a: any) =>
console.log(`[${name}]`, ...a);
export const read = Deno.readTextFile;
export const write = Deno.writeTextFile;
-67
View File
@@ -1,67 +0,0 @@
import {
genValueRegExp,
logger,
read,
run,
sha256RegExp,
versionRegExp,
write,
} from "./common.ts";
interface Replacer {
regex: RegExp;
value: string;
}
const log = logger("src");
const prefetchHash = (nixpkgs: string, version: string) =>
run("nurl", ["https://github.com/denoland/deno", version, "-H", "-n", nixpkgs, "-S"]);
const prefetchCargoHash = (nixpkgs: string) =>
run(
"nurl",
["-e", `(import ${nixpkgs} {}).deno.cargoDeps.overrideAttrs (_: { hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; })`]
);
const replace = (str: string, replacers: Replacer[]) =>
replacers.reduce(
(str, r) => str.replace(r.regex, r.value),
str,
);
const updateNix = (filePath: string, replacers: Replacer[]) =>
read(filePath).then((str) => write(filePath, replace(str, replacers)));
const genVerReplacer = (k: string, value: string): Replacer => (
{ regex: genValueRegExp(k, versionRegExp), value }
);
const genShaReplacer = (k: string, value: string): Replacer => (
{ regex: genValueRegExp(k, sha256RegExp), value }
);
export async function updateSrc(
filePath: string,
nixpkgs: string,
denoVersion: string,
) {
log("Starting src update");
const trimVersion = denoVersion.substring(1);
log("Fetching hash for:", trimVersion);
const sha256 = await prefetchHash(nixpkgs, denoVersion);
log("sha256 to update:", sha256);
await updateNix(
filePath,
[
genVerReplacer("version", trimVersion),
genShaReplacer("hash", sha256),
],
);
log("Fetching cargoHash for:", sha256);
const cargoHash = await prefetchCargoHash(nixpkgs);
log("cargoHash to update:", cargoHash);
await updateNix(
filePath,
[genShaReplacer("cargoHash", cargoHash)],
);
log("Finished src update");
}
-43
View File
@@ -1,43 +0,0 @@
#!/usr/bin/env nix-shell
/*
#!nix-shell -i "deno run --allow-net --allow-run --allow-read --allow-write" -p deno git nurl
*/
import { getExistingVersion, getLatestVersion, logger } from "./common.ts";
import { Architecture, updateLibrustyV8 } from "./librusty_v8.ts";
import { updateSrc } from "./src.ts";
const log = logger("update");
// TODO: Getting current file position to more-safely point to nixpkgs root
const nixpkgs = Deno.cwd();
// TODO: Read values from default.nix
const owner = "denoland";
const repo = "deno";
const denoDir = `${nixpkgs}/pkgs/by-name/de/${repo}`;
const src = `${denoDir}/package.nix`;
const librusty_v8 = `${denoDir}/librusty_v8.nix`;
const architectures: Architecture[] = [
{ nix: "x86_64-linux", rust: "x86_64-unknown-linux-gnu" },
{ nix: "aarch64-linux", rust: "aarch64-unknown-linux-gnu" },
{ nix: "x86_64-darwin", rust: "x86_64-apple-darwin" },
{ nix: "aarch64-darwin", rust: "aarch64-apple-darwin" },
];
log("Updating deno");
log("Getting latest deno version");
const version = await getLatestVersion(owner, repo);
const existingVersion = await getExistingVersion(src);
const trimVersion = version.substr(1); // Strip v from v0.0.0
log("Latest version: ", trimVersion);
log("Extracted version:", existingVersion);
if (trimVersion === existingVersion) {
log("Version already matches latest, skipping...");
Deno.exit(0);
}
const tasks = [
updateSrc(src, nixpkgs, version),
updateLibrustyV8(librusty_v8, owner, repo, version, architectures),
];
await Promise.all(tasks);
log("Updating deno complete");