Recently ran into an issue when fulfilling library dependencies using Environment Modules for a user who wanted to install an R package inside the RStudio interactive app (running via singularity container).
Not sure if this should go as far as being up-streamed but I imagine others will run into this issue so I want to document my fix.
Users Original Issue:
User wanted to install the ‘sf’ R package.
Dependencies for ‘sf’:
C++11, GDAL (>= 2.0.1), GEOS (>= 3.4.0), PROJ (>= 4.8.0)
but let’s assume C++ is covered.
Normal process for user to install R package:
We have R installed as a module, as well as those dependencies so user would do:
module add R/[rversion] gdal/[gdalversion] proj/[projversion] …etc.
Then in an R cli, just run: `install.packages(“sf”)
The ‘sf’ package is smart enough (unlike some R packages) to look down the standard Env paths to find libs, c headers and bins. This means that for those dependencies, because the custom install path is pre-pended to LD_LIBRARY_PATH, CPATH, etc. R can compile ‘sf’ successfully. (Nothing ground-breaking here)
Issue I ran into
Problem comes when trying to install from the RStudio app which is after-all running in the Singularity Container environment.
I think that by default, if you use the OSC example RStudio app, the PATH and LD_LIBRARY_PATH variables get passed into the container during run time. This often fulfills many library dependencies that are Environment Modules because a
module add [dependency] that is placed in the
setup_env function in
$RSTUDIOAPPHOME/template/script.sh.erb will load the module into the environment and the updated LD_LIBRARY_PATH will get propagated to the container.
If you have a dependency that fulfills c headers, like gdal in my case, you would prepend the
include dir for the module to CPATH. However, this is an issue with in the singularity container because CPATH does not get propagated to the container environment.
My failed solution:
Casting a wide net, I tried setting
SINGULARITYENV_... variables for all of the Env variables I would need in the container. I added the following to the
setup_env function at the beginning of
module add ..... export SINGULARITYENV_PATH="$PATH" export SINGULARITYENV_CPATH="$CPATH" export SINGULARITYENV_LIBRARY_PATH="$LIBRARY_PATH" export SINGULARITYENV_LD_LIBRARY_PATH="$LD_LIBRARY_PATH"
but no luck.
I noticed that there is a wrapper shell script for the rsession command that actually runs, captured in the variable RSESSION_WRAPPER_FILE and eventually saved, then run as rsession.sh.
Seeing that the rsession.log file variable is being set there, I added:
export CPATH="$CPATH" export LIBRARY_PATH="$LIBRARY_PATH"
This takes the CPATH and LIBRARY_PATH variables from the environment in which the
module add's are being done and cements them into the wrapper script where the rsession runs from, effectively propagating the variables into the container.
Note: I left out PATH and LD_LIBRARY_PATH because those are already being successfully passed into the container.
I hope all of this makes sense. Please let me know if I put this post in the wrong place!