- sysroot += libwebp, libdeflate, libtiff 4.6 (+libjpeg-turbo, jbigkit-libs,
liblerc): from a NEEDED scan of every ELF object in the zip these are the
libs RHEL8/9 lack at the required version (PIL _imaging, vendor
libtiff.so.5, GUI binary libtiff.so.6).
- install step 9: run olex2c once as the owner so Olex2 writes
cctbx/cctbx_build/libtbx_env into the shared prefix (its first-start cold
start; users cannot write there). The upstream fable/sdrive.f error on
that run is expected and documented: libtbx_env is pickled before it.
- install step 10: second start + refine of the sucrose sample; die if
cctbx is still reported broken, warn on other errors.
- launcher: PYTHONNOUSERSITE=1.
olex2c needs libreadline.so.8 (RHEL8 has .so.7, vendor lib/ only .so.6),
so the Ra build node could not complete the post-install ld.so --list and
the guard aborted. Add Fedora 40 readline-8.2 to the sysroot rpms (needs
only the host libtinfo.so.6) and make step 7 print the listing, warn on
host libs missing on the build node, and die only on a genuine
patchelf/sysroot failure.
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.
First build failed in install: cp -a onto /opt/psi logs 'failed to
preserve ownership ... Permission denied' for every file (chown refused)
and exits non-zero, which tripped the die-guard although the copy itself
was fine. Use cp -r --preserve=mode,timestamps,links instead. Record the
pitfall in the new-module skill guardrails.
The official olex2-linux64.zip already ships both the GUI (olex2) and the
console build (olex2c) plus cctbx and a private CPython 3.8, so nothing is
compiled. Default prep downloads + sha256-verifies the zip (rolling file,
version carries the upstream SVN revision), install copies the vendor tree
flat into PREFIX and adds bin/olex2 + bin/olex2c launchers that reproduce
the vendor start env without running the unirun auto-updater.
Both tarballs unpack stripped into SRC_DIR; glm unpacked last and its
CMakeLists.txt shadowed pymol's. setup.py's cmake-based build_ext then
configured glm instead of pymol, built glm's test suite successfully
(372 .o, ~1min, exit 0) and produced a pure-python wheel with no error.
- config.yaml: glm url now FIRST so pymol's top-level files win
- build: guard that SRC_DIR/CMakeLists.txt is pymol's (TARGET_NAME)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Upstream documents 'pip install --no-build-isolation .'. With default
build isolation the wheel builds in an isolated env upstream never
tests and comes out pure-python (no _cmd.so) without any error - the
root cause of the ModuleNotFoundError: pymol._cmd at runtime.
setuptools+numpy now pre-installed into the venv as build deps.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two cache layers kept resurrecting a pure-python wheel without _cmd.so:
- modbuild -f re-untars over the old src dir, leaving a stale build/
tree from a half-failed compile; setup.py packs it as-is
- uv's built-wheel cache (in UV_CACHE_DIR, not ~/.cache/uv) then serves
that wheel on every rebuild (Prepared in ~550ms = no compile)
rm -rf $SRC_DIR/build in configure + --no-cache on the pymol install
kill both permanently.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
uv registers the wheel as pymol==3.1.0, so 'uv cache clean
pymol-open-source' is a no-op and the poisoned pure-python wheel
keeps being reinstalled from cache (Prepared in 537ms = no compile).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Launcher existed while compiled ext was missing (partial compile ->
pure-python wheel installed from poisoned uv cache). Import pymol._cmd
at install time so a broken build dies in modbuild, not at runtime.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Skill (local + repo copy): --tmpdir/--distdir now part of the standard
recipe (never write big files to /var/tmp — small and shared on the
login node), env-contamination and slow-shared-storage guardrails
added, ccp4 archetype 5b updated to the wget --continue + gzip -t prep
that is actually in ccp4/build.
Main README: agent section notes the skill can be buggy (use with
caution, corrections welcome, reading along is a good way to learn) and
that new software or a new download site needs the vendor install page
given as context; /var/tmp warning made explicit here and in
ccp4/README.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Main README: clone/SSH/branching quickstart with full /das paths,
--tmpdir/--distdir as part of the standard build command (do not fill
/var/tmp or $HOME) with cleanup for defaults, tips deduplicated against
module READMEs, old-system references removed, resource links and
tutorial acknowledgements added.
Module READMEs: purge outdated recipes repo-wide — Pmodules/1.1.20 and
2.0.0 plus ./build replaced by modbuild/2.1.3 invocations; the cctbx
unbound-variable fix moved from the main README into phenix and DIALS
READMEs where it belongs.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Refresh to modbuild 2.1.3 (no build subcommand, real flag list, no
--dry-run/--check-mode), document the --tmpdir/--distdir /das recipe,
and collect the lessons from the ccp4 build: no errexit in hooks,
pipefail vs yes|, partial-download reuse, env contamination (module
purge + reload modbuild), slow shared-storage installs. The new-module
skill (SKILL.md + REFERENCE.md) now lives in .claude/skills/new-module
so Claude Code auto-discovers it and other agents can be pointed at the
same files.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The ~/.Pmodules/Pmodules.yaml route did not reliably set download_dir,
so the maintained recipe now passes both dirs on the command line;
readers must adapt the p-group path to their own.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Byte-compiling the bundled Python env writes thousands of .pyc files on
network storage; whole install budget on Ra is about an hour.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Untarring 3.7 GB into ~15-20 GB of small files on shared /opt/psi takes
10-30 min silently; documented so nobody kills a healthy build.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Builtin curl in default prep has no retry/resume: an interrupted 3.7 GB
download restarts from zero and leaves a partial file that prep reuses
silently. Custom pbuild::prep resumes with wget --continue and gates the
build on gzip -t, so a truncated tarball can neither be reused nor
require a full re-download. urls: dropped from config.yaml (unused with
custom prep); install untars straight from the distfiles cache instead
of a pointless 3.7 GB copy via SRC_DIR.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
First Ra run "succeeded" while broken: modbuild has no errexit in hooks,
so a truncated cached tarball (gzip EOF) and a wrong hardcoded top dir
(tarball unpacks to ccp4-9, not ccp4-9.0) scrolled by and the modulefile
got installed anyway. Every critical step now ends the build via
std::die, the top dir is globbed, and install verifies ccp4.setup-sh
exists before finishing. README documents the recovery (rm partial
tarball from distfiles, --clean-install).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>