# Firefox 154.0 — el navegador. Tercera app de usuario final, y **la cabeza de la familia Gecko**: # Waterfox y Zen son forks suyos y reutilizan todo lo de abajo. # # ══ POR QUÉ 154 Y NO 155, QUE ES LA QUE SIGUE ZEN ══════════════════════════════════════════════ # Zen declara `"version": "155.0.1"` en su `surfer.json` y Waterfox 6.7 también va por el canal # release, así que 155 parecía la base obvia. Se eligió **154** por una razón concreta: **los parches # de musl de Alpine son para 154.0**, y son once. Ese es el trabajo de portabilidad que un import de # nix pierde y que no conviene rehacer a mano — sin ellos Firefox no compila contra musl. # # Un Firefox que compila con el set probado vale más que uno con el número correcto que no compila. # Y como Firefox se mueve cada cuatro semanas, la paridad exacta con Zen es una cinta de correr: lo # que de verdad se reutiliza entre los tres es LA PLATAFORMA (gtk3/nodejs/clang/cbindgen, todo ya en # el corpus) y ESTE SET DE PARCHES. Subir a 155 después es un rebase, no un port. # # ══ TODO BUNDLEADO SALVO GTK3 ══════════════════════════════════════════════════════════════════ # Alpine usa `--with-system-{icu,nspr,nss,av1,libvpx,webp,libevent,...}`; de ésas el corpus tiene # CERO. Firefox trae todas en el árbol, así que se dejan bundleadas: son menos piezas móviles para el # primer build, que es exactamente cuando conviene minimizar variables. Cuando alguna de esas # librerías tenga receta propia y valga compartirla, el flag se enciende y se re-mide. # # ══ SIN BRANDING OFICIAL, Y NO ES UN DESCUIDO ══════════════════════════════════════════════════ # Alpine pone `--enable-official-branding`. Acá NO: el binario lleva once parches, y usar el nombre y # el logo de Firefox sobre un build modificado entra en la política de marcas de Mozilla — es # literalmente la historia de Iceweasel en Debian. Con el branding `unofficial` el navegador es el # mismo software y nadie tiene que pedir permiso a nadie. Es la misma cautela que la receta de # `dejavu-fonts-nerd` ya aplicó con la licencia de Bitstream Vera: **una fuente modificada no puede # llamarse como la original, y un navegador parcheado tampoco.** # # ══ WAYLAND-ONLY, HEREDADO DE GTK3 ═════════════════════════════════════════════════════════════ # `--enable-default-toolkit=cairo-gtk3-wayland`. Nuestro GTK3 se construyó con `-Dx11_backend=false` # ⇒ este Firefox **no puede correr como cliente X11 ni bajo Xwayland**. Bajo Wayland nativo sí. Está # escrito en `recipes/gtk3.toml` y se repite acá porque es lo primero que alguien va a preguntar. # # ══ HERMÉTICO: NADA DE RED DURANTE EL BUILD ════════════════════════════════════════════════════ # --disable-bootstrap su trabajo ES descargar toolchains. Prohibido. # MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE sin esto `mach` arma un virtualenv con `pip` y sale a # =system la red. Con `system` usa lo que ya está. # MOZBUILD_STATE_PATH por defecto escribe en `$HOME`, que en el sandbox no es # suyo; se apunta al árbol de build. # Los crates de Rust vienen VENDORIZADOS en el tarball (`third_party/rust`) ⇒ cargo no baja nada. # # ══ LO DEMÁS QUE SE APAGA ══════════════════════════════════════════════════════════════════════ # --disable-jemalloc musl trae su propio allocator; jemalloc encima es la receta del # cuelgue clásico de Firefox en Alpine. # --without-wasm-sandboxed- exige el SDK de WASI, que no está en ninguna cola. Apaga el # libraries sandbox wasm de algunas librerías de medios, no el sandbox del # proceso de contenido. # --disable-crashreporter manda telemetría a Mozilla; además pide breakpad. # --disable-updater la distro actualiza por hammer, no por un updater propio. # --disable-tests no entran al artefacto. # (SIN --enable-linker) Se deja que Firefox detecte solo. Con `zig-cc` esto era # OBLIGATORIO —zig se anuncia como `zig ld 0.16.0` y el sondeo de # `toolchain.configure` clasifica por esa cadena buscando # «mold»/«GNU ld»/«GNU gold»/«LLD»— y **pedir el linker por nombre # vuelve FATAL cualquier fallo del sondeo**. Con gcc el linker sí se # anuncia como «GNU ld», así que el flag ya no haría daño; se deja # fuera igual porque no aporta nada y una perilla menos es una # diferencia menos entre esta receta y las de Waterfox y Zen. name = "firefox" version = "154.0" license = "MPL-2.0" [source] # Tarball de RELEASE de Mozilla: fichero SUBIDO por upstream, sha256 estable y publicado en su # SHA256SUMS. No es un `/archive/` de forja, que se genera al vuelo (ver `recipes/mbedtls.toml`). tarball = "https://ftp.mozilla.org/pub/firefox/releases/154.0/source/firefox-154.0.source.tar.xz" sha256 = "36cec5b3688a60f78a6d20dcaee15b598f84e03c66f6587056aead6cb498b99a" # Los once de musl del APKBUILD de Alpine (community/firefox). NO se traen los suyos de ppc64le, # loongarch ni Android: no aplican a x86_64 y cada parche que no hace falta es una forma más de que # un rebase falle sin motivo. patches = [ "firefox-patches/lfs64.patch", "firefox-patches/time64.patch", "firefox-patches/musl-no-linux-prctl.patch", "firefox-patches/fix-fortify-system-wrappers.patch", "firefox-patches/fix-rust-target.patch", "firefox-patches/sandbox-sched_setscheduler.patch", "firefox-patches/abseil-cpp.patch", "firefox-patches/glean-stub.patch", "firefox-patches/rust-lto-thin.patch", "firefox-patches/wasip1.patch", "firefox-patches/widevine.patch", ] [build] # ══ `gcc` Y NO `zig-cc` — TRES MUROS DE UNA VEZ ════════════════════════════════════════════════ # El resto del corpus va con zig-cc y esta receta es una EXCEPCIÓN consciente, del mismo tipo que la # que el repo ya mantiene para el kernel y cmake (ADR 0011). Se llegó acá por eliminación, no por # comodidad — con zig-cc el configure de Firefox murió tres veces seguidas: # # 1. «Could not use lld as linker» — zig se identifica como `zig ld 0.16.0` y el sondeo de Mozilla # clasifica por esa cadena buscando «LLD»/«GNU ld»/«GNU gold». # 2. «Cannot find ar» — zig trae `ar` como SUBCOMANDO y `check_prog` busca un ejecutable. # 3. **«Firefox does not support linking statically with libstdc++»** — y éste no es un flag: # `flags.configure:79` compila un C++ mínimo, lo pasa por `llvm-objdump --private-headers` y # exige encontrar un `NEEDED …libc++`. zig enlaza libc++ ESTÁTICA para musl, así que ese NEEDED # no existe nunca. No hay perilla que apagar; es una negativa de upstream. # # El gcc del lab (15.2.0, con `libstdc++` COMPARTIDA) satisface los tres: `NEEDED libstdc++.so.6`, # un `ar` de verdad y un linker que se anuncia como «GNU ld». # # ⚠ EL PRECIO, ESCRITO: **el lab NO entra en `hash_inputs`**, así que un Firefox construido con el # gcc del lab queda más expuesto a la deriva del rootfs que uno con zig-cc — dos labs con gcc # distinto pueden sellar bytes distintos sin que el store lo note. Es la misma deuda que ya cargan el # kernel y las otras recetas `compiler=gcc`, y la razón por la que conviene no ampliar esta lista sin # haber agotado antes el camino de zig. compiler = "gcc" target = "x86_64-linux-musl" link = "dynamic" flags = [] # ══ `strip_debug`: SIN ESTO EL ARTEFACTO SERÍA INMANEJABLE ═════════════════════════════════════ # Medido en el `nodejs` que acaba de sellar sin strip: su binario pesa **984 MB, de los cuales # `.debug_info` son 497 MB y `.debug_line` otros 43** — más de la mitad del artefacto es información # de depuración. Firefox es varias veces V8, así que sin strip su artefacto entraría en varios GB, y # el store no es sólo disco: se sincroniza hub↔worker y se respalda. # # Es además el hallazgo del SDD 23: el 79% del contenido binario del store era `.debug_*`, y quitarlo # hace que artefactos que no reproducían PASEN a reproducir, porque lo que difería eran las rutas del # árbol de build embebidas en esas secciones. # # Entra en `hash_inputs` A PROPÓSITO (cambia el contenido del artefacto), y usa `zig objcopy`, que # siempre está en el sandbox ⇒ no agrega una dep de build. strip_debug = true [build.phases] configure = ''' export MOZBUILD_STATE_PATH="$PWD/.mozbuild" export MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE=system export MOZ_NOSPAM=1 # ── RUST_TARGET: lo EXIGE el parche de Alpine, no Firefox ───────────────────────────────────── # `fix-rust-target.patch` REEMPLAZA la autodetección del triple de Rust por un # `os.environ['RUST_TARGET']` pelado. Sin la variable, configure muere con # `KeyError: 'RUST_TARGET'` — que se lee como un bug de Firefox y es en realidad el contrato del # parche: el APKBUILD de Alpine lo exporta como `$CTARGET` y acá hay que hacer lo propio. # El valor NO se adivina: sale de `ls .dev-fs/alpine/usr/lib/rustlib/` en el lab, que es # `x86_64-alpine-linux-musl` — el rustc del sandbox es el de Alpine, no el del host (el del host es # `x86_64-unknown-linux-gnu` y usarlo produciría un cross-compile silencioso). export RUST_TARGET=x86_64-alpine-linux-musl cat > .mozconfig <<'MOZ' ac_add_options --prefix=/usr ac_add_options --enable-application=browser ac_add_options --enable-default-toolkit=cairo-gtk3-wayland ac_add_options --enable-release ac_add_options --enable-optimize ac_add_options --enable-hardening ac_add_options --with-branding=browser/branding/unofficial ac_add_options --with-libclang-path=/usr/lib ac_add_options --disable-bootstrap ac_add_options --disable-jemalloc ac_add_options --disable-crashreporter ac_add_options --disable-updater ac_add_options --disable-tests ac_add_options --disable-debug ac_add_options --disable-debug-symbols ac_add_options --disable-strip ac_add_options --disable-install-strip ac_add_options --disable-cargo-incremental ac_add_options --without-wasm-sandboxed-libraries ac_add_options --enable-alsa ac_add_options --enable-pulseaudio ac_add_options --enable-dbus ac_add_options --enable-ffmpeg mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir MOZ ./mach configure ''' # `mach build` respeta -jN; la cuenta es la misma que en nodejs.toml y por el mismo motivo: un número # fijo ataría el ArtifactHash a la RAM de quien escribió la receta. # ⚠ OJO con el techo: dentro del sandbox `/proc/meminfo` NO muestra la memoria del contenedor sino la # del host (medido en el LXC: 186 GiB en vez de 16), así que en un contenedor esta cuenta se degrada # a `nproc`. Es un tope, no una garantía. compile = ''' export RUST_TARGET=x86_64-alpine-linux-musl # ver la nota en la fase configure export MOZBUILD_STATE_PATH="$PWD/.mozbuild" export MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE=system export MOZ_NOSPAM=1 gib=$(awk "/MemTotal/{printf \"%d\", \$2/1024/1024}" /proc/meminfo) j=$(( gib / 3 )); [ "$j" -lt 1 ] && j=1 n=$(nproc); [ "$j" -gt "$n" ] && j=$n echo "mach build -j$j (MemTotal ${gib} GiB, nproc $n)" ./mach build -j"$j" ''' install = ''' export RUST_TARGET=x86_64-alpine-linux-musl # ver la nota en la fase configure export MOZBUILD_STATE_PATH="$PWD/.mozbuild" export MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE=system DESTDIR=/out ./mach install ''' [deps] build = [ "python3", "pkgconf", "nasm", "make", "cmake", # la plataforma Gecko, compartida con Waterfox y Zen "nodejs", "cbindgen", "clang18", "llvm18", "gtk3", "atk", "gdk-pixbuf", "pango", "cairo", "libepoxy", "glib-shared", "pcre2-shared", "libffi-shared", "zlib-shared", "harfbuzz", "fribidi", "freetype-shared", "fontconfig-shared", "pixman", "libpng-shared", "libjpeg-turbo-shared", "wayland", "wayland-protocols", "libxkbcommon", "mesa", "libdrm", "dbus", "pipewire", "pulseaudio", "alsa-lib", "libxml2-shared", "linux-headers", ]