Hi
Issue
I have encountered a problem that Geant4 shared libraries, such as libG4materials.so, don’t have embedded rpath in the binary files. This causes the shared libraries can’t find its dependencies.
If you run ldd libG4materials.so, the linked shared libraries can’t be found:
[root@d3ef4098097d lib64]# ldd libG4materials.so
linux-vdso.so.1 (0x00007fedf0e46000)
libG4intercoms.so => not found
libz.so.1 => /lib64/libz.so.1 (0x00007fedf0d47000)
libG4global.so => not found
libG4clhep.so => not found
libG4ptl.so.3 => not found
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fedf0ace000)
libm.so.6 => /lib64/libm.so.6 (0x00007fedf09e0000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fedf09b4000)
libc.so.6 => /lib64/libc.so.6 (0x00007fedf07c2000)
/lib64/ld-linux-x86-64.so.2 (0x00007fedf0e48000)
By reading the elf file with readelf -d libG4materials.so, it lacks the rpath:
Dynamic section at offset 0xc5be8 contains 33 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libG4intercoms.so]
0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
0x0000000000000001 (NEEDED) Shared library: [libG4global.so]
0x0000000000000001 (NEEDED) Shared library: [libG4clhep.so]
0x0000000000000001 (NEEDED) Shared library: [libG4ptl.so.3]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000e (SONAME) Library soname: [libG4materials.so]
0x000000000000000c (INIT) 0x224
0x000000000000000d (FINI) 0x6bb60
0x0000000000000019 (INIT_ARRAY) 0xc65f0
0x000000000000001b (INIT_ARRAYSZ) 24 (bytes)
0x000000000000001a (FINI_ARRAY) 0xc6608
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x6c000
0x0000000000000005 (STRTAB) 0x71f68
0x0000000000000006 (SYMTAB) 0x6d420
0x000000000000000a (STRSZ) 38363 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000003 (PLTGOT) 0xc6fe8
0x0000000000000002 (PLTRELSZ) 9768 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x7d120
0x0000000000000007 (RELA) 0x7bd10
0x0000000000000008 (RELASZ) 5136 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffffe (VERNEED) 0x7bb90
0x000000006fffffff (VERNEEDNUM) 4
0x000000006ffffff0 (VERSYM) 0x7b544
0x000000006ffffff9 (RELACOUNT) 29
0x0000000000000000 (NULL) 0x0
Shared libraries can be found if user change the environment variable LD_LIBRARY_PATH. But this is undesirable as it’s very intrusive for other programs running in the same system.
How to reproduce
Create a docker image with:
docker build -t geant-image .
in the folder containing the following Dockerfile:
ARG BUILD_REPO=fedora
FROM ${BUILD_REPO}:latest
ARG THREAD_NUM=4
ENV SIMPATH="/opt/FairSoft"
RUN yes | dnf upgrade --refresh &&\
dnf install -y util-linux gcc gcc-gfortran clang cmake ninja-build git wget &&\
dnf install -y expat-devel xerces-c-devel openblas-devel openssl-devel python python-devel python3-numpy python3-pygments python3-pyyaml&&\
dnf autoremove -y && mkdir -p /tmp/download && cd /tmp/download &&\
export CC=clang && export FC=gfortran && export CXX=clang++ &&\
mkdir -p ${SIMPATH} && cd /tmp/download &&\
wget https://github.com/Geant4/geant4/archive/refs/tags/v11.3.2.tar.gz &&\
tar xzf v11.3.2.tar.gz && cd geant4-11.3.2 &&\
mkdir build && cd build &&\
cmake -DCMAKE_INSTALL_PREFIX=${SIMPATH} -GNinja -DCMAKE_CXX_STANDARD=23 -DGEANT4_BUILD_MULTITHREADED=ON -DGEANT4_BUILD_TLS_MODEL=global-dynamic -DGEANT4_USE_SYSTEM_EXPAT=ON -DGEANT4_USE_G3TOG4=ON -DGEANT4_USE_GDML=ON -DGEANT4_USE_OPENGL_X11=OFF -DGEANT4_USE_RAYTRACER_X11=OFF -DGEANT4_USE_PYTHON=ON -DGEANT4_INSTALL_DATA=ON -DGEANT4_INSTALL_DATA_TIMEOUT=36000 -DGEANT4_BUILD_STORE_TRAJECTORY=OFF -DGEANT4_BUILD_VERBOSE_CODE=ON -DGEANT4_BUILD_BUILTIN_BACKTRACE=OFF .. &&\
ninja -j${THREAD_NUM} && ninja install &&\
rm -rf /tmp/download && dnf autoremove -y
After the image is build, create its container:
docker run -it --name test geant-image "/bin/bash"
Then inside the container, go to the library folder:
cd /opt/FairSoft/lib64
Query the needed shared libraries with:
ldd libG4materials.so
Then the missing shared libraries could be seen.
Potential fix
In the CMake file, specify the rpath of the library targets:
include(GNUInstallDirs)
file(RELATIVE_PATH relDir
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}
)
set(CMAKE_INSTALL_RPATH $ORIGIN $ORIGIN/${relDir})
Please refer to section 27.2.2 of the book “Professional CMake: A Practical Guide” by Craig Scott about the installation rpath.
Geant4 Version: v11.3.2
Operating System: Fedora 42
Compiler/Version: gcc 15.0
CMake Version: 4.1