erplibre/script/install/lib_qpdf.sh
Mathieu Benoit a579cc9cf3 [FIX] install: the EL9, EL10 and Fedora build chain
"dnf install: error: unrecognized arguments" on AlmaLinux 10 and Rocky 10,
on every call: PostgreSQL, build dependencies, pyenv. The tools group got
away with its fallback, which made the trace misleading -- gcc installed,
nothing after it did.

"--skip-unavailable" is a dnf5 option, which the script's own comment
already said while assuming it everywhere. Fedora 41+ ships dnf5, but EL9
and EL10 stay on dnf4, whose equivalent is "--setopt=strict=0". We now ask
dnf what it understands instead of inferring it from the distribution.

Three neighbouring fixes: the "c-development" group does not exist on EL,
where it is called "development"; CRB is enabled through /usr/bin/crb; and
g++ plus the missing headers are installed explicitly. Rust is added only
where wheels are absent, and qpdf is built when the distribution ships one
older than pikepdf demands.

--- FR ---

« dnf install: error: unrecognized arguments » sur AlmaLinux 10 et
Rocky 10, à chaque appel : PostgreSQL, dépendances de compilation, pyenv.
Le groupe d'outils s'en tirait par son repli, ce qui rendait la trace
trompeuse — gcc installé, rien après lui.

« --skip-unavailable » est une option de dnf5, ce que le commentaire du
script disait déjà tout en la supposant partout. Fedora 41+ livre dnf5,
mais EL9 et EL10 restent sur dnf4, dont l'équivalent est
« --setopt=strict=0 ». On demande maintenant à dnf ce qu'il comprend
plutôt que de le déduire de la distribution.

Trois correctifs voisins : le groupe « c-development » n'existe pas sur
EL, où il s'appelle « development » ; CRB s'active par /usr/bin/crb ; et
g++ ainsi que les en-têtes manquants sont posés explicitement. Rust n'est
ajouté que là où les roues manquent, et qpdf est compilé quand la
distribution en livre un plus ancien que ce qu'exige pikepdf.

Assisted-by: Claude Opus 5
2026-08-16 23:33:49 -04:00

89 lines
4.1 KiB
Bash

#!/usr/bin/env bash
# © 2021-2026 TechnoLibre (http://www.technolibre.ca)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
#
# Bibliothèque SOURÇABLE : garantir un qpdf assez récent pour pikepdf.
#
# pikepdf 10 déclare QPDF_MIN_VERSION = "12.2.0" et se lie à la bibliothèque
# C++ de la distribution. Là où PyPI publie une roue, rien de tout cela ne
# s'exécute ; sur s390x il n'y en a aucune, pikepdf compile, et une version
# trop ancienne le fait échouer sur des en-têtes qui n'existent pas encore
# (« qpdf/QPDFJob.hh », apparu en 10.6 ; « qpdf/QPDFLogger.hh », en 11.0) puis
# sur des constantes renommées. Le message ne nomme jamais qpdf : on lit trois
# cents lignes de g++ avant de comprendre.
#
# Aucune famille n'est à jour partout, d'où le seuil plutôt qu'une liste de
# distributions : Ubuntu 24.04 livre 11.9, AlmaLinux et Rocky 9 livrent 10.3
# (sans même QPDFJob.hh), leurs 10 livrent 11.9 ; Ubuntu 25.10, Fedora 43 et
# Tumbleweed dépassent le seuil et ne compilent rien.
#
# Ce fichier existe parce que le bloc vivait en double : corrigé côté apt, il
# ne l'était pas côté dnf, et EL9 est ressorti sur exactement le même mur le
# lendemain. Le seuil, la version et la façon de bâtir sont désormais écrits
# UNE fois pour les trois familles de paquets.
EL_QPDF_MIN=12.2.0
EL_QPDF_VER=12.3.2
# Vrai si la version passée en argument atteint le seuil. « sort -V » est le
# seul comparateur de versions disponible partout sans dépendance, mais il
# classe « 12.2 » AVANT « 12.2.0 » — un paquet numéroté sur deux composantes
# aurait donc déclenché une compilation d'une demi-heure pour rien. On complète
# les composantes manquantes avant de comparer.
el_qpdf_ge_min() {
local v="$1" dots
[ -n "${v}" ] || return 1
dots="${v//[^.]/}"
while [ "${#dots}" -lt 2 ]; do
v="${v}.0"
dots="${dots}."
done
[ "$(printf '%s\n%s\n' "${EL_QPDF_MIN}" "${v}" | sort -V | head -1)" = "${EL_QPDF_MIN}" ]
}
# Version actuellement visible du compilateur, ou « 0 ».
# /usr/local n'est pas dans le chemin par défaut de pkg-config sur toutes les
# familles : sans ces deux entrées, un qpdf déjà compilé passerait inaperçu et
# on le recompilerait à chaque passage du script.
el_qpdf_version() {
PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:/usr/local/lib64/pkgconfig:${PKG_CONFIG_PATH}" \
pkg-config --modversion libqpdf 2> /dev/null || echo 0
}
# Compile et installe qpdf dans /usr/local si, et seulement si, ce qui est
# présent ne suffit pas. Ne rend jamais un code non nul : l'échec est signalé
# et l'installation continue, pikepdf dira lui-même ce qui manque.
el_qpdf_ensure() {
local have build dir
have="$(el_qpdf_version)"
if el_qpdf_ge_min "${have}"; then
echo "qpdf ${have} >= ${EL_QPDF_MIN} : rien a compiler pour pikepdf."
return 0
fi
echo "qpdf ${have} < ${EL_QPDF_MIN} requis par pikepdf : compilation de qpdf ${EL_QPDF_VER} (long en emulation)."
build="$(mktemp -d)"
if curl -fsSL --max-time 600 -o "${build}/qpdf.tar.gz" \
"https://github.com/qpdf/qpdf/releases/download/v${EL_QPDF_VER}/qpdf-${EL_QPDF_VER}.tar.gz" \
&& tar -xzf "${build}/qpdf.tar.gz" -C "${build}" \
&& cmake -S "${build}/qpdf-${EL_QPDF_VER}" -B "${build}/build" \
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local \
-DBUILD_DOC=OFF -DBUILD_STATIC_LIBS=OFF \
&& cmake --build "${build}/build" -j"$(nproc)" \
&& sudo cmake --install "${build}/build"; then
# CMake choisit « lib » ou « lib64 » selon la famille, et /usr/local/lib64
# n'est pas dans le chemin de ld.so d'EL : sans cette déclaration, pikepdf
# se construirait pour échouer au CHARGEMENT, encore plus loin de la cause.
for dir in /usr/local/lib64 /usr/local/lib; do
if [ -e "${dir}/libqpdf.so" ]; then
echo "${dir}" | sudo tee /etc/ld.so.conf.d/qpdf-local.conf > /dev/null
break
fi
done
sudo ldconfig
echo "qpdf $(el_qpdf_version) installe dans /usr/local."
else
echo "Attention : compilation de qpdf echouee, pikepdf ne pourra pas se construire."
fi
rm -rf "${build}"
}