gioser

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1576Shell 205Rust 111Markdown 993774 Definiciones

⎇ ba1fb2d3a8ada748984dceeb0f58e6b3e67772b8 recipes/waterfox.toml TOML · 206 líneas · 12.2 KB Historia crudo

waterfox aparcada: no falló por los parches, le falta `browser/locales` en el clon fe940887b · Sergio ·

1# Waterfox 6.7.1.1 (Gecko 153.1.0) — el PRIMER FORK, y la prueba de la tesis del reúso.
2#
3# ══ QUÉ HEREDA, QUE ES CASI TODO ═══════════════════════════════════════════════════════════════
4# Waterfox es un fork de Gecko con árbol completo propio, así que consume EXACTAMENTE la misma
5# plataforma que Firefox —gtk3, nodejs, clang18, cbindgen, y las variantes `-shared` del corpus— y
6# los MISMOS seis muros ya resueltos. Ninguno se vuelve a pagar:
7#   1. sin `--enable-linker`     el sondeo de Mozilla no reconoce a zig (y con gcc ya no aplica).
8#   2. `compiler = "gcc"`        `flags.configure` EXIGE un `NEEDED …libc++`; zig enlaza libc++
9#                                estática para musl. Es negativa de upstream, no una perilla.
10#   3. `RUST_TARGET`             contrato del parche `fix-rust-target` de Alpine, no un bug.
11#   4. checksums vendorizados    cargo verifica cada fichero; los parches de musl los rompen.
12#   5. `strip_debug`             sin él el artefacto se va a varios GB.
13#   6. hermético                 `--disable-bootstrap` + `MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE`.
14# **Las diferencias reales con `recipes/firefox.toml` son TRES: la fuente, el branding y la versión.**
15# Si aparece una cuarta, conviene preguntarse si no debería estar en las dos.
16#
17# ══ LA BASE ES 153.1.0 Y LOS PARCHES SON DE 154 ════════════════════════════════════════════════
18# `config/milestone.txt` de este tag dice 153.1.0: una release POR DEBAJO de la de Firefox. Los once
19# parches de musl se reutilizan igual porque el código que tocan (LFS64, time64, prctl, el sandbox)
20# se mueve poco entre releases — pero es una apuesta explícita, no un hecho: si `patch` falla, falla
21# TEMPRANO, antes de compilar nada, y el arreglo es rebasar el parche que se queje.
22#
23# ══ ACÁ SÍ VA BRANDING OFICIAL, Y NO ES INCOHERENCIA ═══════════════════════════════════════════
24# `recipes/firefox.toml` va con branding SIN MARCA a propósito, porque poner el nombre y el logo de
25# Firefox sobre un binario parcheado entra en la política de marcas de Mozilla (la historia de
26# Iceweasel). Acá es al revés: `browser/branding/official` es **la marca del propio Waterfox**, que
27# BrowserWorks distribuye en su árbol para que se construya así. Usar su branding es lo que quieren;
28# lo que no se puede es usar el de Mozilla.
29
30# ══ APARCADA 2026-09-05 — Y NO POR LOS PARCHES ═════════════════════════════════════════════════
31# Primer intento en el worker: murió en CUATRO SEGUNDOS, no en las cuatro horas que temíamos, y por
32# algo que este comentario no preveía:
33#
34#     FATAL ERROR PROCESSING MOZBUILD FILE  /src/waterfox/browser/moz.build
35#     The underlying problem is we referenced a path that does not exist. That path is:
36#     /src/waterfox/browser/locales/moz.build
37#
38# O sea: los once parches de musl **sí agarraron** —la apuesta de reusar los de 154 sobre un árbol
39# 153.1.0 no es lo que falló— y lo que falta es un TROZO DEL ÁRBOL. `browser/locales` no está en el
40# clon. Sospechoso número uno: el `--filter=blob:none` + cómo BrowserWorks compone su repo (locales
41# como submódulo o generado), no la receta.
42#
43# Se aparca a propósito: la prioridad pasó a `firefox` con la cadena de optimización y a `atuq`
44# (SDD 26). Cuando se retome, el primer paso es mirar si `browser/locales` existe en el commit
45# pineado — un minuto de `git ls-tree`, no un build.
46name    = "waterfox"
47version = "6.7.1.1"
48license = "MPL-2.0"
49
50[source]
51# Por COMMIT y no por el `tarball_url` de GitHub: ése es un `/archive/`-style que la forja genera al
52# vuelo y cuyo sha256 cambia (ADR 0006). El tag `6.7.1.1` es LIGERO —una sola ref en `ls-remote`, sin
53# `^{}`— ⇒ este sha ES el commit. hammer clona con `--filter=blob:none`, así que un árbol Gecko
54# entero no trae la historia: sólo los blobs de este commit.
55repo   = "https://github.com/BrowserWorks/Waterfox.git"
56commit = "fd6662f3abfe6161e88b1b9cb4c70a963bdb345a"
57# Los once de musl del APKBUILD de Alpine (community/firefox). NO se traen los suyos de ppc64le,
58# loongarch ni Android: no aplican a x86_64 y cada parche que no hace falta es una forma más de que
59# un rebase falle sin motivo.
60patches = [
61  "firefox-patches/lfs64.patch",
62  "firefox-patches/time64.patch",
63  "firefox-patches/musl-no-linux-prctl.patch",
64  "firefox-patches/fix-fortify-system-wrappers.patch",
65  "firefox-patches/fix-rust-target.patch",
66  "firefox-patches/sandbox-sched_setscheduler.patch",
67  "firefox-patches/abseil-cpp.patch",
68  "firefox-patches/glean-stub.patch",
69  "firefox-patches/rust-lto-thin.patch",
70  "firefox-patches/wasip1.patch",
71  "firefox-patches/widevine.patch",
72]
73
74[build]
75# ══ `gcc` Y NO `zig-cc` — TRES MUROS DE UNA VEZ ════════════════════════════════════════════════
76# El resto del corpus va con zig-cc y esta receta es una EXCEPCIÓN consciente, del mismo tipo que la
77# que el repo ya mantiene para el kernel y cmake (ADR 0011). Se llegó acá por eliminación, no por
78# comodidad — con zig-cc el configure de Firefox murió tres veces seguidas:
79#
80#   1. «Could not use lld as linker» — zig se identifica como `zig ld 0.16.0` y el sondeo de Mozilla
81#      clasifica por esa cadena buscando «LLD»/«GNU ld»/«GNU gold».
82#   2. «Cannot find ar» — zig trae `ar` como SUBCOMANDO y `check_prog` busca un ejecutable.
83#   3. **«Firefox does not support linking statically with libstdc++»** — y éste no es un flag:
84#      `flags.configure:79` compila un C++ mínimo, lo pasa por `llvm-objdump --private-headers` y
85#      exige encontrar un `NEEDED …libc++`. zig enlaza libc++ ESTÁTICA para musl, así que ese NEEDED
86#      no existe nunca. No hay perilla que apagar; es una negativa de upstream.
87#
88# El gcc del lab (15.2.0, con `libstdc++` COMPARTIDA) satisface los tres: `NEEDED libstdc++.so.6`,
89# un `ar` de verdad y un linker que se anuncia como «GNU ld».
90#
91# ⚠ EL PRECIO, ESCRITO: **el lab NO entra en `hash_inputs`**, así que un Firefox construido con el
92# gcc del lab queda más expuesto a la deriva del rootfs que uno con zig-cc — dos labs con gcc
93# distinto pueden sellar bytes distintos sin que el store lo note. Es la misma deuda que ya cargan el
94# kernel y las otras recetas `compiler=gcc`, y la razón por la que conviene no ampliar esta lista sin
95# haber agotado antes el camino de zig.
96compiler = "gcc"
97target   = "x86_64-linux-musl"
98link     = "dynamic"
99flags    = []
100# ══ `strip_debug`: SIN ESTO EL ARTEFACTO SERÍA INMANEJABLE ═════════════════════════════════════
101# Medido en el `nodejs` que acaba de sellar sin strip: su binario pesa **984 MB, de los cuales
102# `.debug_info` son 497 MB y `.debug_line` otros 43** — más de la mitad del artefacto es información
103# de depuración. Firefox es varias veces V8, así que sin strip su artefacto entraría en varios GB, y
104# el store no es sólo disco: se sincroniza hub↔worker y se respalda.
105#
106# Es además el hallazgo del SDD 23: el 79% del contenido binario del store era `.debug_*`, y quitarlo
107# hace que artefactos que no reproducían PASEN a reproducir, porque lo que difería eran las rutas del
108# árbol de build embebidas en esas secciones.
109#
110# Entra en `hash_inputs` A PROPÓSITO (cambia el contenido del artefacto), y usa `zig objcopy`, que
111# siempre está en el sandbox ⇒ no agrega una dep de build.
112strip_debug = true
113
114[build.phases]
115configure = '''
116export MOZBUILD_STATE_PATH="$PWD/.mozbuild"
117export MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE=system
118export MOZ_NOSPAM=1
119# ── RUST_TARGET: lo EXIGE el parche de Alpine, no Firefox ─────────────────────────────────────
120# `fix-rust-target.patch` REEMPLAZA la autodetección del triple de Rust por un
121# `os.environ['RUST_TARGET']` pelado. Sin la variable, configure muere con
122# `KeyError: 'RUST_TARGET'` — que se lee como un bug de Firefox y es en realidad el contrato del
123# parche: el APKBUILD de Alpine lo exporta como `$CTARGET` y acá hay que hacer lo propio.
124# El valor NO se adivina: sale de `ls .dev-fs/alpine/usr/lib/rustlib/` en el lab, que es
125# `x86_64-alpine-linux-musl` — el rustc del sandbox es el de Alpine, no el del host (el del host es
126# `x86_64-unknown-linux-gnu` y usarlo produciría un cross-compile silencioso).
127export RUST_TARGET=x86_64-alpine-linux-musl
128
129# ── LOS PARCHES ROMPEN EL CHECKSUM DE LOS CRATES VENDORIZADOS ─────────────────────────────────
130# `error: the listed checksum of third_party/rust/zeitstempel/src/unix.rs has changed`. Los crates
131# de Rust vienen VENDORIZADOS en el tarball y cargo verifica el sha de CADA fichero contra
132# `.cargo-checksum.json`; en cuanto un parche de musl toca uno, el build muere. Cargo no ofrece
133# ninguna forma de recalcularlo, así que la salida —la misma del APKBUILD de Alpine— es vaciar la
134# lista de ficheros del manifiesto, dejando el checksum del paquete.
135#
136# Son los CINCO crates que tocan los parches, no uno: el error los va destapando de a uno y buscarlos
137# por prueba y error costaría cinco vueltas de configure.
138for c in audio_thread_priority cc zeitstempel wgpu-hal alsa; do
139  f="third_party/rust/$c/.cargo-checksum.json"
140  [ -f "$f" ] || { echo "FALTA $f — ¿upstream movió el crate?" >&2; exit 1; }
141  sed -i 's/\("files":{\)[^}]*/\1/' "$f"
142done
143cat > .mozconfig <<'MOZ'
144ac_add_options --prefix=/usr
145ac_add_options --enable-application=browser
146ac_add_options --enable-default-toolkit=cairo-gtk3-wayland
147ac_add_options --enable-release
148ac_add_options --enable-optimize
149ac_add_options --enable-hardening
150ac_add_options --enable-official-branding
151ac_add_options --with-libclang-path=/usr/lib
152ac_add_options --disable-bootstrap
153ac_add_options --disable-jemalloc
154ac_add_options --disable-crashreporter
155ac_add_options --disable-updater
156ac_add_options --disable-tests
157ac_add_options --disable-debug
158ac_add_options --disable-debug-symbols
159ac_add_options --disable-strip
160ac_add_options --disable-install-strip
161ac_add_options --disable-cargo-incremental
162ac_add_options --without-wasm-sandboxed-libraries
163ac_add_options --enable-alsa
164ac_add_options --enable-pulseaudio
165ac_add_options --enable-dbus
166ac_add_options --enable-ffmpeg
167mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir
168MOZ
169./mach configure
170'''
171# `mach build` respeta -jN; la cuenta es la misma que en nodejs.toml y por el mismo motivo: un número
172# fijo ataría el ArtifactHash a la RAM de quien escribió la receta.
173# ⚠ OJO con el techo: dentro del sandbox `/proc/meminfo` NO muestra la memoria del contenedor sino la
174# del host (medido en el LXC: 186 GiB en vez de 16), así que en un contenedor esta cuenta se degrada
175# a `nproc`. Es un tope, no una garantía.
176compile = '''
177export RUST_TARGET=x86_64-alpine-linux-musl   # ver la nota en la fase configure
178export MOZBUILD_STATE_PATH="$PWD/.mozbuild"
179export MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE=system
180export MOZ_NOSPAM=1
181gib=$(awk "/MemTotal/{printf \"%d\", \$2/1024/1024}" /proc/meminfo)
182j=$(( gib / 3 )); [ "$j" -lt 1 ] && j=1
183n=$(nproc); [ "$j" -gt "$n" ] && j=$n
184echo "mach build -j$j (MemTotal ${gib} GiB, nproc $n)"
185./mach build -j"$j"
186'''
187install = '''
188export RUST_TARGET=x86_64-alpine-linux-musl   # ver la nota en la fase configure
189export MOZBUILD_STATE_PATH="$PWD/.mozbuild"
190export MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE=system
191DESTDIR=/out ./mach install
192'''
193
194[deps]
195build = [
196  "python3", "pkgconf", "nasm", "make", "cmake",
197  # la plataforma Gecko, compartida con Waterfox y Zen
198  "nodejs", "cbindgen", "clang18", "llvm18",
199  "gtk3", "atk", "gdk-pixbuf", "pango", "cairo", "libepoxy",
200  "glib-shared", "pcre2-shared", "libffi-shared", "zlib-shared",
201  "harfbuzz", "fribidi", "freetype-shared", "fontconfig-shared", "pixman",
202  "libpng-shared", "libjpeg-turbo-shared",
203  "wayland", "wayland-protocols", "libxkbcommon", "mesa", "libdrm",
204  "dbus", "pipewire", "pulseaudio", "alsa-lib",
205  "libxml2-shared", "linux-headers",
206]