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.
olex2
Olex2 — open-source (BSD) small-molecule crystal structure solution, refinement and analysis (olex2.refine / ShelX front-end, built on cctbx/smtbx). This module provides both the GUI and the console build:
| launcher | what it is |
|---|---|
olex2 |
wxWidgets GUI (needs an X display) |
olex2c |
console / "headless" Olex2 — same engine, no GUI, scriptable |
- Upstream: https://www.olexsys.org/olex2 — install notes: https://www.olexsys.org/olex2/docs/getting-started/installing-olex2/
- Source: https://github.com/pcxod/olex2 (C++ engine; the HTML GUI lives in
svn.olex2.org/olex2-gui) — not used, see "Why the binary archive" - License: BSD (https://www.olexsys.org/olex2/docs/getting-started/installing-olex2/open-source/)
- Download server: https://secure.olex2.org/olex2-distro/ (mirror http://www2.olex2.org/olex2-distro/)
How it is built
Upstream (install notes, "Linux"): "We do not provide installers for Linux
– and provide zip files instead (Use the 'start' bash script to launch
Olex2)" and "Nothing needs to be compiled". The official
olex2-distro/1.5/olex2-linux64.zip (255 MB, ~1 GB unpacked) already
contains everything (verified by listing the archive, 2026-10-16):
olex2/olex2 GUI binary olex2/olex2c console binary (24 MB)
olex2/unirun vendor auto-updater olex2/start vendor launcher (runs unirun, then olex2)
olex2/cctbx/ cctbx_build + cctbx_sources olex2/lib/ private CPython 3.8 + libpython, openblas, ssl, png, ...
olex2/ilib/ olex2/util/pyUtil/ olex2/etc/ olex2/sample_data/ NoSpherA2, hart, hart_mpi ...
The recipe (build):
- default
pbuild::prepdownloads the zip perurls:infiles/config.yamlinto the distfiles cache asolex2-<version>-linux64.zip, verifies the pinned sha256 and copies it toSRC_DIR(unpacker: none); configurerunsunzip -t(truncated-download guard) and unzips;installcopies the vendor tree flat into$PREFIX— Olex2 derives itsBaseDir()from the binary location, so the layout must stay as shipped — fixes modes, switchesusettings.dattoupdate=Never, and installsfiles/olex2-launchertwice as$PREFIX/bin/olex2and$PREFIX/bin/olex2c. Only$PREFIX/bingoes onPATH.
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 execs the binary.
unirun is never run: /opt/psi/MX is shared and read-only, updates are
done by building a new module version.
Why the binary archive and not a source build
The user-facing "open source" route is this archive: Olex2 is BSD and the
official binaries are the open-source build. Compiling from
https://github.com/pcxod/olex2 is not a practical module recipe: the repo
builds only olex2 (GUI, wxWidgets mandatory) and unirun — there is no
olex2c target in its CMakeLists/SConstruct/Makefile — the HTML GUI is in a
separate SVN, and the matching cctbx/smtbx build is not published. Its own
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.
Building on Ra / RHEL9
module use unstable && module load modbuild/2.1.3
cd olex2
modbuild build \
--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.
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
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:
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
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:
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
Verifying the install
which olex2c # -> /opt/psi/MX/olex2/1.5-7665/bin/olex2c
which olex2 # -> /opt/psi/MX/olex2/1.5-7665/bin/olex2
cat /opt/psi/MX/olex2/1.5-7665/version.txt # SVN Revision No. 7665
# console: starts, loads a shipped sample, refines, exits (writes to ~/.olex2
# and to a scratch copy of the sample - run it in a scratch dir)
cd $(mktemp -d) && cp /opt/psi/MX/olex2/1.5-7665/sample_data/sucrose/* .
olex2c # interactive prompt; then type:
# reap sucrose.res
# refine 4
# exit
# GUI (needs X / x2go / NoMachine session):
olex2
Scripting olex2c: it reads commands from stdin, so a batch job can do
printf 'reap %s\nrefine 10\nexit\n' x.ins | olex2c (to be confirmed on the
first RHEL9 test — the Windows olex2c.exe is used this way by CrysAlisPro
and the upstream NoSpherA2 release tests). The headless engine loads
macrox.xld instead of macro.xld; GUI-only python calls print
"not available in Headless Olex" rather than fail.
First-start notes: Olex2 keeps user data in ~/.olex2 (DataDir), copies
sample data there and may try to delete runonce.* markers in BaseDir
(read-only for users — harmless). The vendor start and unirun remain
under $PREFIX but are intentionally not on PATH; do not run them against
the shared install.
Adding a new version
1.5/olex2-linux64.zip is a rolling file — OlexSys replaces it in place
(check Modified on https://secure.olex2.org/olex2-distro/1.5/, or the
ALPHA/BETA series folders). The sha256 pinned in files/config.yaml will
therefore fail against a newer drop; that is the signal to add a version,
not to edit the hash:
- 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; - add
1.5-7800underversions:(relstage: unstable) andolex2-1.5-7800-linux64.zip: <sha256>undershasums:— theurls:entry needs no change (${V_PKG}= series dir,${V}= cache name); for a 1.6 series just use1.6-<rev>and the URL follows; - build as above; promote to
stableonly afterolex2candolex2have been exercised on the target host.
History: 1.5 (stable) is the older Ra/RHEL8 module built by the previous
recipe from a hand-downloaded olex2-linux64.zip placed next to build
(never committed, *.zip is gitignored); it is kept in config.yaml so
the installed module stays listed. Do not rebuild it with this recipe.