ladybird
Build times (auto-updated)
- x86_64: 1h43m (2026-10-03 08:17 UTC, MAKEFLAGS=-j6)
- Path:
arch/adapted/ladybird(moved here 2026-10-01 fromlocal-install/once the-DENABLE_CI_BASELINE_CPU=ONbuild-flag override became a real local deviation from upstream’s PKGBUILD – seefeedback_local_adaptions_go_in_adaptedcross-session memory; entry added toarch/adapted/README)./data/INSTALL/ladybirdremains the actual build checkout either way –repo_build_staged.shnow rsyncs thisarch/adapted/ladybirdtree into it before each build instead of it being the standalone source of truth. - AUR package
ladybird(the stable/tagged one, notladybird-git). arch=(x86_64)only – no ARM support, so this never touches the ARM cluster. C++ browser with a vcpkg-managed dependency tree (harfbuzz, icu, skia, etc. all built from source via vcpkg on first build), which is why the build takes ~3.5h even withMAKEFLAGS=-j6– most of that time is vcpkg compiling its ~75 packages before Ladybird itself even starts building.- No existing
/data/INSTALL/ladybirdcheckout and not installed locally via yay, so this was a fresh clone + first-ever build, no-oldbackup needed. - 2026-09-29: first build,
ladybird20260901-2, built and published clean for x86_64 on the first attempt viarepo_release.sh. namcap flagged a pile of “unused shared library”/"implicitly satisfied dependency” warnings (Vulkan, glib2, libatomic, libstdc++, etc.) – cosmetic, from vcpkg-built binaries carrying broader RPATH/link info than namcap expects; upstream’s own PKGBUILD dependency list, left as-is.
2026-10-01: SIGILL on startup on another machine – -march=native baked in
User installed the published 20260901-2 package elsewhere and it SIGILLs
immediately on launch, crashing inside glibc’s _dl_init/ call_init – i.e. in
a global/static constructor, before main() even runs. Root cause confirmed by
reading Ladybird’s own upstream source at the pinned commit (e980ca4):
Meta/CMake/compile_options.cmake does, unconditionally unless
ENABLE_CI_BASELINE_CPU is set and the build isn’t cross-compiling:
elseif (NOT CMAKE_CROSSCOMPILING)
add_cxx_compile_options(-march=native)
endif()
The AUR PKGBUILD’s prepare() never passes ENABLE_CI_BASELINE_CPU, so the
build picked up -march=native – i.e. it was compiled for this exact build
host’s (euronuc, Intel i5-1135G7 Tiger Lake) CPU, which supports a very broad
instruction set including full AVX-512
(avx512f/dq/cd/bw/vl/vbmi2/vnni/bitalg/gfni/vaes/…). Any machine without that
same feature set SIGILLs on the first compiler-generated instruction that needs
it – consistent with it happening in a static initializer rather than any
particular user-triggered code path.
This is a known class of upstream issue, not specific to our build:
ladybird#10298
(“WebContent crashes with SIGILL on Haswell CPU”) and
ladybird#6522, where
a maintainer notes: “This started happening as of 49817a1 - when compiler
option -march=native was introduced by default” and confirms the documented
escape hatch: -DENABLE_CI_BASELINE_CPU=ON, which switches the top-level
Ladybird/Lagom sources to -march=x86-64-v3 on x86_64 (-march=armv8.2-a on
aarch64, -mcpu=apple-m1 on Apple Silicon) instead of -march=native – see
that file’s ENABLE_CI_BASELINE_CPU branch.
Caveats before trusting this as a full fix:
x86-64-v3still requires AVX2/BMI2/FMA (Haswell-class, ~2013+). If the machine that crashed predates that, this flag alone won’t be enough and an even more conservative-march=(x86-64-v2or plainx86-64) would be needed instead – need that machine’s CPU model/lscpuoutput to confirm which baseline is actually required.ENABLE_CI_BASELINE_CPUonly affectsadd_cxx_compile_optionscalls in Lagom’s owncompile_options.cmake, i.e. the top-level Ladybird/AK/LibJS/LibWeb sources. It does not propagate into the vcpkg-built dependencies (harfbuzz/icu/skia/etc.) –generate_vcpkg_toolchain_variables.cmakeonly forwardsCC/CXXto vcpkg builds, notCFLAGS/CXXFLAGS. Those ports use their own build systems’ defaults (Skia’s GN build in particular does its own runtime CPU dispatch viaSkOpts/SkCpu, checked at call time rather than static-init time, so it’s a less likely source of a static-initializer SIGILL – but not proven innocent without actually disassembling the crash site).
Fix applied 2026-10-01: added -DENABLE_CI_BASELINE_CPU=ON to the
cmake --preset Release line in prepare(), bumped pkgrel 2 -> 3
(packaging-only change, not pkgver – see feedback_pkgrel_vs_pkgver).
Confirmed with the user’s own lscpu output from two affected machines
(eurobuild6: AMD Ryzen 7 2700X Zen+; a Framework laptop: Intel i3-1315U Raptor
Lake) that both fully satisfy x86-64-v3 (avx2/bmi1/bmi2/fma/f16c/movbe/lzcnt
all present) and neither has any avx512* flag – so x86-64-v3 is both
necessary and sufficient for these two, no need to drop to x86-64-v2. Rebuilt
via repo_release.sh, published clean as 20260901-3 (1h44m – notably faster
than the first 3h23m build, despite the vcpkg dependency build visibly
restarting from detect_compiler again in the chroot, so the vcpkg binary cache
under Build/caches doesn’t survive a build, but Ladybird’s own source-asset
CDN cache apparently still saved real time on downloads).
Package also migrated from local-install/ to arch/adapted/ladybird at the
same time, since the CMake flag override is a real local deviation from
upstream’s PKGBUILD, not an as-is rebuild – see
feedback_local_adaptions_go_in_adapted. /data/INSTALL/ladybird remains the
build checkout; repo_build_staged.sh rsyncs arch/adapted/ladybird into it
before each future build now.
Still needs real-world confirmation – the build no longer bakes in AVX-512, but nobody has yet re-run the actual binary on the machine(s) that originally SIGILL’d to confirm it now launches.
2026-10-01: arch/adapted/ladybird got deleted by cleanup_all.sh, recovered
The move from local-install/ into arch/adapted/ladybird (described above)
was done as a plain file copy but never git added – adapted/ is directly
tracked (not a submodule), so an untracked directory there looks identical to
build cruft to cleanup_all.sh’s git clean -fd step. The very next
update_cycle.sh run (same day) swept the whole directory away
(adapted/README~ too, a real but untracked edit artifact). adapted/README’s
already-tracked ladybird line survived untouched (modified-tracked-file edits
are left alone, only untracked paths get removed).
Recovered from /data/INSTALL/ladybird (the actual build checkout, untouched by
this): PKGBUILD, hb-fc-whole-archive.patch, new-tab.patch,
gcc-build.patch copied back into arch/adapted/ladybird/, .SRCINFO
regenerated fresh (the one that had existed was stale at pkgrel=2, predating
the CI-baseline-CPU fix). Confirmed the restored PKGBUILD matches what’s
actually live (repo_arch_status.sh -> 20260901-3, matching pkgrel=3).
Still untracked as of this writing – same exposure exists until the user
runs git add adapted/ladybird adapted/README themselves (never done
automatically here, see [[feedback_never_git_commit_or_push]]). See
[[feedback_adapted_needs_git_add_immediately]] for the general lesson.
2026-10-01: runtime SSL CA cert error – known upstream Landlock-sandbox bug, not ours
User reported, on a machine running the rebuilt (non-SIGILL) 20260901-3
binary:
RequestServer: Request::handle_complete_state: Unable to map error (77):
"Problem with the SSL CA cert (path? access rights?)"
curl error 77 = CURLE_SSL_CACERT_BADFILE. Root-caused via upstream’s own issue
tracker, not a packaging bug:
ladybird#10241 –
RequestServer’s Landlock sandbox allows read-only access to /etc/ssl itself,
but on Arch (and Fedora, openSUSE, NixOS) the actual cert bundle under
/etc/ssl/certs/ca-certificates.crt is a symlink pointing outside that
allowed tree (e.g. into /etc/ca-certificates/) – the kernel resolves the
symlink before Landlock’s path check, so curl can’t read the real target once
sandboxed, even though the symlink itself is visible.
An alternate fix (read the CA bundle into memory before the sandbox applies,
via CURLOPT_CAINFO_BLOB instead of a path) was attempted in PR
#10256 but closed
unmerged (conflicts) 2026-09-28. The fix that actually landed is a different,
earlier PR: #12092, “Allow the real CA bundle through the Linux
sandbox”
(kalenikaliaksandr), merged 2026-09-18 – its real commit is
df15885
(“RequestServer: Allow the real CA bundle through the Linux sandbox”,
Services/RequestServer/SandboxLinux.cpp): resolves the cert-store paths
libcurl/OpenSSL actually use (cainfo/capath, OpenSSL’s default cert
file/dir, SSL_CERT_FILE/SSL_CERT_DIR) and allowlists those exact paths as
read-only Landlock rules, rather than just the /etc/ssl directory the symlinks
live in – directly fixes the symlink-resolution gap. This is after our old
pinned commit (e980ca4, 2026-09-01), so our build never had it.
User-confirmed runtime workaround in the issue thread (for anyone on an
un-rebased build): --certificate /etc/ssl/certs/ca-certificates.crt on the
command line, or --disable-sandbox (inconsistent results, not recommended).
Fix applied 2026-10-01: rebased the pinned commit forward to df15885
(2026-09-18) – deliberately not latest master (which moves daily) to keep the
jump scoped to “the known fix” rather than a month of unrelated churn. pkgver
20260901 -> 20260918 (new upstream snapshot date), pkgrel reset to 1 (not a
packaging-only change, see [[feedback_pkgrel_vs_pkgver]]). vcpkg pin left
unchanged (7f3781e, 2026-08-27) – didn’t appear relevant to this fix; revisit
if the build itself fails against it. The 3 patches
(hb-fc-whole-archive.patch/new-tab.patch/gcc-build.patch) target files
that may have moved in 17 days of upstream churn – watch for patch-apply
failures in prepare() on this build; if one fails, re-diff that patch against
the new commit rather than assuming it’s still correct unchanged.
Built+published 2026-10-02, confirmed clean: all 3 patches applied without
conflict against the new commit despite the 17-day gap, vcpkg build (Skia
etc.) + Ladybird’s own ~3664-object compile both completed with no errors,
published as 20260918-1 for x86_64 (2h31m). Same cosmetic namcap “unused
shared library”/"implicitly satisfied dependency” noise as the first build
(vcpkg RPATH breadth), nothing new. Still needs real-world confirmation that
the actual SSL/CA symptom is gone – nobody has re-run this exact binary against
the previously-failing site yet; revisit if the user reports back either way.
2026-10-02: SIGILL on a third machine (eurox) – below even x86-64-v2, not fixed by the existing ENABLE_CI_BASELINE_CPU flag
eurox’s lscpu (~/CPU.eurox): Intel Core2 Duo L7500 @ 1.60GHz (2008
Merom/Penryn mobile chip). Checked its flags against the microarchitecture
levels:
x86-64baseline (SSE2): satisfied.x86-64-v2(needs SSE4.1, SSE4.2, POPCNT, SSSE3, CMPXCHG16B): not satisfied – hasssse3/cx16/lahf_lmbut nosse4_1,sse4_2, orpopcnt.x86-64-v3(AVX2, BMI1/2, FMA, F16C, LZCNT, MOVBE): nowhere close – no AVX of any kind.
The existing fix (-DENABLE_CI_BASELINE_CPU=ON, see the 2026-10-01 entry above)
compiles Ladybird’s own sources at -march=x86-64-v3, which is why eurobuild6
(Ryzen 7 2700X) and the Framework laptop (i3-1315U) work – both clear v3.
eurox doesn’t even clear v2, so it hits the same class of SIGILL
(static-initializer instruction the CPU lacks), just earlier in the hierarchy.
This was anticipated as a caveat in the 2026-10-01 entry but not previously
confirmed against a real machine this old.
ENABLE_CI_BASELINE_CPU is a hardcoded on/off switch to x86-64-v3 in
upstream’s compile_options.cmake – no built-in knob for v2 or plain baseline.
Supporting eurox would need a patch to that file for a more conservative
-march= on this branch, and separately addressing vcpkg’s own Skia/ICU/etc.
builds (which don’t inherit ENABLE_CI_BASELINE_CPU at all – same gap noted
2026-10-01), before even considering whether a 2-core/1.6GHz 2008 chip can
usefully run a Chromium-class engine at all.
User decision 2026-10-02: document only, revisit later – not pursuing a fix now. If this comes up again, start from this entry rather than re-deriving the flag comparison.
2026-10-02: simdjson ABI bump on eurobuild6 forced a rebuild, which uncovered a second, unrelated break (Atomic::fetch_update deprecated in Rust 1.99)
eurobuild6 reported
Ladybird: error while loading shared libraries: libsimdjson.so.33: cannot open shared object file.
simdjson isn’t in this PKGBUILD’s depends() at all – it’s vendored via
vcpkg (-DBUILD_SHARED_LIBS=OFF only controls Lagom/Ladybird’s own libs, not
vcpkg ports) and installed alongside the binary by cmake --install, so the
running .so.33 is whatever vcpkg built it as, not a system package.
eurobuild6 had picked up simdjson 5.0.1-1 (soname bump) via its own
pacman -Syu while euronuc (the build host) was still on 4.6.11-1 – i.e.
euronuc’s chroot was simply behind, and a fresh vcpkg build on an updated
euronuc would naturally re-vendor the new simdjson and ship a matching .so.
Fix: ran pacman -Syu on euronuc first, confirmed simdjson 5.0.1-1 matched,
then rebuilt. This needed no PKGBUILD change at all – pure rebuild, pkgrel 1
-> 2.
That same pacman -Syu also bumped Arch’s rust/cargo package to a version
shipping Rust 1.99.0 (stable since 2026-09-28), which deprecated
Atomic::<T>::fetch_update in favor of try_update (identical
signature/semantics, try_update stable since 1.95.0). Ladybird’s own
Libraries/LibWeb/Rust crate (3 call sites: css/declaration_block.rs:365,
css/rule.rs:763, css/style_sheet.rs:396) still calls fetch_update, and
something in the build turns -D warnings into a hard error for that crate
(couldn’t pin down the exact injection point – not in any Cargo.toml [lints]
section or visible RUSTFLAGS in the source tree; likely the Corrosion
CMake/Rust bridge, fetched at configure time rather than vendored), so the
pkgrel=2 rebuild failed outright on libweb_rust with 3 deprecation errors.
This is unrelated to simdjson – just two system-package bumps landing in the
same pacman -Syu. Confirmed via GitHub’s commit-search API that upstream
Ladybird has not yet touched any of these 3 files since our pin (df15885,
2026-09-18) – the Rust 1.99 release (2026-09-28) is only 4 days old, so this is
a very fresh toolchain-wide break (multiple unrelated OSS projects hit the
identical fetch_update deprecation the same week per public issue trackers),
not something to expect upstream to have already absorbed.
Fix applied 2026-10-02: added 3 small patch files
(rust-fetch-update-declaration-block.patch, rust-fetch-update-rule.patch,
rust-fetch-update-style-sheet.patch), each a pure fetch_update ->
try_update rename at the one call site, applied in prepare() alongside the
existing 3 patches. pkgrel 2 -> 3 (packaging-only, see
[[feedback_pkgrel_vs_pkgver]]). Chose the patch-file route over an env-only
RUSTFLAGS=-A deprecated workaround (user’s explicit call) since the exact
-D warnings injection point was never located, so a flag-only fix had an
unclear chance of actually winning; the source rename is deterministic
regardless of where the lint promotion comes from. If a future rustc release
deprecates something else in this same vendored Rust crate, expect the same
failure mode – check this entry first before re-deriving the
Corrosion/RUSTFLAGS investigation.
Rebuilt clean after the patch: vcpkg (75 ports) + Ladybird’s own ~3664-object
compile both completed with no errors, published as 20260918-3 for x86_64 in
1h43m. Followed the /data/INSTALL/<pkg> -old rotation convention correctly
on the second attempt only – first attempt skipped it (caught and corrected
mid-session, see [[feedback_grep_memory_before_find]]): rotated the
then-current (good, published -1) /data/INSTALL/ladybird to -old before
the patched rebuild, discarded the intervening failed pkgrel=2 attempt
outright (never published, nothing worth keeping), and removed -old only after
the patched pkgrel=3 build published successfully. NOT actually confirmed
– a premature “confirmed” note was written here based on an ambiguous one-word
reply (“yay”), then retracted the same session once the user clarified
eurobuild6 still fails, now with both libsimdjson.so.33 (same as before)
and a libjpeg62 error too. Investigating below – don’t trust a bare
acknowledgement as confirmation of a specific technical claim again.
2026-10-02/03: real root cause found – package() never shipped vcpkg’s vendored shared libraries at all
Downloaded the live published .pkg.tar.zst and inspected it directly (the
20260918-3 rebuild above): it contains zero .so files – only the 6
executables. simdjson is not a real runtime dependency at all – it’s vendored
via vcpkg (pinned vcpkg commit 7f3781e, 2026-08-27), which builds its own
copy of simdjson from source, completely independent of any system simdjson
pacman package. That vendored copy happens to build with SOVERSION 33;
updating the host’s system simdjson package (the whole premise of the
20260918-2/-3 rebuilds above) therefore changes nothing for this.
Confirmed by running ldd directly on the extracted WebContent binary on
euronuc itself (the build host, not just eurobuild6):
libsimdjson.so.33 => not found
libjpeg.so.62 => not found
libskia.so => not found
libsimdutf.so.35 => not found
libmimalloc-secure.so.2 => not found
Every binary’s RUNPATH is $ORIGIN:$ORIGIN/../lib, i.e. they expect vcpkg’s
shared libs to ship alongside them – but package() only ever ran
cmake --install build, which installs Ladybird’s own targets, never vcpkg’s.
This has silently never fully worked on any machine – most of vcpkg’s ~75
built libs happen to coincidentally match real installed Arch packages by soname
(harfbuzz, icu, openssl, zlib, …), masking the gap;
simdjson/jpeg/skia/simdutf/mimalloc-secure are just the 5 that don’t
(Arch’s own libjpeg-turbo ships .so.8, not the classic .so.62 ABI vcpkg’s
jpeg port builds, for instance). Diffed against the live upstream AUR PKGBUILD
to confirm this isn’t something our adapted/ changes broke – upstream’s own
package() is identical in this respect; the gap is upstream’s, not ours.
vcpkg’s build puts everything at
${srcdir}/build/vcpkg_installed/x64-linux-dynamic/lib/. Considered copying all
of it straight into top-level usr/lib/ (matches vcpkg’s own $ORIGIN RPATH
convention) but that’s a pacman non-starter: most of those filenames
(libssl.so.3, libharfbuzz.so.0, libz.so.1, libicu*.so.78,
libpng16.so.16, libxml2.so.16, etc.) are already owned by real packages
already in depends() – pacman hard-refuses to install two packages claiming
the same path.
Fix applied (pkgrel 3 -> 4): copy the entire vcpkg lib dir into
usr/lib/ladybird/ instead (already solely owned by this package – the 6
executables already live there), then
patchelf --add-rpath '$ORIGIN/../lib/ladybird:$ORIGIN' on all 6 installed
binaries (usr/bin/Ladybird + the 5 helpers under usr/lib/ladybird/) so both
locations resolve correctly regardless of which RPATH entry fires. Added
patchelf to makedepends. User’s explicit call: bundle everything vcpkg
built, not just the 5 confirmed-missing ones – more robust against whatever the
next machine happens to already have installed, at the cost of some
duplication/staleness risk for bundled copies of otherwise-system-tracked libs
like openssl.
Rebuilt via a detached nohup ... & disown process (the harness’s normal
backgrounded-bash tracking killed the first attempt outright mid-build for no
discernible reason – see [[feedback_long_builds_need_detached_process]],
first hit with thunderbird-esr140-bin, now confirmed recurring). Published
clean as 20260918-4 for x86_64 (1h43m). Verified for real this time:
downloaded the published package fresh, fully extracted it (an earlier
selective-filename tar x of just libsimdjson.so.33 missed that it’s a
symlink to libsimdjson.so.33.0.0 and produced a false “still missing” alarm –
caught before reporting it) – 210 .so files now ship in usr/lib/ladybird/,
and ldd on both usr/bin/Ladybird and usr/lib/ladybird/WebContent shows
zero unresolved libraries. This is the real fix; the two earlier rebuilds
(-2/-3, chasing a system simdjson version bump) were addressing a symptom
that was never the actual cause. Still needs the user’s own real-world
confirmation that eurobuild6 launches cleanly now.