Error while loading shared libraries

From Planets
Revision as of 21:09, 25 May 2023 by Emillour (talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

The symptoms

If you get a message of the likes of

./gcm_32x32x15_phystd_seq.e: error while loading shared libraries: libgfortran.so.4: cannot open shared object file: No such file or directory

or

./gcm_32x32x15_phystd_seq.e: error while loading shared libraries: libnetcdff.so.5: cannot open shared object file: No such file or directory

or

./gcm_32x32x15_phystd_seq.e: error while loading shared libraries: libmpi.so.40: cannot open shared object file: No such file or directory

etc.

This is because your executable was build with dynamic libraries (the default nowadays) and that these are not found at run time. You should therefore ensure that you have the same environment setup when you run the model than when it was compiled. In practice this essentially means that you should source the arch.env file that was used to compile the model before running it. e.g.:

source ../LMDZ.COMMON/arch.env
./gcm_32x32x15_phystd_seq.e > gcm.out 2>&1

Additional comments (mostly for experts)

the ldd command

To find out if an executable knows where to find all the libraries it will need, just ask! Using the ldd command:

ldd gcm_32x32x15_phystd_seq.e

which will return a list of the likes of:

	linux-vdso.so.1 =>  (0x00007ffd67df3000)
	libblas.so.3 => /lib64/libblas.so.3 (0x00002b76b6116000)
	liblapack.so.3 => /lib64/liblapack.so.3 (0x00002b76b636f000)
...

If a library is missing, this is mentioned there, e.g.:

	libnetcdff.so.5 => not found

the LD_LIBRARY_PATH environment variable

Apart from the default system directories (/lib64/, /usr/lib/, etc.) where a program will always look for libraries, one can use the LD_LIBRARY_PATH environment variable to specify (non-standard) paths where the program will look for. e.g: if your NetCDF library "lib" directory is in "/home/me/my_stuff/netcdf/lib" and you want you programs to find it you should update your LD_LIBRARY_PATH:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/me/my_stuff/netcdf/lib

the "Wl,-rpath=" compilation option

One can "hard code" into an executable where it should look for when seeking dynamical libraries at run time via the "-Wl,-rpath=" option provided to the linker when compiling/linking the code. Following up on previous example and assuming you're using the makelmdz_fcm script, this implies adapting the arch.fcm file %BASE_LD line:

%BASE_LD -Wl,-rpath=/home/me/my_stuff/netcdf/lib

Note however that this "hard coding" of the path into the executable is not recommended as if the library is later moved to a different directory then the executable won't find it anymore... You have been warned.

the patchelf utility

Sometimes ldd reveals that some "system libraires" (e.g. located in /lib64) are used instead of the ones you provide. There is actually a tool patchelf which may be useful to modify, in a similar way to the -rpath mentioned above, but on an existing executable the paths where it will expect to find its shared libraries. See https://github.com/NixOS/patchelf