# EESSI hackathon Jan'22 - installing software on top of EESSI
Live collaborative notes for this task during the 2nd EESSI hackathon; see also general notes at https://hackmd.io/vSOfDj-SQSmYglhxz_R4hg
Notes from Dec'21 hackathon: https://github.com/EESSI/meetings/wiki/EESSI-hackathon-Dec'21
Zoom for this task: https://uib.zoom.us/j/63932793319?pwd=Ry9BQ3VUaHcwTncwSFFrdU1PWnF3QT09
## Custom GCCcore with RPATH wrappers
Prepare environment (e.g. w/ EESSI 2021.06)
```bash
source /cvmfs/pilot.eessi-hpc.org/2021.06/init/bash
module load EasyBuild/4.4.1
```
Notes (Kenneth):
* Make sure that EasyBuild is properly configured (by sourcing `configure_easybuild` script from https://github.com/EESSI/software-layer/)
* note: both `$WORKDIR` and `$EPREFIX` environment variables must be defined!
* Use fast local disk for build directories: `export EASYBUILD_BUILDPATH=/tmp/$USER/easybuild/build`
Build custom GCCcore with rpath wrapper scripts in place:
```bash
export EASYBUILD_PREFIX=$HOME
eb GCCcore-9.3.0.eb --include-easyblocks-from-pr 2638 --force --try-amend=add_rpath_wrappers=True
```
Which picks up the GCCcore-9.3.0.eb from https://github.com/easybuilders/easybuild-easyblocks/pull/2638/files#diff-a2355c6aa1836d1f465436c868adde40651d28cb2bd59cd0e201614fe3b94fe9
To use this custom GCC core module:
```bash
module use $HOME/modules/all
module avail GCCcore/9.3.0
module load GCCcore/9.3.0
```
Now `which gcc` points to a wrapper script (also for `ld` and other commands) that automagically puts the right RPATHs in place when compiling something.
```bash
$ gcc hello_lorld.cxx -o hello_world_withrpath
$ readelf -d hello_world_withrpath
```
### Centrally install custom `GCCcore/9.3.0` that includes RPATH wrapper scripts on CitC cluster
```
source /cvmfs/pilot.eessi-hpc.org/versions/2021.12/init/bash
module use /mnt/shared/02_software_on_top/easybuild/modules/all
module load foss/2020a
which gcc
file $(which gcc)
```
```
$ gcc hello_world.c -o hello_world
/mnt/shared/02_software_on_top/easybuild/software/GCCcore/9.3.0/bin/rpath_wrappers/gcc: line 40: /tmp/eb-eai87q5k/rpath_wrapper_gcc.log: No such file or directory
```
Fix is to create expected directory:
```
$ mkdir -p /tmp/eb-eai87q5k
$ gcc hello_world.c -o hello_world
$ readelf -d hello_world
```
## Subtasks
- https://github.com/easybuilders/easybuild-framework/issues/3918
- Kenneth: module_generator.py
- Martin: modify prepare_rpath_wrappers() in toolchain.py of EasyBuild framework
## To Figure Out
- Install `ld` wrappers with `binutils` instead?
- Put everything in `GCC (= binutils + GCCcore)`?
- How to deal with rpath wrappers for other compilers? (e.g. intel) => hints towards GCCcore or binutils
- Is it enough to just install ld wrappers? (Martin will look into this)
- in EESSI context:
- we use `binutils` from compat layer (not installed with EasyBuild)
- if we want to wrap `ld`, it would have to be done either in `GCCcore`, or in `GCC`
- this implies more general support is required for installing RPATH wrappers (not just through `GCCcore` easyblock)?
## Building Software on top of EESSI (ie not using EasyBuild)
Notes (Frank Everdij):
Use EESSI 2021.12 stack.
Pick suitable software package candidate:
- LAMMPS is chosen. It has fairly trivial dependencies and it's missing from the current EESSI stack
- Also serves as a test for OpenMPI functionality when not using EasyBuild
### LAMMPS Development and Runtime issues
The naive way of building LAMMPS:
```
wget https://download.lammps.org/tars/lammps-stable.tar.gz
tar zxvf lammps-stable.tar.gz
cd lammps-29Sep2021
source /cvmfs/pilot.eessi-hpc.org/versions/2021.12/init/bash
module load Eigen
module load OpenMPI
module load FFTW
module load FFmpeg
mkdir build && cd build && cmake -C ../cmake/presets/most.cmake ../cmake -DCMAKE_Fortran_COMPILER=gfortran -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=~/lammps
make -j8 all >& make.log &
make install
```
This produces a LAMMPS `lmp` binary in `~/lammps` with missing `libfftw3.so` RPATH. The LAMMPS CMakeLists.txt does not properly address this RPATH issue:
```
[frankeverdij@mgmt bin]$ ldd lmp | grep fftw
libfftw3.so.3 => not found
libfftw3_omp.so.3 => not found
```
Moreover, this does not take advantage of the recommended development environment already in EESSI.
A fix for this is to use a development stack with RPATH wrappers enabled:
```
source /cvmfs/pilot.eessi-hpc.org/versions/2021.12/init/bash
module use /mnt/shared/02_software_on_top/easybuild/modules/all
module load foss/2020a
which gcc
[EESSI pilot 2021.12] $ which gcc
/mnt/shared/02_software_on_top/easybuild/software/GCCcore/9.3.0/bin/rpath_wrappers/gcc
```
This replaces the gcc/g++/ld commands with the wrapper functionality of EasyBuild. The result is a correct(ed) RPATH and the linker now finds the correct library:
```
[frankeverdij@fair-mastodon-c5d-2xlarge-0001 bin]$ ldd lmp | grep fftw
libfftw3.so.3 => /cvmfs/pilot.eessi-hpc.org/versions/2021.12/software/linux/x86_64/intel/skylake_avx512/software/FFTW/3.3.8-gompi-2020a/lib/../lib64/libfftw3.so.3 (0x00007fde2e39d000)
libfftw3_omp.so.3 => /cvmfs/pilot.eessi-hpc.org/versions/2021.12/software/linux/x86_64/intel/skylake_avx512/software/FFTW/3.3.8-gompi-2020a/lib/../lib64/libfftw3_omp.so.3 (0x00007fde3073c000)
```
The used buildscript and example slurm-job can be found in the hackathon repo:
https://github.com/EESSI/hackathons/tree/02_software_on_top/2022-01/02_software_on_top
### Other issues found
- Don't forget the FOSS module for your development! CMake needs to be loaded separately. Perhaps this can be included in future FOSS modules.
- The temporary wrapper is currently built for a specific GCCCore which is not the default. If you load library modules and assume the default version, these will override the GCCcore module with a newer (10) version and your wrappers aren't there anymore.
- The LAMMPS install script also wants to change the `lmp` executable RPATH setting to remove the build directory. This may not be caught with wrapper scripts.
### To Do
- Add RPATH wrapper functionality into the EESSI to make bare EESSI development builds easier without resorting to a custom GCCcore.
- Alternatively a script can be made with `readelf` `patchelf` `ldd` and `pkgconf` to fix RPATH's in binaries and libraries.
### GetFEM build and runtime
GetFEM is chosen as an example of a `configure;make;make install` build. It produces a python module with C++ library.
The issue when building this package is that it finds the compatibility compilers first, even if one loads the wrapper script.
When loading the wrapper scripts and then run `configure` it finds the wrappers, compiles the application but the linker still uses the compat `ld` binary
```
[EESSI pilot 2021.12] $ which gcc
/mnt/shared/02_software_on_top/easybuild/software/GCCcore/9.3.0/bin/rpath_wrappers/gcc
```
and building with:
```
./configure --prefix=$HOME/getfem --enable-shared --enable-python --enable-metis --with-blas=`pkgconf --variable=libdir openblas`/libopenblas.so
```
gives
```
checking for ld used by gcc... /cvmfs/pilot.eessi-hpc.org/versions/2021.12/compat/linux/x86_64/usr/x86_64-pc-linux-gnu/bin/ld
```
which results in a `lib/libgetfem.so` library with mixed compat and software RPATH's. The library `lib/python3.8/site-packages/getfem/_getfem.cpython-38-x86_64-linux-gnu.s` seems to have the correct path to libopenblas.so
The example program in https://github.com/EESSI/hackathons/tree/02_software_on_top/2022-01/02_software_on_top/GetFEM_test_cantilever can be called with `python3 - cantilever` and produces point displacement output. This is not a thorough test however and i haven't checked the result, but it serves as an example of a `configure` build script together with `libtool`