olex2: bundle glibc 2.39 + libstdc++ 14 sysroot, patchelf the executables
The 2026 upstream Linux binaries (olex2c, olex2, unirun, NoSpherA2, openblas, cctbx ext) need GLIBC_2.38 / GLIBCXX_3.4.32; RHEL9 has 2.34 / 3.4.29 so they cannot run natively and a newer libc cannot be supplied via LD_LIBRARY_PATH. Fetch frozen Fedora 40 glibc/libstdc++/libgcc rpms from kojipkgs plus a static patchelf (all sha256-pinned), extract them into PREFIX/sysroot and set interpreter + DT_RPATH on the dynamic executables. Host keeps providing GTK2/X11/GL. Launcher sets C.UTF-8 and never exposes the sysroot on LD_LIBRARY_PATH. Install verifies with ld.so --list that olex2c resolves through the bundled glibc.
This commit is contained in:
1 parent
2b5bb570ca
commit
53a5753541
4 files changed
+225
-47
No files matched your search
+91
-36
@@ -34,26 +34,72 @@ olex2/ilib/ olex2/util/pyUtil/ olex2/etc/ olex2/sample_data/ NoSpherA2,
|
||||
|
||||
The recipe (`build`):
|
||||
|
||||
1. default `pbuild::prep` downloads the zip per `urls:` in
|
||||
`files/config.yaml` into the distfiles cache as
|
||||
`olex2-<version>-linux64.zip`, verifies the pinned sha256 and copies it
|
||||
to `SRC_DIR` (`unpacker: none`);
|
||||
2. `configure` runs `unzip -t` (truncated-download guard) and unzips;
|
||||
1. default `pbuild::prep` downloads the zip, three Fedora 40 rpms and a
|
||||
static patchelf per `urls:` in `files/config.yaml` into the distfiles
|
||||
cache, verifies the pinned sha256 of each and copies them to `SRC_DIR`
|
||||
(`unpacker: none`);
|
||||
2. `configure` runs `unzip -t` (truncated-download guard), unzips, extracts
|
||||
the rpms with `rpm2cpio | cpio` into `SRC_DIR/sysroot` and checks the
|
||||
bundled `ld.so` runs;
|
||||
3. `install` copies the vendor tree **flat into `$PREFIX`** — Olex2 derives
|
||||
its `BaseDir()` from the binary location, so the layout must stay as
|
||||
shipped — fixes modes, switches `usettings.dat` to `update=Never`, and
|
||||
installs `files/olex2-launcher` twice as `$PREFIX/bin/olex2` and
|
||||
`$PREFIX/bin/olex2c`. Only `$PREFIX/bin` goes on `PATH`.
|
||||
shipped — plus `$PREFIX/sysroot`, fixes modes, switches `usettings.dat`
|
||||
to `update=Never`, **patchelf's** `olex2c olex2 unirun NoSpherA2` to the
|
||||
bundled loader (see next section), installs `files/olex2-launcher` twice
|
||||
as `$PREFIX/bin/olex2` and `$PREFIX/bin/olex2c`, and proves with
|
||||
`ld.so --list olex2c` that the binary resolves through the bundled glibc.
|
||||
Only `$PREFIX/bin` goes on `PATH`.
|
||||
|
||||
`files/olex2-launcher` is the vendor `start` script minus the updater: it
|
||||
exports `OLEX2_CCTBX_DIR`, `BOOST_ADAPTBX_*`, `OLEX2_GL_*`,
|
||||
`LD_LIBRARY_PATH=$PREFIX/lib:$PREFIX/ilib:$PREFIX/cctbx/cctbx_build/lib`,
|
||||
`PYTHONHOME=$PREFIX`, unsets `PYTHONPATH` (an inherited one would be
|
||||
imported by the embedded Python 3.8 and break it), sets
|
||||
`LIBGL_ALWAYS_SOFTWARE=1` for the GUI only, then `exec`s the binary.
|
||||
`PYTHONHOME=$PREFIX`, `LANG/LC_ALL=C.UTF-8`, unsets `PYTHONPATH` (an
|
||||
inherited one would be imported by the embedded Python 3.8 and break it),
|
||||
sets `LIBGL_ALWAYS_SOFTWARE=1` for the GUI only, then `exec`s the binary.
|
||||
`unirun` is never run: `/opt/psi/MX` is shared and read-only, updates are
|
||||
done by building a new module version.
|
||||
|
||||
### Bundled glibc 2.39 sysroot (why and how)
|
||||
|
||||
Since 2026 OlexSys builds the Linux binaries on an Ubuntu 24.04-class
|
||||
toolchain. Scanning the archive's ELF files (2026-10-16):
|
||||
|
||||
| file | needs |
|
||||
|---|---|
|
||||
| olex2c, olex2, unirun | GLIBC_2.38, GLIBCXX_3.4.32 |
|
||||
| NoSpherA2, lib/libopenblas.so.0, some cctbx_build/lib/*.so | GLIBC_2.38 |
|
||||
| RHEL9 provides | GLIBC_2.34, GLIBCXX_3.4.29 |
|
||||
| RHEL8 provides | GLIBC_2.28, GLIBCXX_3.4.25 |
|
||||
|
||||
A newer glibc can **not** be dropped in via `LD_LIBRARY_PATH`: the dynamic
|
||||
loader path (`/lib64/ld-linux-x86-64.so.2`) is hard-wired into each
|
||||
executable and must match its libc. So the recipe:
|
||||
|
||||
- ships glibc 2.39 + GCC 14 `libstdc++`/`libgcc_s` under `$PREFIX/sysroot`
|
||||
(frozen Fedora 40 rpms from kojipkgs, Fedora's permanent build archive;
|
||||
same glibc generation as the upstream build host);
|
||||
- runs `patchelf --set-interpreter <sysroot ld.so> --force-rpath --set-rpath
|
||||
<sysroot libdir>:$PREFIX/lib:$PREFIX/ilib:$PREFIX/cctbx/cctbx_build/lib:$PREFIX:$ORIGIN`
|
||||
on every dynamic executable (`hart`, `hart_mpi` are static and skipped).
|
||||
DT_RPATH, not RUNPATH, so that everything the embedded Python `dlopen()`s
|
||||
later resolves libc/libstdc++/openblas through the same list;
|
||||
- leaves GTK2, X11, GL, fontconfig, libcrypt etc. to the **host**: libraries
|
||||
built against an older glibc run fine on a newer one, the reverse does not.
|
||||
|
||||
Rules that keep this safe:
|
||||
|
||||
- the sysroot lib dir is never exported in `LD_LIBRARY_PATH` (child
|
||||
processes — `sh`, `shelxl`, editors — would load the foreign libc and
|
||||
crash); only the patched executables see it, through their RPATH;
|
||||
- `LANG=LC_ALL=C.UTF-8` in the launcher: the bundled glibc has no locale
|
||||
archive, C.UTF-8 is built in;
|
||||
- the originals are untouched inside the cached zip; a rebuild re-patches
|
||||
from scratch.
|
||||
|
||||
Unverified until the first RHEL9 run: NSS lookups through the host's
|
||||
`libnss_sss` under the newer libc (expected fine, NSS ABI is stable), and
|
||||
`hart_mpi` against the host MPI.
|
||||
|
||||
### Why the binary archive and not a source build
|
||||
|
||||
The user-facing "open source" route *is* this archive: Olex2 is BSD and the
|
||||
@@ -66,47 +112,51 @@ README says to take the official distribution and only swap in self-built
|
||||
`olex2`/`unirun` binaries. The `Headless.zip`/`Batch.zip` next to the
|
||||
archive on the download server are 2 KB plugin stubs, not builds.
|
||||
|
||||
Alternative considered: an Apptainer image (`ubuntu:24.04` + gtk2/GL) that
|
||||
`exec`s the host-side tree. Cleaner for the next rolling drop, but needs
|
||||
apptainer on every execution host and a privileged/fakeroot image build.
|
||||
Switch to it if the sysroot route shows locale/NSS/MPI trouble.
|
||||
|
||||
## Building on Ra / RHEL9
|
||||
|
||||
```sh
|
||||
module use unstable && module load modbuild/2.1.3
|
||||
module purge; module use unstable && module load modbuild/2.1.3
|
||||
cd olex2
|
||||
modbuild build \
|
||||
modbuild build --clean-install \
|
||||
--tmpdir=/das/work/p21/p21515/.cache/Pmodules \
|
||||
--distdir=/das/work/p21/p21515/.cache/Pmodules \
|
||||
1.5-7665
|
||||
module use MX unstable && module load olex2/1.5-7665
|
||||
```
|
||||
|
||||
Expect a silent 10–20 min for the `cp -a` of ~12 000 files onto `/opt/psi`;
|
||||
watch `du -sh /opt/psi/MX/olex2/1.5-7665` from a second shell. Needs
|
||||
`unzip` on the build host.
|
||||
Build host needs `unzip`, `rpm2cpio` (rpm) and `cpio`. Expect a silent
|
||||
10–20 min for the copy of ~12 000 files onto `/opt/psi`; watch
|
||||
`du -sh /opt/psi/MX/olex2/1.5-7665` from a second shell. The install step
|
||||
ends with `olex2: <exe> -> interpreter .../sysroot/...` lines and, if the
|
||||
build host lacks gtk2 etc., a WARNING list of host libs to install on the
|
||||
execution hosts.
|
||||
|
||||
If the download server is unreachable from the build host (it is a plain
|
||||
https URL, no login), fetch the zip anywhere and pre-stage it under the
|
||||
exact name `<distdir>/olex2-1.5-7665-linux64.zip`; prep then skips the
|
||||
If the download server is unreachable from the build host (plain https
|
||||
URLs, no login), fetch the files anywhere and pre-stage them under the
|
||||
exact names from `files/config.yaml` in `<distdir>`; prep then skips the
|
||||
download but still checks the sha256.
|
||||
|
||||
**RHEL9 runtime libraries.** The binaries bundle their own python, ssl,
|
||||
png, jpeg, tiff, openblas, gfortran, but link system X11/GTK/OpenGL. On a
|
||||
fresh RHEL9 host check once:
|
||||
**RHEL9 host libraries.** The binaries bring their own glibc, libstdc++,
|
||||
python, ssl, png, jpeg, tiff, openblas, gfortran, but link system
|
||||
GTK2/X11/OpenGL — also `olex2c` (wx is linked in statically). Check once
|
||||
per host type:
|
||||
|
||||
```sh
|
||||
module load olex2/1.5-7665
|
||||
ldd /opt/psi/MX/olex2/1.5-7665/olex2c | grep 'not found' # console: expect nothing
|
||||
ldd /opt/psi/MX/olex2/1.5-7665/olex2 | grep 'not found' # GUI: typically gtk/mesa libs
|
||||
P=/opt/psi/MX/olex2/1.5-7665
|
||||
$P/sysroot/usr/lib64/ld-linux-x86-64.so.2 --list $P/olex2c | grep -E 'not found|libc.so.6|libstdc'
|
||||
```
|
||||
|
||||
and `dnf install` whatever the GUI line reports (likely candidates:
|
||||
`gtk3`/`gtk2`, `mesa-libGL`, `mesa-libGLU`, `libSM`, `libXxf86vm`,
|
||||
`libxkbcommon`, `libstdc++`). `olex2c` has far fewer needs and is the one to
|
||||
verify first. Note `ldd` on the raw binary without the launcher's
|
||||
`LD_LIBRARY_PATH` also lists the bundled libs as missing — only lines that
|
||||
survive with the launcher env count:
|
||||
|
||||
```sh
|
||||
LD_LIBRARY_PATH=$P/lib:$P/ilib:$P/cctbx/cctbx_build/lib ldd $P/olex2c | grep 'not found' # P=/opt/psi/MX/olex2/1.5-7665
|
||||
```
|
||||
`libc.so.6`/`libstdc++.so.6` must resolve under `$P/sysroot`; every `not
|
||||
found` line is a host package to `dnf install` (expected candidates on a
|
||||
minimal RHEL9: `gtk2`, `mesa-libGL`, `mesa-libGLU`, `libSM`, `libXxf86vm`,
|
||||
`libxkbcommon`). Plain `ldd` on the raw binary also works after the patch
|
||||
(it honours the new interpreter).
|
||||
|
||||
## Verifying the install
|
||||
|
||||
@@ -151,11 +201,16 @@ not to edit the hash:
|
||||
1. download the current zip and read its revision and hash:
|
||||
`unzip -p olex2-linux64.zip olex2/version.txt` → e.g. `SVN Revision No. 7800`,
|
||||
`sha256sum olex2-linux64.zip`;
|
||||
2. add `1.5-7800` under `versions:` (`relstage: unstable`) and
|
||||
2. check the new binaries' glibc need still fits the bundled 2.39:
|
||||
`unzip -p olex2-linux64.zip olex2/olex2c | strings | grep -o 'GLIBC_2\.[0-9]*' | sort -uV | tail -1`
|
||||
(and `GLIBCXX_3\.4\.[0-9]*` ≤ 3.4.33). If upstream moved past that, bump
|
||||
the three rpms in `urls:`/`shasums:` to a newer frozen Fedora release
|
||||
(kojipkgs `packages/glibc/<ver>/<rel>/x86_64/`, `packages/gcc/...`);
|
||||
3. add `1.5-7800` under `versions:` (`relstage: unstable`) and
|
||||
`olex2-1.5-7800-linux64.zip: <sha256>` under `shasums:` — the `urls:`
|
||||
entry needs no change (`${V_PKG}` = series dir, `${V}` = cache name);
|
||||
for a 1.6 series just use `1.6-<rev>` and the URL follows;
|
||||
3. build as above; promote to `stable` only after `olex2c` and `olex2`
|
||||
4. build as above; promote to `stable` only after `olex2c` and `olex2`
|
||||
have been exercised on the target host.
|
||||
|
||||
History: `1.5` (stable) is the older Ra/RHEL8 module built by the previous
|
||||
|
||||
+101
-9
@@ -8,13 +8,36 @@
|
||||
# olex2 GUI (wxWidgets) olex2c console/"headless" Olex2
|
||||
# unirun vendor auto-updater (NOT used here) start vendor launcher (NOT used here)
|
||||
# cctbx/ lib/ (private CPython 3.8 + libs) ilib/ util/ etc/ sample_data/ ...
|
||||
# Default pbuild::prep downloads the zip (urls: in files/config.yaml), checks
|
||||
# the pinned sha256 (shasums:) and copies it into SRC_DIR (unpacker: none).
|
||||
# configure unzips, install copies the vendor tree 1:1 into $PREFIX (Olex2's
|
||||
# BaseDir() is wherever the binaries sit) and adds $PREFIX/bin launchers.
|
||||
#
|
||||
# BUT: since 2026 OlexSys builds the Linux binaries on an Ubuntu 24.04-class
|
||||
# toolchain: olex2c/olex2/unirun/NoSpherA2/libopenblas/cctbx *.so need
|
||||
# GLIBC_2.38 + GLIBCXX_3.4.32, while RHEL9 has glibc 2.34 / GLIBCXX_3.4.29
|
||||
# (RHEL8: 2.28 / 3.4.25). A newer glibc cannot be supplied via LD_LIBRARY_PATH
|
||||
# (the dynamic loader is hard-wired into each ELF), so this recipe ships a
|
||||
# private glibc 2.39 + GCC 14 libstdc++/libgcc under $PREFIX/sysroot (frozen
|
||||
# Fedora 40 rpms from kojipkgs) and re-points the ELF executables at that
|
||||
# loader with patchelf (--set-interpreter + DT_RPATH). GTK2/X11/GL still come
|
||||
# from the host: older libs run fine on a newer glibc. The sysroot libc dir is
|
||||
# NEVER put on LD_LIBRARY_PATH - that would crash every system tool Olex2 spawns.
|
||||
#
|
||||
# Default pbuild::prep downloads every file (urls: in files/config.yaml),
|
||||
# checks the pinned sha256 (shasums:) and copies it into SRC_DIR (unpacker:
|
||||
# none). configure unpacks, install copies the vendor tree 1:1 into $PREFIX
|
||||
# (Olex2's BaseDir() is wherever the binaries sit) and adds $PREFIX/bin launchers.
|
||||
#
|
||||
# No errexit in modbuild hooks -> every critical step is die-guarded.
|
||||
|
||||
# files fetched by prep (names must match urls:/shasums: in files/config.yaml)
|
||||
OLEX2_SYSROOT_RPMS=(
|
||||
glibc-2.39-37.fc40.x86_64.rpm
|
||||
libstdc++-14.2.1-3.fc40.x86_64.rpm
|
||||
libgcc-14.2.1-3.fc40.x86_64.rpm
|
||||
)
|
||||
OLEX2_PATCHELF_TGZ="patchelf-0.18.0-x86_64.tar.gz"
|
||||
# ELF executables in the vendor tree that get the bundled loader (static ones,
|
||||
# e.g. hart, are detected and skipped)
|
||||
OLEX2_PATCH_EXES=(olex2c olex2 unirun NoSpherA2 hart_mpi)
|
||||
|
||||
pbuild::configure() {
|
||||
local -r zip="${SRC_DIR}/olex2-${V}-linux64.zip"
|
||||
[[ -s "${zip}" ]] || std::die 42 "olex2: ${zip} not found - prep did not fetch it. \
|
||||
@@ -28,6 +51,36 @@ Pre-stage the archive by hand as <distdir>/olex2-${V}-linux64.zip (see README) a
|
||||
[[ -f "${SRC_DIR}/olex2/olex2c" && -f "${SRC_DIR}/olex2/olex2" ]] || \
|
||||
std::die 42 "olex2: unexpected archive layout - expected ${SRC_DIR}/olex2/{olex2,olex2c}"
|
||||
rm -f "${zip}"
|
||||
|
||||
# --- private glibc 2.39 + libstdc++ 14 sysroot (Fedora 40 rpms) ----------
|
||||
command -v rpm2cpio >/dev/null && command -v cpio >/dev/null || \
|
||||
std::die 42 "olex2: need rpm2cpio and cpio on the build host (dnf install rpm cpio)"
|
||||
local -r sysroot="${SRC_DIR}/sysroot"
|
||||
local rpm
|
||||
rm -rf "${sysroot}"
|
||||
mkdir -p "${sysroot}"
|
||||
for rpm in "${OLEX2_SYSROOT_RPMS[@]}"; do
|
||||
[[ -s "${SRC_DIR}/${rpm}" ]] || std::die 42 "olex2: ${rpm} missing in SRC_DIR - prep did not fetch it"
|
||||
( cd "${sysroot}" && rpm2cpio "${SRC_DIR}/${rpm}" | cpio -idm --quiet ) || \
|
||||
std::die 42 "olex2: extracting ${rpm} failed"
|
||||
done
|
||||
local ld libc libdir
|
||||
ld="$(find "${sysroot}" -type f -name 'ld-linux-x86-64.so.2' -print -quit)"
|
||||
libc="$(find "${sysroot}" -type f -name 'libc.so.6' -print -quit)"
|
||||
[[ -n "${ld}" && -n "${libc}" ]] || std::die 42 "olex2: ld-linux-x86-64.so.2 / libc.so.6 not found in the extracted glibc rpm"
|
||||
libdir="$(dirname "${libc}")"
|
||||
[[ -e "${libdir}/libstdc++.so.6" && -e "${libdir}/libgcc_s.so.1" ]] || \
|
||||
std::die 42 "olex2: libstdc++.so.6 / libgcc_s.so.1 not next to libc.so.6 in ${libdir}"
|
||||
# the loader is static: it must run on any x86_64 host
|
||||
"${ld}" --version > "${SRC_DIR}/ldso.version" 2>&1 || \
|
||||
std::die 42 "olex2: the bundled ld.so does not run on this host"
|
||||
echo "olex2: bundled loader: $(head -n1 "${SRC_DIR}/ldso.version")"
|
||||
|
||||
# --- patchelf (static release binary) --------------------------------------
|
||||
[[ -s "${SRC_DIR}/${OLEX2_PATCHELF_TGZ}" ]] || std::die 42 "olex2: ${OLEX2_PATCHELF_TGZ} missing in SRC_DIR - prep did not fetch it"
|
||||
mkdir -p "${SRC_DIR}/patchelf"
|
||||
tar -xzf "${SRC_DIR}/${OLEX2_PATCHELF_TGZ}" -C "${SRC_DIR}/patchelf" || std::die 42 "olex2: unpacking patchelf failed"
|
||||
"${SRC_DIR}/patchelf/bin/patchelf" --version >/dev/null || std::die 42 "olex2: patchelf binary does not run on this host"
|
||||
}
|
||||
|
||||
pbuild::compile() {
|
||||
@@ -36,6 +89,7 @@ pbuild::compile() {
|
||||
|
||||
pbuild::install() {
|
||||
local -r src="${SRC_DIR}/olex2"
|
||||
local -r patchelf="${SRC_DIR}/patchelf/bin/patchelf"
|
||||
|
||||
# 1. vendor tree, flat into $PREFIX (= BaseDir). Slow on /opt/psi: 12k files.
|
||||
# NOT `cp -a`: on /opt/psi chown is refused, so -a ends with thousands of
|
||||
@@ -44,12 +98,17 @@ pbuild::install() {
|
||||
cp -r --preserve=mode,timestamps,links "${src}/." "${PREFIX}/" || \
|
||||
std::die 42 "olex2: copying the vendor tree into ${PREFIX} failed"
|
||||
|
||||
# 2. zip loses nothing, but make sure the ELF binaries are executable and
|
||||
# 2. private glibc/libstdc++ sysroot
|
||||
rm -rf "${PREFIX}/sysroot"
|
||||
cp -r --preserve=mode,timestamps,links "${SRC_DIR}/sysroot" "${PREFIX}/sysroot" || \
|
||||
std::die 42 "olex2: copying the sysroot into ${PREFIX} failed"
|
||||
|
||||
# 3. zip loses nothing, but make sure the ELF binaries are executable and
|
||||
# everything is world-readable on the shared install
|
||||
chmod 755 "${PREFIX}"/{olex2,olex2c,unirun,start,NoSpherA2,hart,hart_mpi} 2>/dev/null || true
|
||||
chmod -R a+rX "${PREFIX}" || true
|
||||
|
||||
# 3. never auto-update a shared, read-only install (vendor default is
|
||||
# 4. never auto-update a shared, read-only install (vendor default is
|
||||
# update=Always + ask_update=true, driven by unirun). Best effort - the
|
||||
# launchers never call unirun anyway.
|
||||
if [[ -f "${PREFIX}/usettings.dat" ]]; then
|
||||
@@ -57,7 +116,28 @@ pbuild::install() {
|
||||
"${PREFIX}/usettings.dat" || true
|
||||
fi
|
||||
|
||||
# 4. launchers: $PREFIX/bin/olex2 (GUI) and $PREFIX/bin/olex2c (console).
|
||||
# 5. re-point the ELF executables at the bundled loader. DT_RPATH (not
|
||||
# RUNPATH, hence --force-rpath) so that everything dlopen()ed later by the
|
||||
# embedded Python (cctbx *.so, lib-dynload, _ac7util) resolves libc,
|
||||
# libstdc++, libopenblas ... through the same list. Host dirs (/lib64)
|
||||
# follow via the loader's defaults + /etc/ld.so.cache.
|
||||
local ld libdir rpath exe
|
||||
ld="$(find "${PREFIX}/sysroot" -type f -name 'ld-linux-x86-64.so.2' -print -quit)"
|
||||
libdir="$(dirname "$(find "${PREFIX}/sysroot" -type f -name 'libc.so.6' -print -quit)")"
|
||||
[[ -x "${ld}" && -d "${libdir}" ]] || std::die 42 "olex2: sysroot loader/libdir not found under ${PREFIX}/sysroot"
|
||||
rpath="${libdir}:${PREFIX}/lib:${PREFIX}/ilib:${PREFIX}/cctbx/cctbx_build/lib:${PREFIX}:\$ORIGIN"
|
||||
for exe in "${OLEX2_PATCH_EXES[@]}"; do
|
||||
[[ -f "${PREFIX}/${exe}" ]] || continue
|
||||
if ! "${patchelf}" --print-interpreter "${PREFIX}/${exe}" >/dev/null 2>&1; then
|
||||
echo "olex2: ${exe} is statically linked - left untouched"
|
||||
continue
|
||||
fi
|
||||
"${patchelf}" --set-interpreter "${ld}" --force-rpath --set-rpath "${rpath}" "${PREFIX}/${exe}" || \
|
||||
std::die 42 "olex2: patchelf failed on ${exe}"
|
||||
echo "olex2: ${exe} -> interpreter ${ld}"
|
||||
done
|
||||
|
||||
# 6. launchers: $PREFIX/bin/olex2 (GUI) and $PREFIX/bin/olex2c (console).
|
||||
# Two copies of one script (it dispatches on basename $0, so no symlinks).
|
||||
# Only $PREFIX/bin goes on PATH - the raw binaries and the vendor
|
||||
# 'start' (auto-updater) stay off it.
|
||||
@@ -67,9 +147,21 @@ pbuild::install() {
|
||||
install -m 755 "${BUILDBLOCK_DIR}/files/olex2-launcher" "${PREFIX}/bin/olex2c" || \
|
||||
std::die 42 "olex2: installing bin/olex2c launcher failed"
|
||||
|
||||
# 5. what the modulefile / launchers rely on
|
||||
# 7. prove the patched olex2c resolves through the bundled glibc. Missing
|
||||
# HOST libs (gtk2, GL ...) are only a warning here: they must be
|
||||
# installed on the execution hosts, the build host may differ.
|
||||
"${ld}" --list "${PREFIX}/olex2c" > "${SRC_DIR}/olex2c.ldd" 2>&1 || \
|
||||
std::die 42 "olex2: bundled loader cannot resolve olex2c - see ${SRC_DIR}/olex2c.ldd"
|
||||
grep -q "${libdir}/libc.so.6" "${SRC_DIR}/olex2c.ldd" || \
|
||||
std::die 42 "olex2: olex2c does not pick up the bundled glibc (see ${SRC_DIR}/olex2c.ldd) - patchelf step broken"
|
||||
if grep -q 'not found' "${SRC_DIR}/olex2c.ldd"; then
|
||||
echo "olex2: WARNING - host libraries missing on THIS host; dnf install them on the execution hosts:"
|
||||
grep 'not found' "${SRC_DIR}/olex2c.ldd"
|
||||
fi
|
||||
|
||||
# 8. what the modulefile / launchers rely on
|
||||
local f
|
||||
for f in olex2 olex2c cctbx/cctbx_build/lib lib/libpython3.8.so.1.0 lib/python3.8 util/pyUtil/initpy.py bin/olex2c; do
|
||||
for f in olex2 olex2c cctbx/cctbx_build/lib lib/libpython3.8.so.1.0 lib/python3.8 util/pyUtil/initpy.py bin/olex2c sysroot; do
|
||||
[[ -e "${PREFIX}/${f}" ]] || std::die 42 "olex2: ${PREFIX}/${f} missing after install - module would be broken"
|
||||
done
|
||||
echo "olex2: installed upstream build '$(cat "${PREFIX}/version.txt" 2>/dev/null)' (tag $(cat "${PREFIX}/olex2.tag" 2>/dev/null))"
|
||||
|
||||
+24
-2
@@ -15,21 +15,43 @@ olex2:
|
||||
- url: https://secure.olex2.org/olex2-distro/${V_PKG}/olex2-linux64.zip
|
||||
name: olex2-${V}-linux64.zip
|
||||
unpacker: none # build/configure unzips (zip is not tar/7z)
|
||||
# Private glibc 2.39 + GCC 14 libstdc++/libgcc for $PREFIX/sysroot: the
|
||||
# upstream binaries need GLIBC_2.38 / GLIBCXX_3.4.32, RHEL9 has 2.34 /
|
||||
# 3.4.29. Frozen Fedora 40 builds from kojipkgs (permanent build archive,
|
||||
# URLs never move). build/configure extracts them with rpm2cpio|cpio.
|
||||
- url: https://kojipkgs.fedoraproject.org/packages/glibc/2.39/37.fc40/x86_64/glibc-2.39-37.fc40.x86_64.rpm
|
||||
name: glibc-2.39-37.fc40.x86_64.rpm
|
||||
unpacker: none
|
||||
- url: https://kojipkgs.fedoraproject.org/packages/gcc/14.2.1/3.fc40/x86_64/libstdc++-14.2.1-3.fc40.x86_64.rpm
|
||||
name: libstdc++-14.2.1-3.fc40.x86_64.rpm
|
||||
unpacker: none
|
||||
- url: https://kojipkgs.fedoraproject.org/packages/gcc/14.2.1/3.fc40/x86_64/libgcc-14.2.1-3.fc40.x86_64.rpm
|
||||
name: libgcc-14.2.1-3.fc40.x86_64.rpm
|
||||
unpacker: none
|
||||
# static patchelf: re-points the ELF executables at the bundled loader
|
||||
- url: https://github.com/NixOS/patchelf/releases/download/0.18.0/patchelf-0.18.0-x86_64.tar.gz
|
||||
name: patchelf-0.18.0-x86_64.tar.gz
|
||||
unpacker: none
|
||||
shasums:
|
||||
# sha256 of the 2026-09-08 drop of 1.5/olex2-linux64.zip (255161849 bytes,
|
||||
# upstream MD5 b2d4a696854849ae586b96efd0b084ae, version.txt "SVN Revision No. 7665").
|
||||
# A mismatch after a future upstream refresh is EXPECTED: add a new version
|
||||
# (README "Adding a new version") instead of editing this line.
|
||||
olex2-1.5-7665-linux64.zip: a747d2a12d764448960cd45c2dbc8c57beb0a5403908abbf318e4c8e04dbf872
|
||||
glibc-2.39-37.fc40.x86_64.rpm: 3976fe456c25eb15a8eea4fd57140a2d9b0084ef721960b510e02872c4fe5cc9
|
||||
libstdc++-14.2.1-3.fc40.x86_64.rpm: 6b6c07bef7ecf7af4a4042bc53eca6c188e07567b3ae710568495a5ca89ccede
|
||||
libgcc-14.2.1-3.fc40.x86_64.rpm: 6d84546060cf58bd1ea2456a0ac52659bf9670782258b664dfc0aa046ff3a50d
|
||||
patchelf-0.18.0-x86_64.tar.gz: ce84f2447fb7a8679e58bc54a20dc2b01b37b5802e12c57eece772a6f14bf3f0
|
||||
versions:
|
||||
# 1.5: legacy Ra/RHEL8 module built by the previous recipe from a
|
||||
# hand-downloaded olex2-linux64.zip committed next to build. Kept so the
|
||||
# hand-downloaded olex2-linux64.zip placed next to build. Kept so the
|
||||
# installed module stays listed; do NOT rebuild it with this recipe
|
||||
# (no shasum, filename olex2-1.5-linux64.zip would fetch today's rolling zip).
|
||||
1.5:
|
||||
config:
|
||||
relstage: stable
|
||||
# Current snapshot, RHEL9 target: GUI + olex2c from the same archive.
|
||||
# Current snapshot, RHEL9 target: GUI + olex2c from the same archive,
|
||||
# running on the bundled glibc 2.39 sysroot.
|
||||
1.5-7665:
|
||||
config:
|
||||
relstage: unstable
|
||||
@@ -23,6 +23,15 @@ case "$exe" in
|
||||
esac
|
||||
[[ -x "$base/$exe" ]] || { echo "olex2-launcher: $base/$exe is missing or not executable (broken install?)" >&2; exit 1; }
|
||||
|
||||
# --- bundled glibc ---------------------------------------------------------
|
||||
# The executables were patchelf'ed at build time to use $base/sysroot's
|
||||
# ld.so + libc + libstdc++ via DT_RPATH. Nothing to export for that, and
|
||||
# NEVER add $base/sysroot/... to LD_LIBRARY_PATH: every system tool Olex2
|
||||
# spawns (sh, shelxl, editors) would then load the foreign libc and crash.
|
||||
# The bundled glibc has no locale archive -> use its built-in C.UTF-8.
|
||||
export LANG=C.UTF-8
|
||||
export LC_ALL=C.UTF-8
|
||||
|
||||
# --- vendor 'start' environment ------------------------------------------
|
||||
export OLEX2_CCTBX_DIR="$base/cctbx"
|
||||
# cctbx sets signal handlers for FPE and does not handle them
|
||||
|
||||
Reference in new issue
Block a user