Docker容器中动态库的问题

Azi*_*uth 4 qt docker

因此,我在 Docker 容器中有一个使用 Qt 的项目(用于 C++ 服务器应用程序)。
当我尝试在另一台计算机上运行该映像时,收到错误消息

error while loading shared libraries: libQt5Core.so.5: cannot open shared object file: No such file or directory
Run Code Online (Sandbox Code Playgroud)

我确保库文件确实存在于容器中,它确实存在

find . -name *Qt5Core*
...
./usr/lib/x86_64-linux-gnu/libQt5Core.so.5
...
Run Code Online (Sandbox Code Playgroud)

所以我认为LD_LIBRARY_PATH可能没有正确设置,因此我添加了

ENV LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu/:${LD_LIBRARY_PATH}"
Run Code Online (Sandbox Code Playgroud)

到我的 Dockerfile。
但错误仍然存​​在。

请注意,另一台机器使用 Podman 而不是 Docker(它没有安装实际的 Docker,我不是管理员,因此我无法测试它是否可以使用 Docker 工作)。
我创建图像的计算机安装了 Qt,因此问题可能不会出现在那里,因为它可以从容器外部使用该库。

有什么是我忽略的吗?

(我可以尝试将库文件复制到容器内可执行文件所在的同一文件夹中,但如果可能的话,我更喜欢更干净的解决方案。)

(有一个问题:Linux: Can't find Existing Shared Library in dockerContainer,这听起来有点相似,但是,那里的解决方案围绕着cmake,我不使用它。)


编辑:如果相关,当我使用ldd构建CMD它的计算机上的 Dockerfile 的指令检查容器内可执行文件的依赖关系时,我得到

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)
Run Code Online (Sandbox Code Playgroud)

然而,在另一台机器上,结果是

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)
Run Code Online (Sandbox Code Playgroud)

所以它只是没有找到Qt Core库文件。请注意,/usr/lib/x86_64-linux-gnu/其他机器本身不存在,因此它显然是容器内的路径。另一个有趣的发现是它确实找到了libQt5Network.so.5,考虑到这种情况,我觉得这很奇怪。


如果相关的话,我的 Dockerfile,针对这个问题构建了一些诊断:

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
Run Code Online (Sandbox Code Playgroud)

编辑:我尝试在CMDDockerfile 部分中添加一些诊断和库路径的另一个手动导出:

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
Run Code Online (Sandbox Code Playgroud)

手动导出没有帮助,并且ls再次清楚地表明它libQt5Core.so.5确实存在。

Azi*_*uth 7

解决了问题。这看起来是一个非常奇特的错误。
我发现了问题https://askubuntu.com/questions/1034313/ubuntu-18-4-libqt5core-so-5-cannot-open-shared-object-file-no-such-file-or-dir并使用了那里得票最高的答案,添加行

RUN strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
Run Code Online (Sandbox Code Playgroud)

到我的 Dockerfile。

现在我的容器工作得很好。

如果有人有更直接的解决方案,我会很感兴趣。我真的不能说我理解正在发生的事情,人们可以在链接下阅读的内核业务实际上是关于什么的。