So, I have a project in a Docker container which uses Qt (for a C++ server application).
When I try to run the image on a different computer, I get the error message
error while loading shared libraries: libQt5Core.so.5: cannot open shared object file: No such file or directory
I made sure that the library file actually exists within the container, which it does
find . -name *Qt5Core*
...
./usr/lib/x86_64-linux-gnu/libQt5Core.so.5
...
So I assumed that LD_LIBRARY_PATH was perhaps not set properly, thus I added
ENV LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu/:${LD_LIBRARY_PATH}"
to my Dockerfile.
The error persists, though.
Note that the other machine uses Podman instead of Docker (it does not have the actual Docker installed an I am not admin, thus I can't test if it works using Docker).
That the computer on which I created the image has Qt installed, thus it might be that the problem just doesn't surface there because it can use the library from outside the container.
Is there something I overlooked?
(I could try to copy the library file into the same folder where the executable is located within the container, but if possible, I'd prefer a cleaner solution.)
(There is this question: Linux: Can't find existing shared library in docker container which sounded kind of similar, however, the solution there revolves around cmake, which I don't use.)
Edit: If relevant, when I check the dependencies of the executable within the container with ldd within the CMD instructions of the Dockerfile on the machine on which I build it, I get
podman run --pod my_pod -it test_server
linux-vdso.so.1 (0x00007ffdb45a4000)
libQt5Network.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Network.so.5 (0x00007efcdf0ee000)
libQt5Core.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 (0x00007efcdeba5000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007efcde9c4000)
libgcc_s.so.1 => /usr/lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007efcde9a9000)
libc.so.6 => /usr/lib/x86_64-linux-gnu/libc.so.6 (0x00007efcde7b7000)
libpthread.so.0 => /usr/lib/x86_64-linux-gnu/libpthread.so.0 (0x00007efcde794000)
libz.so.1 => /usr/lib/x86_64-linux-gnu/libz.so.1 (0x00007efcde776000)
libdl.so.2 => /usr/lib/x86_64-linux-gnu/libdl.so.2 (0x00007efcde770000)
libicui18n.so.66 => /usr/lib/x86_64-linux-gnu/libicui18n.so.66 (0x00007efcde471000)
libicuuc.so.66 => /usr/lib/x86_64-linux-gnu/libicuuc.so.66 (0x00007efcde28b000)
libpcre2-16.so.0 => /usr/lib/x86_64-linux-gnu/libpcre2-16.so.0 (0x00007efcde208000)
libdouble-conversion.so.3 => /usr/lib/x86_64-linux-gnu/libdouble-conversion.so.3 (0x00007efcde1f2000)
libglib-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007efcde0c7000)
libm.so.6 => /usr/lib/x86_64-linux-gnu/libm.so.6 (0x00007efcddf78000)
/lib64/ld-linux-x86-64.so.2 (0x00007efcdf2b9000)
libicudata.so.66 => /usr/lib/x86_64-linux-gnu/libicudata.so.66 (0x00007efcdc4b7000)
libpcre.so.3 => /usr/lib/x86_64-linux-gnu/libpcre.so.3 (0x00007efcdc444000)
However, on the other machine, the result is
podman run --pod my_pod -it test_server
linux-vdso.so.1 (0x00007fff18584000)
libQt5Network.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Network.so.5 (0x00007fca4e9bb000)
libQt5Core.so.5 => not found
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fca4e7d2000)
libgcc_s.so.1 => /usr/lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fca4e7b7000)
libc.so.6 => /usr/lib/x86_64-linux-gnu/libc.so.6 (0x00007fca4e5c5000)
libQt5Core.so.5 => not found
libpthread.so.0 => /usr/lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fca4e5a0000)
libz.so.1 => /usr/lib/x86_64-linux-gnu/libz.so.1 (0x00007fca4e584000)
libdl.so.2 => /usr/lib/x86_64-linux-gnu/libdl.so.2 (0x00007fca4e57e000)
libm.so.6 => /usr/lib/x86_64-linux-gnu/libm.so.6 (0x00007fca4e42f000)
/lib64/ld-linux-x86-64.so.2 (0x00007fca4eb86000)
So it only does not find the Qt Core library file. Note that /usr/lib/x86_64-linux-gnu/ does not exist on the other machine itself, thus it clearly is a path within the container. Another interesting find is that it does find libQt5Network.so.5, which I find rather strange given the circumstances.
If relevant, my Dockerfile, with some diagnostics build on for this very problem:
FROM ubuntu:20.04
# get some basics
RUN apt update
RUN apt-get install -y wget
RUN apt-get install -y software-properties-common
# get C++ compiler
RUN apt-get install -y g++
RUN apt-get install -y build-essential
# get Qt
RUN apt-get install -y qt5-default
RUN apt-get install -y libqt5gui5
ENV LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu/:${LD_LIBRARY_PATH}"
COPY connection.cpp /
COPY connection.h /
COPY main.cpp /
COPY server.cpp /
COPY server.h /
COPY server.pro /
# compile
RUN qmake server.pro; \
make
RUN echo $LD_LIBRARY_PATH
EXPOSE 9999
CMD ldd Server; \
/Server
Edit: I tried to add some diagnostics and another manual export for the library path in the CMD section of the Dockerfile:
CMD export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/; \
echo '-----------------------------:'; \
echo 'library path:'; \
echo $LD_LIBRARY_PATH; \
echo '-----------------------------:'; \
echo 'content relevant directory:'; \
ls /usr/lib/x86_64-linux-gnu/; \
echo '-----------------------------:'; \
echo 'dependencies:'; \
ldd Server; \
/Server
The manual export did not help, and the ls again clearly shows that libQt5Core.so.5 does in fact exist.
Solved the issue. This is a very exotic bug it seems.
I found the question https://askubuntu.com/questions/1034313/ubuntu-18-4-libqt5core-so-5-cannot-open-shared-object-file-no-such-file-or-dir and used the highest voted answer there, adding the line
RUN strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
to my Dockerfile.
Now my container works just fine.
If anybody has a solution that is more straight-forward, I'd be interested, though. I can't really say that I understand what's happening, what this business with the kernel one can read about under the link actually is about.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With