From 44b3624de64890d45e875018052125f87b9f09b1 Mon Sep 17 00:00:00 2001 From: Sergio Date: Mon, 14 Sep 2026 16:40:35 +0000 Subject: [PATCH] =?UTF-8?q?kirigami:=20arreglado=20el=20no-determinismo=20?= =?UTF-8?q?=E2=80=94=20eran=20DOS=20causas,=20y=20ahora=20reproduce=20bit?= =?UTF-8?q?=20a=20bit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Antes: dos reconstrucciones con las mismas entradas y el mismo lab daban artefactos distintos. Ahora: `why-differs` da 464 entradas idénticas · 0 divergen. Hash: 41eea38e… → a72b1626… (arrastra 37 dependientes directos, 39 transitivos). ── CAUSA 1: el AOT de QML compilaba un conjunto DISTINTO de funciones cada vez ───────── `libKirigamiTemplates.so` cambiaba de tamaño (5.737.344 vs 5.795.072) y difería en 177 símbolos locales, todos `QmlCacheGeneratedCode…__invoke` y concentrados en CUATRO ficheros: InlineMessage, LinkButton, NavigationTabBar y Badge. Y esos cuatro son justo los que importan módulos QML HERMANOS del propio proyecto (`org.kde.kirigami.platform`, `.primitives`, `.controls`). `qmlcachegen` sólo compila a AOT lo que puede resolver de tipos, y los tipos del hermano salen de su `.qmltypes`, que produce otro objetivo del mismo build. `src/templates/CMakeLists.txt` no declara `DEPENDENCIES` ninguna ⇒ con ninja en paralelo es una CARRERA. Control que sostiene el diagnóstico: `Chip` y `Heading`, del mismo directorio, no divergen — y `kirigami-addons` y `kquickcharts`, que también llevan QML, reproducen. No es «QML es no-determinista». Arreglo: `-j1` en el compile. Orden topológico fijo ⇒ el cachegen ve siempre lo mismo. NO es throttling (eso va por nice/taskset justamente para no re-hashear): es corrección, y el re-hash es el precio que se paga a propósito. Descartadas, con motivo: `-DQT_QML_NO_CACHEGEN=ON` apaga también el bytecode precompilado (coste de arranque en el escritorio); `--only-bytecode` sería lo quirúrgico pero `QT_QMLCACHEGEN_ARGUMENTS` es propiedad de objetivo y NO es INHERITED, así que no hay forma de ponerla desde la línea de órdenes. ── CAUSA 2: el .tar.bz2 de plantillas se armaba sin orden ────────────────────────────── `kde_package_app_templates` de ECM tiene camino reproducible —`--sort=name --mtime=@ SOURCE_DATE_EPOCH --numeric-owner --owner=0 --group=0`— pero detrás de `if(GNU_TAR_FOUND)`, que exige que `tar --version` diga «GNU tar». El rootfs del lab es Alpine: `tar` es BUSYBOX ⇒ caía al respaldo `cmake -E tar cvfj`, que ni ordena ni normaliza. El orden lo ponía readdir. Arreglo: `tar` (GNU tar 1.35, ya en el corpus) entra en `[deps] build`. Comprobado mirando el artefacto, no deducido: drwxr-xr-x 0/0 1970-01-01 00:00 ./ -rw-r--r-- 0/0 1970-01-01 00:00 ./CMakeLists.txt -rw-r--r-- 0/0 1970-01-01 00:00 ./LICENSES/BSD-3-Clause.txt owner 0/0, mtime al epoch (SOURCE_DATE_EPOCH=1 lo fija el sandbox) y la lista ORDENADA. --- docs/state/repro-verificado.tsv | 13 +++++++ recipes/incoming-kde/kirigami.toml | 56 ++++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/docs/state/repro-verificado.tsv b/docs/state/repro-verificado.tsv index 45f6a610..e83519e2 100644 --- a/docs/state/repro-verificado.tsv +++ b/docs/state/repro-verificado.tsv @@ -216,3 +216,16 @@ kcharselect 3e9900e586d2b49ccc516b0754a41290129b6035bb81f862ab55ee52fba8030d 202 kruler f07475e4b692543acb0b48cf9e6c2a86ae3aa2397b0135406835e225d82f129d 2026-09-14 reproduce kdf 65a6d9fe124d9f5ce03d0ee1fb0d061ae9f58fec3afbb35fb3ced4db3f7a4479 2026-09-14 reproduce kfind b7a5dd9fc4fafdde8504b509ed22356803ad4da4b2988b2a89d426c2c3d43053 2026-09-14 reproduce +kcalc a7266a6077d34613b2cd7c2fc2ab934dfe15684865fb4fdcdf36e580a9e20da2 2026-09-14 reproduce +filelight e4c6f43173166eda1d25e768b33b0a177beec3a7d3d1e83eb6a81d7eeb682ca3 2026-09-14 reproduce +kmenuedit 44e1ef340bccd4e6aa8ebdfac269dd3c4b0fc0fad08fa71b0d986721658173e7 2026-09-14 reproduce +kdnssd 89de58958d1cb247fe0c655c1f33c1f10caa009ce7074c610dc66bca8c0fcb98 2026-09-14 reproduce +kwalletmanager c619a551037711cf461cdb8a712fbfea85185afbe54af2480cd120cf2df5117a 2026-09-14 reproduce +kcmutils 391d231d4e28e02e716e23d9d87de4cc93cc720b776832a8f90dae2707404614 2026-09-14 reproduce +kactivitymanagerd d1e6e710fc0ba75567d8a170a00442a2412a92b1652ef15fb4337d60393ded5b 2026-09-14 reproduce +plasma-activities-stats 677930a594b1818b92d09905e1ba9d2652d11dc77b412c1797a375e57981ed3d 2026-09-14 reproduce +kdecoration 821bb8db7b3b2675f5fc284c7beefe4626ef95184aad9ce3744ede329e28e5a7 2026-09-14 reproduce +breeze c46ce734f6483f814933390cda0029e72ffb49ee5971ba2555e8af31e1ececbb 2026-09-14 reproduce +qqc2-desktop-style ca8419298d53d63b5d2a763cc8516b0278456a082172ef85aff1849124bbebc2 2026-09-14 reproduce +qqc2-breeze-style aabd2417ea27d5e543be2526851cadba5b79f1a4014af3247b8dc4639250f420 2026-09-14 reproduce +kirigami a72b1626d931c3c9efa43914100c560d7637c6db3cfbe028f23afdcfdfb08d92 2026-09-14 reproduce (arreglado: -j1 + GNU tar) diff --git a/recipes/incoming-kde/kirigami.toml b/recipes/incoming-kde/kirigami.toml index 46fb9c88..2c47bb6b 100644 --- a/recipes/incoming-kde/kirigami.toml +++ b/recipes/incoming-kde/kirigami.toml @@ -5,6 +5,55 @@ # Svg → qtsvg. ShaderTools (qsb) → qtshadertools. Core/Gui/Concurrent/DBus → qtbase. # CERO deps KF6 (el único find_package(KF6Kirigami) es auto-referencia en examples, OFF). Sin option(WITH_X11). # USE_DBUS ON por defecto en Linux → Qt6DBus (qtbase). BUILD_EXAMPLES OFF por defecto. DESKTOP_ENABLED ON. +# +# ══ ⚠ ESTA RECETA ERA NO-DETERMINISTA, Y SE ARREGLÓ EL 2026-09-14 (SDD 23) ═══════════════════════ +# Medido, no sospechado: dos reconstrucciones seguidas con las MISMAS entradas y el MISMO lab daban +# artefactos distintos. Eran dos causas independientes, y cada una tiene su arreglo abajo. +# +# ── CAUSA 1: el AOT de QML compilaba un CONJUNTO DISTINTO de funciones en cada corrida ─────────── +# `libKirigamiTemplates.so` cambiaba de tamaño (5.737.344 contra 5.795.072 bytes) y difería en 177 +# símbolos locales, todos `QmlCacheGeneratedCode…__invoke`, concentrados en CUATRO ficheros QML: +# InlineMessage, LinkButton, NavigationTabBar y Badge. No es que los símbolos se renumeren: es que +# una corrida compila a AOT funciones que la otra no. +# +# Y esos cuatro son exactamente los que importan MÓDULOS QML HERMANOS del propio proyecto +# (`org.kde.kirigami.platform`, `.primitives`, `.controls`). `qmlcachegen` sólo compila a AOT lo que +# puede resolver de tipos, y los tipos de un módulo hermano salen de su `.qmltypes`, que lo produce +# OTRO objetivo del mismo build. `src/templates/CMakeLists.txt` no declara `DEPENDENCIES` ninguna +# ⇒ con ninja en paralelo, que el `.qmltypes` del hermano exista cuando corre el cachegen de +# templates es una CARRERA. Se gana o se pierde según el planificador, y el artefacto sale distinto. +# +# Arreglo: `-j1` en el compile. Con ninja serial el orden es un topológico FIJO ⇒ el cachegen ve +# siempre el mismo estado y compila siempre el mismo conjunto. +# +# ⚠ Esto NO contradice la regla de «el paralelismo no se capa en la receta». Esa regla es sobre +# THROTTLING por recursos —que va por `nice`/`taskset` justamente para no re-hashear—; acá el `-j` +# es CORRECCIÓN, y el re-hash es el precio que se decidió pagar (arrastra 37 dependientes). +# +# ⚠ Las alternativas se miraron y se descartaron, con el motivo: +# · `-DQT_QML_NO_CACHEGEN=ON` — determinista y rápido, pero apaga TAMBIÉN el bytecode precompilado +# de todo el QML de Kirigami: eso es coste de arranque en el escritorio, no de build. +# · `--only-bytecode` por objetivo — sería lo quirúrgico (conserva bytecode, tira sólo el AOT), +# pero `QT_QMLCACHEGEN_ARGUMENTS` es propiedad DE OBJETIVO y no es INHERITED, así que no hay +# forma de ponerla desde la línea de órdenes; haría falta parchear los 9 subdirectorios. +# · declarar `DEPENDENCIES` en templates — es lo correcto aguas arriba, pero `controls` importa +# `templates` y `templates` importa `controls`: el ciclo hay que resolverlo con cuidado y eso +# es trabajo de upstream, no de esta receta. +# +# ── CAUSA 2: el `.tar.bz2` de plantillas se armaba SIN ORDEN ───────────────────────────────────── +# `usr/share/kdevappwizard/templates/kirigami6.tar.bz2` difería desde el byte 0xa, o sea desde el +# primer bloque comprimido. El macro `kde_package_app_templates` de ECM SÍ tiene camino reproducible +# —`--sort=name --mtime=@$SOURCE_DATE_EPOCH --numeric-owner --owner=0 --group=0`— pero está detrás +# de un `if(GNU_TAR_FOUND)`, y esa comprobación corre `tar --sort=name --version` y exige que diga +# «GNU tar». El rootfs del lab es Alpine: `tar` es BUSYBOX ⇒ la comprobación falla ⇒ cae al camino +# de respaldo `cmake -E tar cvfj`, que ni ordena ni normaliza mtime/owner. El orden lo ponía el +# readdir. +# +# Arreglo: `tar` (GNU tar 1.35, ya en el corpus) entra en `[deps] build`. Con él en el overlay la +# comprobación de ECM pasa y se toma el camino reproducible. `SOURCE_DATE_EPOCH` ya lo fija el +# sandbox (=1), así que el `--mtime` queda pineado sin tocar nada más. +# +# Comprobación: `scripts/verificar-repro.sh` sobre esta receta — dos reconstrucciones IDÉNTICAS. name = "kirigami" version = "6.27.0" license = "LGPL-2.1-or-later OR LGPL-3.0-or-later" @@ -39,8 +88,11 @@ cmake -B build -G Ninja -Wno-dev \ -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF \ -DBUILD_TESTING=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_EXAMPLES=OFF ''' -compile = "cmake --build build" +# ⚠ `-j1` NO es throttling: es lo que hace determinista el AOT de QML. Ver la cabecera. +compile = "cmake --build build -j1" install = "DESTDIR=/out cmake --install build" [deps] -build = ["cmake", "samurai", "python3", "pkgconf", "qtbase", "dbus", "extra-cmake-modules", "qttools", "mesa", "libdrm", "libxkbcommon", "wayland", "qtdeclarative", "qtsvg", "qtshadertools"] +# `tar` = GNU tar. NO es un capricho: sin él, ECM no reconoce un tar GNU y arma el .tar.bz2 de +# plantillas por el camino NO reproducible. Ver la cabecera, causa 2. +build = ["cmake", "samurai", "python3", "pkgconf", "qtbase", "dbus", "extra-cmake-modules", "qttools", "mesa", "libdrm", "libxkbcommon", "wayland", "qtdeclarative", "qtsvg", "qtshadertools", "tar"]