mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-10-28 08:36:17 +08:00
dev: On linux -dev_fast is on by default
Assuming the conditions are met for -dev_fast to work (linux, debug, x86-64 without sanitizers), the -dev_fast now defaults to true. download-v8 make target always downloads the .a (as before) and on linux x86-64 it also downloads the .so.
This commit is contained in:
3 files changed
+88
-70
No files matched your search
+5
-6
@@ -12,13 +12,12 @@ See [AGENTS.md](AGENTS.md) for the full set of test, formatting, and code conven
|
||||
### Skip the V8 source build
|
||||
|
||||
By default the build compiles V8 from source, which takes several minutes. Run
|
||||
`make download-v8` once to fetch the matching prebuilt archive from the
|
||||
`make download-v8` once to fetch the matching prebuilt libraries from the
|
||||
[`zig-v8-fork`](https://github.com/lightpanda-io/zig-v8-fork/releases) releases
|
||||
instead; later `make build` / `make test` pick it up automatically.
|
||||
|
||||
On Linux x86_64, `make download-v8-shared` additionally fetches the shared
|
||||
flavor (`libc_v8.so`) that `zig build -Ddev_fast=true` picks up automatically
|
||||
for much faster debug rebuilds.
|
||||
instead; later `make build` / `make test` pick them up automatically. On Linux
|
||||
x86_64 this includes the shared flavor (`libc_v8.so`) used by `-Ddev_fast`
|
||||
builds (defaults to true). Pass `-Ddev_fast=false` to get a static-V8 debug
|
||||
build instead.
|
||||
|
||||
## Before opening a PR
|
||||
|
||||
|
||||
@@ -6,9 +6,8 @@ BC := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
|
||||
# option test filter make test F="server"
|
||||
F=
|
||||
|
||||
# Extra flags forwarded to every `$(ZIG) build` invocation. Most commonly used
|
||||
# to point at a prebuilt V8 archive and skip the multi-minute source rebuild:
|
||||
# ZIGFLAGS=-Dprebuilt_v8_path=/path/to/libc_v8.a make test
|
||||
# Extra flags forwarded to every `$(ZIG) build` invocation, e.g.:
|
||||
# ZIGFLAGS=-Ddev_fast=false make test
|
||||
ZIGFLAGS ?=
|
||||
|
||||
# OS and ARCH
|
||||
@@ -36,7 +35,8 @@ endif
|
||||
# Prebuilt V8
|
||||
# -----------
|
||||
# Building V8 from source takes 10+ minutes. `make download-v8` fetches the
|
||||
# matching prebuilt archive from the zig-v8-fork releases instead. The versions
|
||||
# matching prebuilt archive from the zig-v8-fork releases instead; build.zig
|
||||
# discovers the cached files itself, so the target only fetches. The versions
|
||||
# are read from the install action so they can't drift from CI.
|
||||
#
|
||||
# The cache path is keyed on ZIG_V8_TAG as well as the archive name: a
|
||||
@@ -57,14 +57,6 @@ V8_CACHE := .lp-cache/prebuilt-v8/$(ZIG_V8_TAG)/$(V8_ARCHIVE)
|
||||
V8_SO_ASSET := libc_v8_$(V8_VERSION)_$(OS)_$(ARCH).so
|
||||
V8_SO_CACHE := .lp-cache/prebuilt-v8/$(ZIG_V8_TAG)/libc_v8.so
|
||||
|
||||
# If the prebuilt archive is in place and the caller hasn't set ZIGFLAGS, point
|
||||
# the build at it rather than building V8 from source.
|
||||
ifeq ($(strip $(ZIGFLAGS)),)
|
||||
ifneq ($(wildcard $(V8_CACHE)),)
|
||||
ZIGFLAGS := -Dprebuilt_v8_path=$(V8_CACHE)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
# Infos
|
||||
# -----
|
||||
@@ -85,9 +77,9 @@ help:
|
||||
|
||||
# $(ZIG) commands
|
||||
# ------------
|
||||
.PHONY: build build-v8-snapshot build-dev download-v8 download-v8-shared run run-release test bench data end2end clean
|
||||
.PHONY: build build-v8-snapshot build-dev download-v8 run run-release test bench data end2end clean
|
||||
|
||||
## Download the prebuilt V8 archive (skips the 10+ min source build)
|
||||
## Download the prebuilt V8 libraries (skips the 10+ min source build)
|
||||
download-v8:
|
||||
@mkdir -p $(dir $(V8_CACHE))
|
||||
@test -f $(V8_CACHE) || ( \
|
||||
@@ -96,16 +88,14 @@ download-v8:
|
||||
https://github.com/lightpanda-io/zig-v8-fork/releases/download/$(ZIG_V8_TAG)/$(V8_ARCHIVE) \
|
||||
|| (rm -f $(V8_CACHE); printf "\033[33mDownload ERROR\033[0m\n"; exit 1) )
|
||||
@printf "\033[33mV8 ready: %s\033[0m\n" "$(V8_CACHE)"
|
||||
|
||||
## Download the prebuilt shared V8 used by -Ddev_fast builds (Linux x86_64)
|
||||
download-v8-shared:
|
||||
@mkdir -p $(dir $(V8_SO_CACHE))
|
||||
ifeq ($(OS)_$(ARCH),linux_x86_64)
|
||||
@test -f $(V8_SO_CACHE) || ( \
|
||||
printf "\033[36mDownloading prebuilt shared V8 $(V8_VERSION) ($(ZIG_V8_TAG))...\033[0m\n"; \
|
||||
curl -fL --progress-bar -o $(V8_SO_CACHE) \
|
||||
https://github.com/lightpanda-io/zig-v8-fork/releases/download/$(ZIG_V8_TAG)/$(V8_SO_ASSET) \
|
||||
|| (rm -f $(V8_SO_CACHE); printf "\033[33mDownload ERROR\033[0m\n"; exit 1) )
|
||||
@printf "\033[33mShared V8 ready: %s\033[0m\n" "$(V8_SO_CACHE)"
|
||||
endif
|
||||
|
||||
## Build v8 snapshot
|
||||
build-v8-snapshot:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2023-2024 Lightpanda (Selecy SAS)
|
||||
// Copyright (C) 2023-2026 Lightpanda (Selecy SAS)
|
||||
//
|
||||
// Francis Bouvier <francis@lightpanda.io>
|
||||
// Pierre Tachoire <pierre@lightpanda.io>
|
||||
@@ -37,21 +37,19 @@ const Build = blk: {
|
||||
|
||||
pub fn build(b: *Build) !void {
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const requested_target = b.standardTargetOptions(.{});
|
||||
|
||||
// The three settings below only work as a set, so they get one knob rather
|
||||
// than three defaults: the self-hosted backend needs the shared V8 (it
|
||||
// cannot apply the CREL relocations in the archive) and needs zig's own CRT
|
||||
// (a system crt1.o with SFrame unwind data has relocations its linker does
|
||||
// not handle). Debug-only, opt-in, and a good deal faster to rebuild.
|
||||
const dev_fast = b.option(bool, "dev_fast", "Linux debug builds: shared V8 + self-hosted backend. Implies -Dshared_v8, -Duse_llvm=false and a bundled-CRT target") orelse false;
|
||||
const enable_tsan = b.option(bool, "tsan", "Enable Thread Sanitizer") orelse false;
|
||||
const enable_asan = b.option(bool, "asan", "Enable Address Sanitizer") orelse false;
|
||||
const enable_csan = b.option(std.zig.SanitizeC, "csan", "Enable C Sanitizers");
|
||||
|
||||
const target = if (dev_fast) b.resolveTargetQuery(.{
|
||||
.cpu_arch = .x86_64,
|
||||
.os_tag = .linux,
|
||||
.abi = .gnu,
|
||||
// https://codeberg.org/ziglang/zig/issues/31272
|
||||
.glibc_version = .{ .major = 2, .minor = 43, .patch = 0 },
|
||||
}) else b.standardTargetOptions(.{});
|
||||
const prebuilt_v8_path_option = b.option([]const u8, "prebuilt_v8_path", "Path to a prebuilt libc_v8.a or libc_v8.so");
|
||||
|
||||
const dev_fast = b.option(bool, "dev_fast", "Linux debug builds: shared V8 + self-hosted backend. Implies -Dshared_v8, -Duse_llvm=false and a bundled-CRT target") orelse
|
||||
(builtin.os.tag == .linux and builtin.cpu.arch == .x86_64 and
|
||||
optimize == .Debug and requested_target.query.isNative() and
|
||||
!enable_tsan and !enable_asan and
|
||||
(prebuilt_v8_path_option == null or std.mem.endsWith(u8, prebuilt_v8_path_option.?, ".so")));
|
||||
|
||||
if (dev_fast) {
|
||||
if (builtin.os.tag != .linux) {
|
||||
@@ -62,16 +60,27 @@ pub fn build(b: *Build) !void {
|
||||
std.debug.print("-Ddev_fast is Debug-only (optimize is {s})\n", .{@tagName(optimize)});
|
||||
return error.DevFastRequiresDebug;
|
||||
}
|
||||
if (!requested_target.query.isNative()) {
|
||||
std.debug.print("-Ddev_fast builds for the host; drop -Dtarget/-Dcpu\n", .{});
|
||||
return error.DevFastRequiresNativeTarget;
|
||||
}
|
||||
}
|
||||
|
||||
// dev_fast links V8 shared, so it defaults to the libc_v8.so that
|
||||
// `make download-v8-shared` caches (when present) rather than a
|
||||
// multi-minute from-source build.
|
||||
const prebuilt_v8_path = b.option([]const u8, "prebuilt_v8_path", "Path to a prebuilt libc_v8.a or libc_v8.so") orelse
|
||||
if (dev_fast) findSharedV8Cache(b) else null;
|
||||
const target = if (dev_fast) b.resolveTargetQuery(.{
|
||||
.cpu_arch = .x86_64,
|
||||
.os_tag = .linux,
|
||||
.abi = .gnu,
|
||||
// https://codeberg.org/ziglang/zig/issues/31272
|
||||
.glibc_version = .{ .major = 2, .minor = 43, .patch = 0 },
|
||||
}) else requested_target;
|
||||
|
||||
// Without an explicit -Dprebuilt_v8_path, pick up whatever `make
|
||||
// download-v8` cached rather than building V8 from source.
|
||||
const prebuilt_v8_path = prebuilt_v8_path_option orelse if (enable_tsan or enable_asan) null else findPrebuiltV8(b, target, dev_fast);
|
||||
const snapshot_path = b.option([]const u8, "snapshot_path", "Path to v8 snapshot");
|
||||
const wpt_extensions = b.option(bool, "wpt_extensions", "Extend WebAPI with WPT driver behavior") orelse false;
|
||||
const shared_v8 = b.option(bool, "shared_v8", "Link V8 as a shared library") orelse dev_fast;
|
||||
const shared_v8 = b.option(bool, "shared_v8", "Link V8 as a shared library") orelse
|
||||
(dev_fast or (prebuilt_v8_path != null and std.mem.endsWith(u8, prebuilt_v8_path.?, ".so")));
|
||||
const use_llvm = b.option(bool, "use_llvm", "Use the LLVM backend") orelse !dev_fast;
|
||||
|
||||
const version = resolveVersion(b);
|
||||
@@ -86,10 +95,6 @@ pub fn build(b: *Build) !void {
|
||||
opts.addOption(?[]const u8, "snapshot_path", snapshot_path);
|
||||
opts.addOption(bool, "wpt_extensions", wpt_extensions);
|
||||
|
||||
const enable_tsan = b.option(bool, "tsan", "Enable Thread Sanitizer") orelse false;
|
||||
const enable_asan = b.option(bool, "asan", "Enable Address Sanitizer") orelse false;
|
||||
const enable_csan = b.option(std.zig.SanitizeC, "csan", "Enable C Sanitizers");
|
||||
|
||||
const lightpanda_module = blk: {
|
||||
const mod = b.addModule("lightpanda", .{
|
||||
.root_source_file = b.path("src/lightpanda.zig"),
|
||||
@@ -251,10 +256,10 @@ pub fn build(b: *Build) !void {
|
||||
}
|
||||
}
|
||||
|
||||
/// Looks for the shared V8 that `make download-v8-shared` caches. The cache
|
||||
/// Looks for the prebuilt V8 that `make download-v8` caches. The cache
|
||||
/// path is keyed on the zig-v8 release tag, read from the install action so
|
||||
/// it cannot drift from CI (the Makefile reads the same source of truth).
|
||||
fn findSharedV8Cache(b: *Build) ?[]const u8 {
|
||||
fn findPrebuiltV8(b: *Build, target: Build.ResolvedTarget, dev_fast: bool) ?[]const u8 {
|
||||
const io = b.graph.io;
|
||||
const action = std.Io.Dir.cwd().readFileAlloc(
|
||||
io,
|
||||
@@ -263,32 +268,56 @@ fn findSharedV8Cache(b: *Build) ?[]const u8 {
|
||||
.limited(64 * 1024),
|
||||
) catch return null;
|
||||
|
||||
const tag = blk: {
|
||||
var in_zig_v8 = false;
|
||||
var lines = std.mem.splitScalar(u8, action, '\n');
|
||||
while (lines.next()) |line| {
|
||||
if (std.mem.startsWith(u8, line, " ") and !std.mem.startsWith(u8, line, " ")) {
|
||||
in_zig_v8 = std.mem.eql(u8, std.mem.trimEnd(u8, line, " \r"), " zig-v8:");
|
||||
continue;
|
||||
}
|
||||
if (!in_zig_v8) continue;
|
||||
const trimmed = std.mem.trim(u8, line, " \r");
|
||||
if (std.mem.startsWith(u8, trimmed, "default:")) {
|
||||
var it = std.mem.splitScalar(u8, trimmed, '\'');
|
||||
_ = it.next();
|
||||
break :blk it.next() orelse return null;
|
||||
}
|
||||
const tag = actionDefault(action, "zig-v8:") orelse return null;
|
||||
if (tag.len == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// The .so must keep the name the exe's DT_NEEDED records; the archive
|
||||
// name encodes V8 version, os and arch.
|
||||
const path = if (dev_fast)
|
||||
b.fmt("{s}/prebuilt-v8/{s}/libc_v8.so", .{ b.pathFromRoot(".lp-cache"), tag })
|
||||
else blk: {
|
||||
const version = actionDefault(action, "v8:") orelse return null;
|
||||
break :blk b.fmt("{s}/prebuilt-v8/{s}/libc_v8_{s}_{s}_{s}.a", .{
|
||||
b.pathFromRoot(".lp-cache"),
|
||||
tag,
|
||||
version,
|
||||
@tagName(target.result.os.tag),
|
||||
@tagName(target.result.cpu.arch),
|
||||
});
|
||||
};
|
||||
std.Io.Dir.cwd().access(io, path, .{}) catch {
|
||||
if (dev_fast) {
|
||||
std.debug.print("No cached libc_v8.so; building V8 from source. `make download-v8` skips this.\n", .{});
|
||||
}
|
||||
return null;
|
||||
};
|
||||
if (tag.len == 0) return null;
|
||||
|
||||
const path = b.fmt("{s}/prebuilt-v8/{s}/libc_v8.so", .{ b.pathFromRoot(".lp-cache"), tag });
|
||||
std.Io.Dir.cwd().access(io, path, .{}) catch return null;
|
||||
std.debug.print("Using prebuilt shared V8: {s}\n", .{path});
|
||||
std.debug.print("Using prebuilt V8: {s}\n", .{path});
|
||||
return path;
|
||||
}
|
||||
|
||||
// Returns the quoted `default:` value of a top-level `key` in the install
|
||||
// action's yaml.
|
||||
fn actionDefault(action: []const u8, key: []const u8) ?[]const u8 {
|
||||
var in_key = false;
|
||||
var lines = std.mem.splitScalar(u8, action, '\n');
|
||||
while (lines.next()) |line| {
|
||||
if (std.mem.startsWith(u8, line, " ") and !std.mem.startsWith(u8, line, " ")) {
|
||||
in_key = std.mem.eql(u8, std.mem.trimEnd(u8, line[2..], " \r"), key);
|
||||
continue;
|
||||
}
|
||||
if (!in_key) continue;
|
||||
const trimmed = std.mem.trim(u8, line, " \r");
|
||||
if (std.mem.startsWith(u8, trimmed, "default:")) {
|
||||
var it = std.mem.splitScalar(u8, trimmed, '\'');
|
||||
_ = it.next();
|
||||
return it.next();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
fn linkV8(
|
||||
b: *Build,
|
||||
mod: *Build.Module,
|
||||
|
||||
Reference in new issue
Block a user