I’m using Root 6.36.10 in an environment compiled with Spack, so LD_LIBRARY_PATH is empty but ROOT_LIBRARY_DIR correctly dontains the path of the lib/ folder of the environment. When trying to load a dynamic library from the shell I get:
# echo $LD_LIBRARY_PATH
# echo $ROOT_LIBRARY_PATH
/software/spack/var/spack/environments/gseagen/.spack-env/view/lib/root:/software/spack/var/spack/environments/gseagen/.spack-env/view/lib64:/software/spack/var/spack/environments/gseagen/.spack-env/view/lib
# root
------------------------------------------------------------------
| Welcome to ROOT 6.36.10 https://root.cern |
| (c) 1995-2025, The ROOT Team; conception: R. Brun, F. Rademakers |
| Built for linuxx8664gcc on Oct 16 2026, 09:39:39 |
| From tags/6-36-10@6-36-10 |
| With g++ (Spack GCC) 15.2.0 |
| Try '.help'/'.?', '.demo', '.license', '.credits', '.quit'/'.q' |
------------------------------------------------------------------
root [0] .L lib/libGPhQELEG-3.06.02.so
cling::DynamicLibraryManager::loadLibrary(): /software/install/linux-x86_64_v3/genie-3.6.2-uixeqzr6zjwsgzhqshqsquu2kzy2gqo2/lib/libGPhQELEG-3.06.02.so: undefined symbol: _ZTIN5genie22KineGeneratorWithCacheE
If I set the lib/ libraries to `LD_LIBRARY_PATH it works instead:
# export LD_LIBRARY_PATH=$ROOT_LIBRARY_PATH
# root
------------------------------------------------------------------
| Welcome to ROOT 6.36.10 https://root.cern |
| (c) 1995-2025, The ROOT Team; conception: R. Brun, F. Rademakers |
| Built for linuxx8664gcc on Oct 16 2026, 09:39:39 |
| From tags/6-36-10@6-36-10 |
| With g++ (Spack GCC) 15.2.0 |
| Try '.help'/'.?', '.demo', '.license', '.credits', '.quit'/'.q' |
------------------------------------------------------------------
root [0] .L lib/libGPhQELEG-3.06.02.so
root [1]
According to this post I initially thought that the two variables play the same role for Cling, with the Root-specific one available to avoid potential side effects with other applications using LD_LIBRARY_PATH, but my tests show that it’s not the case.
So what are the differences and the intended usage withing Cling of the two variables? Thanks.
ROOT will search for some requested shared library in the “ROOT_LIBRARY_PATH”. Still, this variable will NOT be used by the dynamic linker to find and load other shared libraries that your requested shared library depends on. The dynamic linker will only see shared libraries in the “LD_LIBRARY_PATH” (and “RPATH” and “RUNPATH” set in your requested shared library, of course).
Sorry, ROOT_LIBRARY_DIR was a mistake and I always meant ROOT_LIBRARY_PATH. I checked your answer and it makes sense, except for one thing. In he following, contrary to the first post, I did everything outside a spack environment, so env variables and RPATHs coincide.
The library I am trying to load is in a folder included in ROOT_LIBRARY_PATH, and it has RPATHS for all the folders containing its dependency libraries, including the one defining the missing symbol Cling complains about:
From the above you can see that the library I’m trying to load and the one containing the missing symbol are in the same folder. Being LD_LIBRARY_PATH undefined Cling starts loading the first looking in ROOT_LIBRARY_PATH, and then ld.so should look at its RPATH to load the second. From the second to last instruction above you can see that the RPATH actually contains the folder containing all the libraries involved, but still Cling fails. The only way I found to make it work is to add the folder to LD_LIBRARY_PATH.
I might have not understood your explanation, but as far as I did it does not match with the above results.
It looks like your “libGPhQELEG” was NOT linked against your “libGPhCmn” (which provides the “typeinfo for genie::KineGeneratorWithCache”), so the dynamic linker does not know that it needs to load it, too.
Try: “ldd $MYLIBFOLDER/libGPhQELEG-3.06.02.so”
I think you have the required files “$MYLIBFOLDER/*.pcm” (and/or “*.rootmap”). ROOT will find them only if your “$MYLIBFOLDER” is in your “LD_LIBRARY_PATH” (“ROOT_LIBRARY_PATH” is not sufficient in this case, as far as I know).
@pcanal@Danilo It seems to me that it would be a good idea to have ROOT search for the “*.pcm” and “*.rootmap” files in the directories specified by the “ROOT_LIBRARY_PATH” (in addition to the “LD_LIBRARY_PATH”).
Thank you, now I think I understand. Effectively these libraries I’m using have not been linked against each other (it’s a 3rd-party software). This poses another more subtle problem related to spack: I can fix the library loading issue by adding the needed folder to LD_LIBRARY_PATH, but in this way when I activate a spack environment containing that library LD_LIBRARY_PATH will be set to the lib/ folder of the environment which contains a load of packages, in particular also some equivalent of the system packages which now will be used by all the programs, not just the spack-built ones, instead of the system-installed ones. This already generates errors in my system, how can I circumvent this?
I am not a Spack expert (maybe you need to talk to the authors of the “gseagen view”).
From what you write, it seems to me that you only need to add this single (“GENIE” related) directory to the “LD_LIBRARY_PATH”, so maybe you could initialize your Spack “view” first and then modify this variable.
I remember cases where I was unable to run “vi” when some “additional” environment was initialized.
In such “problematic” cases, I always open a separate terminal and initialize the environment there. And then in this terminal, I only work with the utilities specific to this environment (other actions are performed in another “standard” terminal).