From deae7d16c76d52f9838881b4557a0f617138925e Mon Sep 17 00:00:00 2001 From: Mathieu Benoit Date: Fri, 14 Aug 2026 02:19:41 -0400 Subject: [PATCH] [ADD] install s390x : batir PROJ quand la distribution est en retard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Debian 13 installe ERPLibre de bout en bout ; Debian 12 s'arrete sur pyproj : ERROR: Minimum supported PROJ version is 9.4.0, installed version is 9.1.1 bookworm livre 9.1.1, trixie 9.6 — d'ou l'ecart entre les deux. La portee est etroite : sur amd64 et arm64, pyproj pose une roue manylinux qui EMBARQUE sa propre PROJ, et la version du systeme n'entre pas en jeu. s390x n'a pas de roue et compile contre celle du systeme. lib_proj.sh est le calque de lib_qpdf.sh, meme motif et memes garde-fous : seuil, comparaison qui complete les composantes manquantes — « sort -V » classe 9.4 avant 9.4.0 — installation dans /usr/local, declaration a ld.so, et jamais de code non nul pour ne pas masquer ce que pyproj dira lui-meme. L'appel reste sous la garde s390x, verifie. --- EN --- Debian 13 installs ERPLibre end to end; Debian 12 stops on pyproj: ERROR: Minimum supported PROJ version is 9.4.0, installed version is 9.1.1 bookworm ships 9.1.1, trixie 9.6 — hence the gap between the two. The scope is narrow: on amd64 and arm64 pyproj lays down a manylinux wheel that BUNDLES its own PROJ, and the system version never comes into play. s390x has no wheel and builds against the system one. lib_proj.sh mirrors lib_qpdf.sh, same pattern and same guards: a threshold, a comparison that pads missing components — "sort -V" ranks 9.4 before 9.4.0 — installation into /usr/local, an ld.so declaration, and never a non-zero exit so as not to mask what pyproj itself will say. The call stays under the s390x guard, verified. Assisted-by: Claude Opus 5 (cherry picked from commit f779702b61ff6405bdd7efabaa1f5bac09e1166b) --- script/install/install_debian_dependency.sh | 7 +- script/install/lib_proj.sh | 89 +++++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 script/install/lib_proj.sh diff --git a/script/install/install_debian_dependency.sh b/script/install/install_debian_dependency.sh index 52e1b4e..908f523 100755 --- a/script/install/install_debian_dependency.sh +++ b/script/install/install_debian_dependency.sh @@ -2,6 +2,7 @@ . ./env_var.sh . ./script/install/lib_qpdf.sh +. ./script/install/lib_proj.sh . ./script/install/lib_lowmem.sh EL_USER=${USER} @@ -163,7 +164,7 @@ if [ "$(uname -m)" = "s390x" ]; then apt_install_batch rust-all libqpdf-dev libgeos-dev libproj-dev proj-bin \ proj-data "${GEO_DEV}" freetds-dev freetds-bin libkrb5-dev libssl-dev \ pkg-config build-essential zlib1g-dev libjpeg-dev libtbb-dev cmake \ - ninja-build + ninja-build libsqlite3-dev sqlite3 libtiff-dev libcurl4-openssl-dev if [[ -n "${APT_FAILED}" ]]; then # Seul un paquet dont dépend la SUITE immédiate est bloquant. Les autres # servent des modules Odoo optionnels : les rendre fatals immobiliserait @@ -202,6 +203,10 @@ if [ "$(uname -m)" = "s390x" ]; then # -- seuil, version batie, chemin d'installation -- est dans lib_qpdf.sh, # partage avec les scripts dnf et zypper qui butaient sur le meme mur. el_qpdf_ensure + # pyproj exige PROJ 9.4 ; bookworm en livre 9.1.1. Meme mecanique que + # qpdf, et meme portee etroite : ailleurs pyproj pose une roue qui + # embarque sa propre PROJ, ici il compile contre celle du systeme. + el_proj_ensure # cryptography ne publie aucune roue s390x : elle se compile, et son # Cargo.lock est en version 4, que seul cargo >= 1.78 sait lire. Ubuntu 24.04 # livre 1.75 et s'arrête sur « lock file version 4 requires diff --git a/script/install/lib_proj.sh b/script/install/lib_proj.sh new file mode 100644 index 0000000..5001bf4 --- /dev/null +++ b/script/install/lib_proj.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +# © 2021-2026 TechnoLibre (http://www.technolibre.ca) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +# +# PROJ assez récent pour pyproj, compilé depuis les sources quand la +# distribution est en retard. Calque de lib_qpdf.sh, pour la même raison et +# avec les mêmes garde-fous. +# +# QUI est concerné, et qui ne l'est pas : sur amd64 et arm64, pyproj publie +# des roues manylinux qui EMBARQUENT leur propre PROJ — rien n'est compilé et +# la version du système n'a aucune importance. s390x n'a pas de roue : pyproj +# se construit contre la PROJ du système, et refuse net si elle est trop +# vieille. +# +# ERROR: Minimum supported PROJ version is 9.4.0, installed version is 9.1.1 +# +# Mesuré sur Debian 12 (bookworm) s390x. Debian 13 livre 9.6 et passe sans +# rien faire ; ce fichier ne s'y déclenche donc pas. + +# Seuil réclamé par pyproj 3.7.x. Le monter suppose de vérifier ce qu'exige la +# version de pyproj réellement verrouillée dans poetry.lock. +EL_PROJ_MIN=9.4.0 +# Version bâtie quand le seuil n'est pas atteint. 9.6.x est la branche stable +# la plus récente à ce jour et couvre largement le seuil. +EL_PROJ_VER=9.6.2 + +# Vrai si la version passée en argument atteint le seuil. Même précaution que +# pour qpdf : « sort -V » classe « 9.4 » AVANT « 9.4.0 », donc une version +# numérotée sur deux composantes déclencherait une compilation inutile — et +# celle de PROJ se compte en dizaines de minutes sous émulation. +el_proj_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_PROJ_MIN}" "${v}" | sort -V | head -1)" = "${EL_PROJ_MIN}" ] +} + +# Version actuellement visible, ou « 0 ». /usr/local n'est pas dans le chemin +# par défaut de pkg-config partout : sans ces entrées, une PROJ déjà compilée +# passerait inaperçue et serait rebâtie à chaque passage. +el_proj_version() { + PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:/usr/local/lib64/pkgconfig:${PKG_CONFIG_PATH}" \ + pkg-config --modversion proj 2> /dev/null || echo 0 +} + +# Compile et installe PROJ 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, pyproj dira lui-même ce qui manque. +el_proj_ensure() { + local have build dir + have="$(el_proj_version)" + if el_proj_ge_min "${have}"; then + echo "PROJ ${have} >= ${EL_PROJ_MIN} : rien a compiler pour pyproj." + return 0 + fi + + echo "PROJ ${have} < ${EL_PROJ_MIN} requis par pyproj : compilation de PROJ ${EL_PROJ_VER} (long en emulation)." + build="$(mktemp -d)" + # TESTING=OFF et les outils en moins : seule la bibliothèque intéresse + # pyproj, et la suite de tests de PROJ double le temps de compilation. + if curl -fsSL --max-time 900 -o "${build}/proj.tar.gz" \ + "https://download.osgeo.org/proj/proj-${EL_PROJ_VER}.tar.gz" \ + && tar -xzf "${build}/proj.tar.gz" -C "${build}" \ + && cmake -S "${build}/proj-${EL_PROJ_VER}" -B "${build}/build" \ + -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DBUILD_TESTING=OFF -DBUILD_APPS=ON -DBUILD_SHARED_LIBS=ON \ + && 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 partout : sans cette déclaration, + # pyproj se construirait pour échouer au CHARGEMENT, plus loin de la cause. + for dir in /usr/local/lib64 /usr/local/lib; do + if [ -e "${dir}/libproj.so" ]; then + echo "${dir}" | sudo tee /etc/ld.so.conf.d/proj-local.conf > /dev/null + break + fi + done + sudo ldconfig + echo "PROJ $(el_proj_version) installe dans /usr/local." + else + echo "Attention : compilation de PROJ echouee, pyproj ne pourra pas se construire." + fi + rm -rf "${build}" + return 0 +}