Real flatpak-builder run (via distrobox) surfaced two real, non-obvious bugs and one dead end, all now fixed/documented from empirical evidence rather than guesswork: - org.kde.Platform//6.10 can never pair with org.freedesktop.Sdk.Extension.rust-stable: sdk-extensions always branch-match runtime-version, and rust-stable is only published under freedesktop-sdk's own branch numbers, never KDE's. Since Ladybird builds its own Qt 6.10.0 via vcpkg regardless of the runtime, there was no reason to use the KDE runtime in the first place. Switched to org.freedesktop.Platform/Sdk//26.08, which also happens to ship rust-stable 1.98.0, an exact match for rust-toolchain.toml. - Ladybird's Meta/CMake/environment.cmake force-overrides CMAKE_TOOLCHAIN_FILE from the VCPKG_ROOT env var whenever LADYBIRD_VCPKG_TYPE is set, silently discarding any -D value passed on the command line. Set VCPKG_ROOT via build-options.env instead. - flatpak-builder needs --disable-rofiles-fuse inside a distrobox (no FUSE available in the container). With these fixes, task build now gets all the way through source fetching (all 347 cargo sources verified), SDK/extension resolution, and CMake configure, failing exactly where expected: vcpkg's own bootstrap script has no network access to download its tool binary. README.md's vcpkg section is rewritten around this precise, verified failure point instead of the earlier general "vcpkg needs network" description. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|---|---|---|
| .dagger | ||
| sources | ||
| tools | ||
| .gitignore | ||
| dagger.json | ||
| flake.nix | ||
| flathub.json | ||
| manifest-template.json | ||
| org.ladybird.Ladybird.json | ||
| README.md | ||
| Taskfile.yml | ||
Ladybird Flatpak (work in progress)
Flatpak packaging for Ladybird, modeled
structurally on Flathub's org.kde.kget manifest. This does not build yet. A real
task build run gets all the way through fetching sources (including all 173 vendored
Rust crates), SDK/toolchain resolution, and CMake configure, and fails cleanly exactly
where expected: vcpkg has no network access in the build sandbox. See "What's unresolved"
below.
Facts this manifest relies on (verified 2026-09-29)
- App ID
org.ladybird.Ladybirdis upstream's own, not invented here: Ladybird already ships a desktop file, AppStream metainfo, D-Bus service file and scalable icon underMeta/CMake/freedesktop/, installed via CMake's-DENABLE_INSTALL_FREEDESKTOP_FILES=ON(seeUI/cmake/InstallRules.cmake). We don't need to author any of those ourselves. - Ladybird has no tagged releases — it's rolling
masteronly. The manifest pins thegitsource to the commit that wasmasterHEAD on 2026-09-29:618693e7173413d0a6e23d6449164170b1c7dae8. Re-pin periodically (Flathub requires a pinned commit, not a tracked branch). - Build system: CMake ≥ 3.30 + Ninja, via the
DistributionCMake preset (LADYBIRD_VCPKG_TYPE=distribution, static libs, Release build type) — seeMeta/CMake/presets/CMakeBasePresets.json. - Dependencies come from vcpkg (
vcpkg.json/vcpkg-configuration.json), pinned tobuiltin-baselinecommit7f3781e19cc7d4e4882a4caec01668c6f7b5c163in the vcpkg repo. That's ~40 C++ libraries (Skia, ICU, FFmpeg, curl, libwebp, libavif, harfbuzz, freetype, sqlite3, simdjson, and notably Qt 6.10.0 itself, built from source via vcpkg rather than taken from the runtime). - Rust toolchain:
rust-toolchain.tomlpins stable channel 1.98.0 (not nightly) withrustfmt/clippy. Rust deps are locked inCargo.lockat the repo root. - Runtime:
org.freedesktop.Platform/org.freedesktop.Sdk26.08, not KDE's runtime despite this being a Qt app and KGet (the template) being a KDE one. Two reasons, confirmed empirically, not just in theory:- Ladybird builds its own Qt 6.10.0 from source via vcpkg regardless of what the
runtime provides (see
vcpkg.jsonoverrides above) — the runtime's Qt was never going to be used. sdk-extensionsare always branched to match the app's ownruntime-version, with no per-extension override.org.freedesktop.Sdk.Extension.rust-stableis only published under freedesktop-sdk's own branch numbers (19.08...26.08), never under KDE's version numbers (6.10 etc), soorg.kde.Platform//6.10+ that extension can never resolve — confirmed by trying it (error: Requested extension org.freedesktop.Sdk.Extension.rust-stable/x86_64/6.10 not installed). freedesktop-sdk branch26.08ships rust-stable 1.98.0, an exact match forrust-toolchain.toml's pin, which is also why that branch and not another.
- Ladybird builds its own Qt 6.10.0 from source via vcpkg regardless of what the
runtime provides (see
How the manifest is built
org.ladybird.Ladybird.json is a generated file — don't hand-edit it. Edit
manifest-template.json (config-opts, finish-args, etc.) and the fragments under
sources/, then run:
task generate-manifest
which splices each "@@SENTINEL@@" string in the template's module sources arrays
with the matching sources/<name>.json array (see tools/generate-manifest.py). A
sentinel with no fragment file yet is dropped with a warning — that's how you can tell
from a fresh assemble which vendoring steps are still outstanding.
What's unresolved (the actual hard part)
Flathub's build sandbox has no network access during flatpak-builder runs (except
in a simple-buildsystem module explicitly wrapping known lockfile-based generators).
Ladybird's build wants network access twice:
-
Rust deps via Cargo — DONE.
rust-toolchain.tomlpins stable channel 1.98.0 (not nightly), deps locked inCargo.lockat the repo root. Vendored usingflatpak-cargo-generator.py(vendored copy attools/flatpak-cargo-generator.py, MIT-licensed, fromflatpak/flatpak-builder-tools), run against the pinned commit'sCargo.lockviatask generate-cargo-sources. Output lives atsources/cargo-sources.json(347 sources: 173 crate archives + 174 inline.cargo-checksum.json/vendor-config writes) and is already spliced into the manifest.CARGO_HOMEis set to/run/build/Ladybird/cargoinbuild-options.envto match where those sources land inside theLadybirdmodule's build directory and thecargo/vendorlayout the generator assumes. Not yet verified against an actual build (noflatpak-builderrun has happened), but the source-generation half is solid, known-good tooling. -
vcpkg fetching things — IN PROGRESS, now precisely located. There is no existing
flatpak-node-generator/flatpak-cargo-generator-equivalent for vcpkg (checkedflatpak/flatpak-builder-tools— nothing there as of this writing).A real
task buildrun (freedesktop runtime, see above) gets through source fetching, SDK/extension resolution, and CMake configure, and fails here, confirmed by reading/run/build/Ladybird/vcpkg-bootstrap.logfrom the failed build dir:Downloading vcpkg-glibc... curl: (6) Could not resolve host: github.comSo the very first network hit isn't even a port — it's vcpkg's own bootstrap script (
vcpkg/bootstrap-vcpkg.sh, invoked automatically byvcpkg.cmakethe first timefind_package/vcpkg_installruns) trying to download vcpkg's own prebuilt tool binary from a GitHub release. That needs vendoring the same way a port does, and comes before any of the ~40 port downloads in the dependency-download order.Getting to this point required two fixes, both non-obvious and worth keeping straight:
- Don't set
-DCMAKE_TOOLCHAIN_FILEdirectly.Meta/CMake/environment.cmakeunconditionally doesset(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "" FORCE)wheneverLADYBIRD_VCPKG_TYPEis set (which we need set, todistribution) —FORCEmeans any value passed via-Don the command line is silently discarded. Set theVCPKG_ROOTenvironment variable instead (build-options.env.VCPKG_ROOT, set to/run/build/Ladybird/vcpkg, matching the vcpkg git source'sdest) and let Ladybird compute the toolchain-file path itself. flatpak-builderneeds--disable-rofiles-fuseinside a distrobox — the rofiles-fuse overlay it normally uses needs a FUSE mount, which isn't available inside the container (fusermount3: ... Permission denied). This is now baked intotask build.
Next concrete step: vendor the vcpkg bootstrap binary the same way as a normal port (pre-place it wherever
bootstrap-vcpkg.shlooks before it curls, as a flatpakfilesource), confirm the build gets past bootstrap, then handle actual port downloads:- vcpkg caches every port's downloaded archive under
$VCPKG_ROOT/downloads/(orVCPKG_DOWNLOADSif set) with predictable filenames, and vcpkg only re-downloads a file if it's missing — it doesn't require network if the file is already there. - Write a generator script (
tools/generate-vcpkg-sources.py, doesn't exist yet) that walks that downloads directory, and for each file emits a flatpak"type": "file"source withdest: vcpkg/downloadsand its sha512 (vcpkg's own hash, reusable directly), writingsources/vcpkg-sources.json— same shape as the cargo fragment, so it'll be picked up by the existing@@VCPKG_SOURCES@@sentinel inmanifest-template.jsonautomatically once it exists. - Note
Meta/CMake/environment.cmakealso pointsX_VCPKG_ASSET_SOURCESathttps://vcpkg-cache.app.ladybird.org/...— Ladybird runs its own vcpkg asset mirror. Doesn't remove the offline-vendoring need (it's still a network fetch), but may be a friendlier/more stable single source than each port's original upstream URL if the generator ends up needing to re-fetch anything by hand. - Open question: whether to let vcpkg build its own Qt 6.10.0 from source (correctness,
but a very large extra build — Qt from source is itself a multi-GB, multi-hour
build) or add an overlay port that redirects Qt to the runtime's Qt6 instead. Needs
a decision before vendoring the full port set, since it changes the download set
significantly. (
org.freedesktop.Platformdoesn't ship Qt at all, unlike KDE's runtime, so "redirect to the runtime's Qt" is no longer on the table now that we're off the KDE runtime — vcpkg building its own Qt is the only remaining option.)
- Don't set
org.ladybird.Ladybird.json still carries an x-comment on the Ladybird module
documenting this gap (ignored by flatpak-builder, same convention as KGet's
x-checker-data), so it's visible in the manifest itself, not just here.
Also not yet done
- Haven't confirmed whether
-DENABLE_QT=ONis the correct/only CMake variable gating the Qt UI (vs. a headless/Android build) — verify againstUI/CMakeLists.txtandvcpkg.json'sVCPKG_MANIFEST_FEATUREShandling once the build gets far enough to actually reach that code path (it doesn't yet — see vcpkg bootstrap blocker above). finish-argsincludes--share=networkbecause Ladybird is a browser and legitimately needs runtime network access (unrelated to the build-time network problem above) — this is normal for other browsers on Flathub, not a placeholder.
Working on this (Taskfile)
Local dev tooling is a Fedora distrobox, not Nix.
flatpak-builder has no Homebrew formula (it's too tied to system ostree/bubblewrap/
polkit integration) and its own Docker/OCI images aren't a good fit for a Nix devShell
either, so task install-tools creates a flatpak-builder distrobox (Fedora, has the
package) and installs it there. The distrobox shares this user's home directory, so
~/.local/share/flatpak is the same install the host flatpak command reads — builds
done inside the box are runnable directly from outside it (task run doesn't need the
box at all). This also avoids a real trap: flatpak install org.flatpak.Builder installs
a Flatpak app, not a flatpak-builder CLI binary on $PATH — it doesn't actually give
you a working flatpak-builder command, which is why an earlier version of this workflow
broke with "flatpak-builder": executable file not found in $PATH.
uv (used to run tools/flatpak-cargo-generator.py) and go-task itself come from
Homebrew directly — no container needed for those.
flake.nix and .dagger/ (see below) are a separate, not-yet-working path meant for
CI, not today's local workflow — don't reach for nix develop here.
Requires go-task and distrobox. All
tasks: task --list.
task install-tools— creates theflatpak-builderdistrobox, installsflatpak-builder/flatpak/gitin it viadnf, and installs the Flatpak runtimes this manifest needs (freedesktop-sdk 26.08 platform/SDK, rust-stable SDK extension) via the hostflatpak.task generate-cargo-sources— downloadsCargo.lockfrom the pinned Ladybird commit and regeneratessources/cargo-sources.json.task generate-manifest— reassemblesorg.ladybird.Ladybird.jsonfrommanifest-template.json+sources/*.json.task update-sources— the above two, in order.task build— runsflatpak-builder --disable-rofiles-fuseinside the distrobox. Currently fails once vcpkg's bootstrap script tries to download its own tool binary (see above).task run—flatpak run org.ladybird.Ladybird(host, no distrobox involved).task clean— removes local build artifacts.
Dagger + Nix (for CI, not yet working)
dagger.json and .dagger/main.go are a hand-written, unrun Dagger Go module — the
local Dagger engine (a podman container on this dev machine) got stuck in an unkillable
kernel D-state and no working engine was available to run dagger init/dagger develop
against, which is what normally generates go.mod/go.sum/the internal/dagger SDK
bindings this file imports. It won't compile as-is. The plan is to finish wiring it up in
GitHub Actions (or once Dagger Cloud's hosted "Cloud Engines" are set up — dagger login
plus dagger --cloud — as a way to sidestep needing any local container engine at all),
rather than chase the local engine issue further right now.
main.go's nixContainer() helper is intended to run flake.nix's devShell (which does
include flatpak-builder, unlike the distrobox-vs-Nix split above — inside a fresh
container, Nix's own sandboxing/build-user setup isn't fighting an immutable host OS the
way it would locally) inside a Dagger pipeline, so flake.nix stays relevant once this is
running in CI even though it's unused for local dev today.
Next steps, in order
- Vendor vcpkg's own bootstrap tool binary (
vcpkg-glibc) sobootstrap-vcpkg.shfinds it locally instead of curling GitHub — figure out exactly where it looks (probably$VCPKG_ROOT/downloads/, matching where port downloads land) and add it as a flatpakfilesource. - Re-run
task build; confirm it gets past bootstrap and starts actually resolving ports. - Do one network-enabled local vcpkg fetch (now that bootstrap works), write
tools/generate-vcpkg-sources.pyagainst$VCPKG_ROOT/downloads/, producesources/vcpkg-sources.json. - Re-run
task buildagain; expect further failed iterations (Rust vendor-dir mismatches, missing headers, the actual multi-hour Qt-from-source build, etc.) before it produces a workingladybirdbinary. - Once it builds and runs, tighten
finish-args/cleanup, add screenshots to the AppStream metainfo if upstream's is missing them, and go through Flathub's submission checklist.