Я создаю свое первое приложение на основе OpenCV на C ++.Моя цель - создать промежуточный образ докера, который может статически скомпилировать приложение, чтобы оно могло работать автономно в полученном меньшем образе.Я готов использовать любой образ докера для этого шага, но для того, чтобы вы могли точно видеть, что у меня есть, вот файл докера для воспроизведения всей среды:
FROM ubuntu:18.04 as compiler
ENV OPENCV_VERSION='3.4.2' DEBIAN_FRONTEND=noninteractive
RUN apt-get -y update && \
apt-get -y upgrade && \
apt-get -y dist-upgrade && \
apt-get -y autoremove && \
apt-get install -y build-essential cmake
RUN apt-get install -y qt5-default libvtk6-dev
RUN apt-get install -y zlib1g-dev libjpeg-dev libwebp-dev libpng-dev libtiff5-dev libopenexr-dev libgdal-dev
RUN apt-get install -y libdc1394-22-dev libavcodec-dev libavformat-dev libswscale-dev libtheora-dev libvorbis-dev libxvidcore-dev libx264-dev yasm libopencore-amrnb-dev libopencore-amrwb-dev libv4l-dev libxine2-dev
RUN apt-get install -y unzip wget
RUN wget --progress=dot:giga https://github.com/opencv/opencv/archive/${OPENCV_VERSION}.zip && \
unzip -q ${OPENCV_VERSION}.zip && \
rm ${OPENCV_VERSION}.zip && \
mv opencv-${OPENCV_VERSION} OpenCV && \
cd OpenCV && \
mkdir build && \
cd build && \
cmake \
-D BUILD_SHARED_LIBS=OFF \
-D WITH_QT=ON \
-D WITH_OPENGL=ON \
-D FORCE_VTK=ON \
-D WITH_TBB=ON \
-D WITH_GDAL=ON \
-D WITH_XINE=ON \
-D BUILD_EXAMPLES=OFF \
-D ENABLE_PRECOMPILED_HEADERS=OFF \
-D BUILD_DOCS=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_TESTS=OFF \
-D BUILD_opencv_apps=OFF \
.. && \
make -j4 && \
make install && \
ldconfig
COPY compile-test.cpp compile-test.cpp
RUN g++ -std=c++11 -static compile-test.cpp -o /app $(pkg-config --cflags --libs opencv)
В настоящее время я могу скомпилировать свои приложения на С ++без проблем с использованием dyanmic libs, но это создает огромный образ докера, и я действительно хочу иметь возможность создавать автономные двоичные файлы для распространения с минимальным размером.
Как вы можете видеть, я компилирую OpenCV из исходного кодавключая флаг BUILD_SHARED_LIBS=OFF
, чтобы убедиться, что я получаю статические библиотеки .a
вместо динамических библиотек .so
.Я взял подсказку из крайне рекомендуемого сценария сборки и изменил его для использования с докером, пропустив несколько вещей на Python, так как я использую c ++.
, потому что у меня было так много проблем смое настоящее приложение, я пошел вперед и создал гораздо более простое приложение, которое также взрывается во время компиляции.Я считаю, что это как-то связано с включенными cflags
и libs
.Проблема в настоящее время находится за пределами моего понимания.Я получаю кучу ошибок, которые, кажется, меняются, когда я настраиваю одно включение в моей команде компиляции.Вот самое простое приложение, которое я пытаюсь скомпилировать.Это действительно ничего не делает, но включает библиотеку.
#include "opencv2/imgcodecs.hpp"
using namespace cv;
Mat img;
int main( int argc, char** argv ) {
img = cv::imread( argv[1], IMREAD_COLOR );
}
Затем я пытаюсь скомпилировать это так:
g++ -std=c++11 -static compile-test.cpp -o /app $(pkg-config --cflags --libs opencv)
И это заканчивается кучейошибки слишком длинные, чтобы их можно было вставить полностью.
//usr/local/lib/libopencv_imgcodecs.a(grfmt_jpeg.cpp.o): In function `cv::JpegEncoder::write(cv::Mat const&, std::vector<int, std::allocator<int> > const&)':
grfmt_jpeg.cpp:(.text._ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE+0xf8): undefined reference to `jpeg_CreateCompress'
grfmt_jpeg.cpp:(.text._ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE+0x105): undefined reference to `jpeg_std_error'
grfmt_jpeg.cpp:(.text._ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE+0x2b5): undefined reference to `jpeg_set_defaults'
grfmt_jpeg.cpp:(.text._ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE+0x2d0): undefined reference to `jpeg_set_quality'
grfmt_jpeg.cpp:(.text._ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE+0x2fe): undefined reference to `jpeg_quality_scaling'
grfmt_jpeg.cpp:(.text._ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE+0x30d): undefined reference to `jpeg_quality_scaling'
grfmt_jpeg.cpp:(.text._ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE+0x367): undefined reference to `jpeg_default_qtables'
grfmt_jpeg.cpp:(.text._ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE+0x379): undefined reference to `jpeg_start_compress'
grfmt_jpeg.cpp:
...
collect2: error: ld returned 1 exit status
Некоторые вещи, которые я уже пробовал
- Начинаем гуглить каждую из, казалось бы, уникальных ошибок компиляции и добавляем соответствующие флаги вконец моего кода компиляции.
- Переупорядочение некоторых флагов включения, но их слишком много, чтобы сделать это эффективно
- Использование пакета
opencv-dev
вместо его компиляции, но кажетсявы не можете этого сделать и ожидаете использовать статические библиотеки.