高山 docker 容器中简单 OpenCV 程序的链接器错误

Posted

技术标签:

【中文标题】高山 docker 容器中简单 OpenCV 程序的链接器错误【英文标题】:Linker Error on a simple OpenCV program in an alpine docker container 【发布时间】:2019-03-07 03:40:53 【问题描述】:

我有一个显示图像的简单程序。

    String imagePath = "D:/Dev Tools/Docker/alpineOpenCV/";
    Mat img = imread(imagePath+"lena.jpg", IMREAD_COLOR);
    imshow ("Test Image", img);

我有一个使用以下 dockerfile 构建的图像。

FROM alpine:3.9
RUN echo -e '@edgunity http://nl.alpinelinux.org/alpine/edge/community\n\
@edge http://nl.alpinelinux.org/alpine/edge/main\n\
@testing http://nl.alpinelinux.org/alpine/edge/testing\n\
@community http://dl-cdn.alpinelinux.org/alpine/edge/community'\
  >> /etc/apk/repositories

RUN apk add --update \
  # --virtual .build-deps \
      build-base \
      openblas-dev \
      unzip \
      wget \
      cmake \
      libtbb@testing  \
      libtbb-dev@testing   \
      libjpeg  \
      libjpeg-turbo-dev \
      libpng-dev \
      jasper-dev \
      tiff-dev \
      libwebp-dev \
      clang-dev \
      linux-headers 

ENV CC /usr/bin/clang
ENV CXX /usr/bin/clang++

ENV OPENCV_VERSION=4.0.1
RUN cd /opt && \
  wget https://github.com/opencv/opencv/archive/$OPENCV_VERSION.zip && \
  unzip $OPENCV_VERSION.zip && \
  rm -rf $OPENCV_VERSION.zip

RUN mkdir -p /opt/opencv-$OPENCV_VERSION/build && \
  cd /opt/opencv-$OPENCV_VERSION/build && \
  cmake \
  -D CMAKE_BUILD_TYPE=RELEASE \
  -D CMAKE_INSTALL_PREFIX=/usr/local \
  -D WITH_FFMPEG=NO \
  -D WITH_IPP=NO \
  -D WITH_OPENEXR=NO \
  -D WITH_TBB=YES \
  -D BUILD_EXAMPLES=NO \
  -D BUILD_android_EXAMPLES=NO \
  -D INSTALL_PYTHON_EXAMPLES=NO \
  -D BUILD_DOCS=NO \
  -D BUILD_opencv_python2=NO \
  -D BUILD_opencv_python3=ON \
  -D PYTHON3_EXECUTABLE=/usr/local/bin/python \
  -D PYTHON3_INCLUDE_DIR=/usr/local/include/python3.6m/ \
  -D PYTHON3_LIBRARY=/usr/local/lib/libpython3.so \
  -D PYTHON_LIBRARY=/usr/local/lib/libpython3.so \
  -D PYTHON3_PACKAGES_PATH=/usr/local/lib/python3.6/site-packages/ \
  -D PYTHON3_NUMPY_INCLUDE_DIRS=/usr/local/lib/python3.6/site-packages/numpy/core/include/ \
  .. && \
  make VERBOSE=1 && \
  make && \
  make install && \
  rm -rf /opt/opencv-$OPENCV_VERSION

我可以使用以下方法成功编译我的程序:

g++ -I/usr/local/include/opencv4/ -I/usr/local/include/opencv4/ -L/usr/local/lib64/ -g -o binary  main.cpp -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lop
encv_video -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_stitching -lopencv_imgcodecs

但是,当我尝试运行 ./binary 时出现链接器错误

Error loading shared library libopencv_core.so.4.0: No such file or directory (needed by ./binary2)
Error loading shared library libopencv_highgui.so.4.0: No such file or directory (needed by ./binary2)
Error loading shared library libopencv_imgcodecs.so.4.0: No such file or directory (needed by ./binary2)
Error relocating ./binary2: _ZN2cv8fastFreeEPv: symbol not found
Error relocating ./binary2: _ZN2cv6imreadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi: symbol not found
Error relocating ./binary2: _ZN2cv6imshowERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11_InputArrayE: symbol not found
Error relocating ./binary2: _ZN2cv7waitKeyEi: symbol not found
Error relocating ./binary2: _ZN2cv3Mat10deallocateEv: symbol not found

我在this thread: 中尝试了以下解决方案,但无济于事。我可以看到我的 so 文件在 /usr/local/lib64/ 中,但我似乎无法正确链接它们。

更新:ldd ./binary 输出

/lib/ld-musl-x86_64.so.1 (0x7f13f91db000)
        libopencv_core.so.4.0 => /usr/local/lib/libopencv_core.so.4.0 (0x7f13f8d33000)
        libopencv_highgui.so.4.0 => /usr/local/lib/libopencv_highgui.so.4.0 (0x7f13f8d24000)
        libopencv_imgcodecs.so.4.0 => /usr/local/lib/libopencv_imgcodecs.so.4.0 (0x7f13f8cdb000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7f13f8b86000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7f13f8b72000)
        libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f13f91db000)
        libtbb.so.2 => /usr/lib/libtbb.so.2 (0x7f13f893d000)
        libz.so.1 => /lib/libz.so.1 (0x7f13f8923000)
        libopenblas.so.3 => /usr/lib/libopenblas.so.3 (0x7f13f6da6000)
        libopencv_videoio.so.4.0 => /usr/local/lib64/libopencv_videoio.so.4.0 (0x7f13f6d70000)
        libopencv_imgproc.so.4.0 => /usr/local/lib64/libopencv_imgproc.so.4.0 (0x7f13f689c000)
        libjpeg.so.8 => /usr/lib/libjpeg.so.8 (0x7f13f683b000)
        libwebp.so.7 => /usr/lib/libwebp.so.7 (0x7f13f67e5000)
        libpng16.so.16 => /usr/lib/libpng16.so.16 (0x7f13f67b5000)
        libtiff.so.5 => /usr/lib/libtiff.so.5 (0x7f13f674b000)
        libjasper.so.4 => /usr/lib/libjasper.so.4 (0x7f13f66da000)
        libgfortran.so.5 => /usr/lib/libgfortran.so.5 (0x7f13f6547000)
        libquadmath.so.0 => /usr/lib/../lib/libquadmath.so.0 (0x7f13f6514000)

【问题讨论】:

最简单的方法 - 为您的项目使用 CMake 和 FindPackage(OpenCV) 你能发布ldd ./binary的输出吗? 刚刚发布。这是在将文件从 lib64 移动到 lib 之后 【参考方案1】:

也许您在 docker runfile 的末尾需要 RUN ldconfigENV PATH="/usr/local/lib64:$PATH"

【讨论】:

完成后我会发布更新可能需要一段时间。【参考方案2】:

在尝试了这么多次并重建了这么多小时之后。我刚刚将所有文件从/usr/local/lib64/ 复制到/usr/local/lib/。它可能不优雅。但它有效。

【讨论】:

以上是关于高山 docker 容器中简单 OpenCV 程序的链接器错误的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在具有高山风味的 docker 容器内构建 AOSP?

Docker:最后的节点高山映像是不是比完整节点映像小?

如何使用Docker将NodeJS应用程序与cron作业进行容器化?

在ARM Docker容器中构建OPENCV时出现问题

在高山容器中启用crond

sh 构建并安装cmd文件夹中的所有内容,以便在高山容器中使用