diff mbox series

[2/4] update_font_cache: write caches that are valid in the final image

Message ID 20261013-fontcache-reproducible-mtime-v1-2-950f07b80f0f@gmail.com
State Under Review
Headers show
Series fontcache: make the caches built into an image valid | expand

Commit Message

Alex Kiernan Oct. 13, 2026, 10:49 a.m. UTC
fontconfig accepts a directory's cache only while the mtime recorded in
it matches the directory, and fc-cache records the mtime clamped to
SOURCE_DATE_EPOCH. The intercept runs with the image's
SOURCE_DATE_EPOCH, against font directories that still carry their
packages' mtimes, and reproducible_final_image_task later sets every
mtime in the image to REPRODUCIBLE_TIMESTAMP_ROOTFS. The recorded and
final mtimes never match, so on the target every cache the image ships
is rejected and each process using fontconfig rescans the fonts and
writes a cache of its own.

When REPRODUCIBLE_TIMESTAMP_ROOTFS is set, set the mtime of every
directory under ${datadir}/fonts to it before running fc-cache, and run
fc-cache with it as SOURCE_DATE_EPOCH, so the caches record the mtimes
the image ships with.

AI-Generated: Claude Opus 5.5 (Claude Code)
Signed-off-by: Alex Kiernan <alex.kiernan@gmail.com>
---
 meta/classes-recipe/fontcache.bbclass         |  1 +
 scripts/postinst-intercepts/update_font_cache | 12 +++++++++++-
 2 files changed, 12 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/meta/classes-recipe/fontcache.bbclass b/meta/classes-recipe/fontcache.bbclass
index deadcd2fbbeb..37ff7d7cbc7e 100644
--- a/meta/classes-recipe/fontcache.bbclass
+++ b/meta/classes-recipe/fontcache.bbclass
@@ -28,6 +28,7 @@  if [ -n "$D" ] ; then
 		'libdir="${libdir}"' \
 		'libexecdir="${libexecdir}"' \
 		'base_libdir="${base_libdir}"' \
+		'datadir="${datadir}"' \
 		'fontconfigcachedir="${FONTCONFIG_CACHE_DIR}"' \
 		'fontconfigcacheparams="${FONTCONFIG_CACHE_PARAMS}"' \
 		'fontconfigcacheenv="${FONTCONFIG_CACHE_ENV}"'
diff --git a/scripts/postinst-intercepts/update_font_cache b/scripts/postinst-intercepts/update_font_cache
index 900db042d64e..5098b2890cc8 100644
--- a/scripts/postinst-intercepts/update_font_cache
+++ b/scripts/postinst-intercepts/update_font_cache
@@ -7,7 +7,17 @@  set -e
 
 rm -f $D${fontconfigcachedir}/CACHEDIR.TAG
 
-PSEUDO_UNLOAD=1 ${binprefix}qemuwrapper -L $D -E ${fontconfigcacheenv} $D${libexecdir}/${binprefix}fc-cache --sysroot=$D --system-only ${fontconfigcacheparams}
+# fontconfig only uses a cache while the mtime it recorded for a font
+# directory, clamped to SOURCE_DATE_EPOCH, matches the directory. Every
+# mtime in the image is set to REPRODUCIBLE_TIMESTAMP_ROOTFS later, so set
+# the font directories' mtimes to it now and have fc-cache record that.
+sde=
+if [ -n "$REPRODUCIBLE_TIMESTAMP_ROOTFS" ] && [ -d $D${datadir}/fonts ]; then
+	find $D${datadir}/fonts -type d -exec touch -h --date=@$REPRODUCIBLE_TIMESTAMP_ROOTFS '{}' +
+	sde="-E SOURCE_DATE_EPOCH=$REPRODUCIBLE_TIMESTAMP_ROOTFS"
+fi
+
+PSEUDO_UNLOAD=1 ${binprefix}qemuwrapper -L $D -E ${fontconfigcacheenv} $sde $D${libexecdir}/${binprefix}fc-cache --sysroot=$D --system-only ${fontconfigcacheparams}
 
 chown -R root:root $D${fontconfigcachedir}
 find $D -type f -name .uuid -exec chown root:root '{}' +