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…
kirigami: arreglado el no-determinismo — eran DOS causas, y ahora reproduce bit a bit
1# kirigami 6.27.0 — KDE Frameworks 6 (tier-4, ADR 0011). Toolkit QML de KDE (UI Plasma Mobile/Desktop).
2# Tarball 6.27 se llama "kirigami" (ya no kirigami2). Precursor QML-pesado de Plasma.
3# CMakeLists: find_package(Qt6 REQUIRED Core Quick Gui Svg QuickControls2 Concurrent ShaderTools).
4# Quick+QuickControls2 → qtdeclarative (en Qt6 QtQuickControls2 vive en el repo qtdeclarative).
5# Svg → qtsvg. ShaderTools (qsb) → qtshadertools. Core/Gui/Concurrent/DBus → qtbase.
6# CERO deps KF6 (el único find_package(KF6Kirigami) es auto-referencia en examples, OFF). Sin option(WITH_X11).
7# USE_DBUS ON por defecto en Linux → Qt6DBus (qtbase). BUILD_EXAMPLES OFF por defecto. DESKTOP_ENABLED ON.
8#
9# ══ ⚠ ESTA RECETA ERA NO-DETERMINISTA, Y SE ARREGLÓ EL 2026-09-14 (SDD 23) ═══════════════════════
10# Medido, no sospechado: dos reconstrucciones seguidas con las MISMAS entradas y el MISMO lab daban
11# artefactos distintos. Eran dos causas independientes, y cada una tiene su arreglo abajo.
12#
13# ── CAUSA 1: el AOT de QML compilaba un CONJUNTO DISTINTO de funciones en cada corrida ───────────
14# `libKirigamiTemplates.so` cambiaba de tamaño (5.737.344 contra 5.795.072 bytes) y difería en 177
15# símbolos locales, todos `QmlCacheGeneratedCode…__invoke`, concentrados en CUATRO ficheros QML:
16# InlineMessage, LinkButton, NavigationTabBar y Badge. No es que los símbolos se renumeren: es que
17# una corrida compila a AOT funciones que la otra no.
18#
19# Y esos cuatro son exactamente los que importan MÓDULOS QML HERMANOS del propio proyecto
20# (`org.kde.kirigami.platform`, `.primitives`, `.controls`). `qmlcachegen` sólo compila a AOT lo que
21# puede resolver de tipos, y los tipos de un módulo hermano salen de su `.qmltypes`, que lo produce
22# OTRO objetivo del mismo build. `src/templates/CMakeLists.txt` no declara `DEPENDENCIES` ninguna
23# ⇒ con ninja en paralelo, que el `.qmltypes` del hermano exista cuando corre el cachegen de
24# templates es una CARRERA. Se gana o se pierde según el planificador, y el artefacto sale distinto.
25#
26# Arreglo: `-j1` en el compile. Con ninja serial el orden es un topológico FIJO ⇒ el cachegen ve
27# siempre el mismo estado y compila siempre el mismo conjunto.
28#
29# ⚠ Esto NO contradice la regla de «el paralelismo no se capa en la receta». Esa regla es sobre
30# THROTTLING por recursos —que va por `nice`/`taskset` justamente para no re-hashear—; acá el `-j`
31# es CORRECCIÓN, y el re-hash es el precio que se decidió pagar (arrastra 37 dependientes).
32#
33# ⚠ Las alternativas se miraron y se descartaron, con el motivo:
34# · `-DQT_QML_NO_CACHEGEN=ON` — determinista y rápido, pero apaga TAMBIÉN el bytecode precompilado
35# de todo el QML de Kirigami: eso es coste de arranque en el escritorio, no de build.
36# · `--only-bytecode` por objetivo — sería lo quirúrgico (conserva bytecode, tira sólo el AOT),
37# pero `QT_QMLCACHEGEN_ARGUMENTS` es propiedad DE OBJETIVO y no es INHERITED, así que no hay
38# forma de ponerla desde la línea de órdenes; haría falta parchear los 9 subdirectorios.
39# · declarar `DEPENDENCIES` en templates — es lo correcto aguas arriba, pero `controls` importa
40# `templates` y `templates` importa `controls`: el ciclo hay que resolverlo con cuidado y eso
41# es trabajo de upstream, no de esta receta.
42#
43# ── CAUSA 2: el `.tar.bz2` de plantillas se armaba SIN ORDEN ─────────────────────────────────────
44# `usr/share/kdevappwizard/templates/kirigami6.tar.bz2` difería desde el byte 0xa, o sea desde el
45# primer bloque comprimido. El macro `kde_package_app_templates` de ECM SÍ tiene camino reproducible
46# —`--sort=name --mtime=@$SOURCE_DATE_EPOCH --numeric-owner --owner=0 --group=0`— pero está detrás
47# de un `if(GNU_TAR_FOUND)`, y esa comprobación corre `tar --sort=name --version` y exige que diga
48# «GNU tar». El rootfs del lab es Alpine: `tar` es BUSYBOX ⇒ la comprobación falla ⇒ cae al camino
49# de respaldo `cmake -E tar cvfj`, que ni ordena ni normaliza mtime/owner. El orden lo ponía el
50# readdir.
51#
52# Arreglo: `tar` (GNU tar 1.35, ya en el corpus) entra en `[deps] build`. Con él en el overlay la
53# comprobación de ECM pasa y se toma el camino reproducible. `SOURCE_DATE_EPOCH` ya lo fija el
54# sandbox (=1), así que el `--mtime` queda pineado sin tocar nada más.
55#
56# Comprobación: `scripts/verificar-repro.sh` sobre esta receta — dos reconstrucciones IDÉNTICAS.
57name = "kirigami"
58version = "6.27.0"
59license = "LGPL-2.1-or-later OR LGPL-3.0-or-later"
60
61[source]
62tarball = "https://download.kde.org/stable/frameworks/6.27/kirigami-6.27.0.tar.xz"
63sha256 = "d7daa74e9fe81b674e54e6e979feb85d3d2f4216bf6d9c02bfaa2c021fe1ac2d"
64
65[build]
66compiler = "zig-cc"
67target = "x86_64-linux-musl"
68link = "dynamic"
69flags = []
70
71[build.phases]
72configure = '''
73ZW="$PWD/.zwrap"; mkdir -p "$ZW"
74cat > "$ZW/cc" <<'W'
75#!/bin/sh
76a=""; for x in "$@"; do [ "$x" = "-Wl,--fatal-warnings" ] && continue; a="$a $x"; done
77exec /opt/zig/zig cc -mcpu=baseline $a
78W
79cat > "$ZW/cxx" <<'W'
80#!/bin/sh
81a=""; for x in "$@"; do [ "$x" = "-Wl,--fatal-warnings" ] && continue; a="$a $x"; done
82exec /opt/zig/zig c++ -mcpu=baseline $a
83W
84chmod +x "$ZW/cc" "$ZW/cxx"
85cmake -B build -G Ninja -Wno-dev \
86 -DCMAKE_C_COMPILER="$ZW/cc" -DCMAKE_CXX_COMPILER="$ZW/cxx" -DCMAKE_ASM_COMPILER="$ZW/cc" \
87 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_PREFIX_PATH=/usr \
88 -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF \
89 -DBUILD_TESTING=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_EXAMPLES=OFF
90'''
91# ⚠ `-j1` NO es throttling: es lo que hace determinista el AOT de QML. Ver la cabecera.
92compile = "cmake --build build -j1"
93install = "DESTDIR=/out cmake --install build"
94
95[deps]
96# `tar` = GNU tar. NO es un capricho: sin él, ECM no reconoce un tar GNU y arma el .tar.bz2 de
97# plantillas por el camino NO reproducible. Ver la cabecera, causa 2.
98build = ["cmake", "samurai", "python3", "pkgconf", "qtbase", "dbus", "extra-cmake-modules", "qttools", "mesa", "libdrm", "libxkbcommon", "wayland", "qtdeclarative", "qtsvg", "qtshadertools", "tar"]