Grapeoff
@Grapeoff
В чём концепция...?

Почему при компиляции приложения с подключённым OpenCV вылетает ошибка `undefined reference`?

В приложении всего 3 библиотеки: SFML, TinyFD и OpenCV. Первые две работают превосходно, но вот OpenCV почему-то не хочет работать.

Библиотеку собирал из исходников, решил собрать с нуля когда по такой же причине падало моё предыдущее приложение.

Вот сама библиотека в проекте:

623cc709498e1783155213.png
Далее её подключение в CMake:

cmake_minimum_required(VERSION 3.0)
project(ImagePixelizer VERSION 0.1)

set(CMAKE_CXX_STANDARD 20)

add_subdirectory(lib/tinyfd)

add_executable(ImagePixelizer src/main.cpp src/SelectFileDialog/FileDialog.cpp)

target_include_directories(ImagePixelizer PRIVATE
        lib/SFML/include/
        lib/OpenCV/include
        lib/NFD/include
        lib/wxWidgets/include
        lib/tinyfd/include)

target_link_libraries(
        ImagePixelizer
        ${PROJECT_SOURCE_DIR}/lib/SFML/lib/libsfml-graphics.a
        ${PROJECT_SOURCE_DIR}/lib/SFML/lib/libsfml-window.a
        ${PROJECT_SOURCE_DIR}/lib/SFML/lib/libsfml-system.a
        ${PROJECT_SOURCE_DIR}/lib/OpenCV/lib/opencv_core455.lib
        ${PROJECT_SOURCE_DIR}/lib/OpenCV/lib/opencv_gapi455.lib
        ${PROJECT_SOURCE_DIR}/lib/OpenCV/lib/opencv_photo455.lib
        ${PROJECT_SOURCE_DIR}/lib/OpenCV/lib/opencv_imgcodecs455.lib
        ${PROJECT_SOURCE_DIR}/lib/OpenCV/lib/opencv_imgproc455.lib
        ${PROJECT_SOURCE_DIR}/lib/OpenCV/lib/opencv_video455.lib
        ${PROJECT_SOURCE_DIR}/lib/OpenCV/lib/opencv_videoio455.lib
        tinyfd)

И сама ошибка:

cmd.exe /C "cd . && H:\CLION2~1.3\bin\mingw\bin\G__~1.EXE -g  CMakeFiles/ImagePixelizer.dir/src/main.cpp.obj CMakeFiles/ImagePixelizer.dir/src/SelectFileDialog/FileDialog.cpp.obj -o ImagePixelizer.exe -Wl,--out-implib,libImagePixelizer.dll.a -Wl,--major-image-version,0,--minor-image-version,0  ../lib/SFML/lib/libsfml-graphics.a  ../lib/SFML/lib/libsfml-window.a  ../lib/SFML/lib/libsfml-system.a  ../lib/OpenCV/lib/opencv_core455.lib  ../lib/OpenCV/lib/opencv_gapi455.lib  ../lib/OpenCV/lib/opencv_photo455.lib  ../lib/OpenCV/lib/opencv_imgcodecs455.lib  ../lib/OpenCV/lib/opencv_imgproc455.lib  ../lib/OpenCV/lib/opencv_video455.lib  ../lib/OpenCV/lib/opencv_videoio455.lib  lib/tinyfd/libtinyfd.a  -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ."
H:\CLion 2021.3\bin\mingw\bin/ld.exe: CMakeFiles/ImagePixelizer.dir/src/main.cpp.obj:D:/Code/ImagePixelizer/src/main.cpp:14: undefined reference to `cv::VideoCapture::VideoCapture()'
H:\CLion 2021.3\bin\mingw\bin/ld.exe: CMakeFiles/ImagePixelizer.dir/src/main.cpp.obj: in function `main':
D:/Code/ImagePixelizer/src/main.cpp:29: undefined reference to `cv::VideoCapture::~VideoCapture()'
H:\CLion 2021.3\bin\mingw\bin/ld.exe: D:/Code/ImagePixelizer/src/main.cpp:29: undefined reference to `cv::VideoCapture::~VideoCapture()'

Чтобы получить эту ошибку, много сделать не пришлось:

#include <SFML/Graphics.hpp>

#include <opencv2/videoio.hpp>

#include "SelectFileDialog/FileDialog.hpp"

int main() {
    sf::RenderWindow window(sf::VideoMode(800, 600), "Image Pixelizer");

    cv::VideoCapture capture; // Использование API OpenCV

    while (window.isOpen()) {
        sf::Event event{};

        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed)
                window.close();
        }

        window.clear();
        window.display();
    }

    return 0;
}


Ошибка выбрасывается при любом использовании API OpenCV.
  • Вопрос задан
  • 282 просмотра
Решения вопроса 1
Grapeoff
@Grapeoff Автор вопроса
В чём концепция...?
Оказалось, что библиотека, скомпилированная одним компилятором, не будет прочтена другим компилятором.

Данная версия OpenCV была скомпилирована компилятором Microsoft Visual C++ 2015 (файлы библиотеки находятся в папке vc15) и не могла быть прочитана моим MinGW. А когда я компилировал библиотеку собственноручно, то также совершал данную ошибку, генерируя проект для Visual Studio 2022.

Сборка OpenCV компилятором MinGW.

Чтобы скомпилировать исходный код для MinGW я выполнил такой порядок действий:
  1. Добавил путь к MinGWв переменную среды Path, чтобы его мог использовать CMakeи я из командной строки.
  2. Скачал исходный код библиотеки. (Версия 4.5.5)
  3. Сконфигурировал и сгенерировал проект для компилятора из MinGW

    623eeaaeb1150655080830.png
  4. Открыл командную строку в папке, куда СMake кладёт бинарники (Where to build the binares) и выполнил команду mingw32-make install, после чего пошёл достаточно долгий процесс компиляции библиотеки.

    cMyfP.png
  5. Далее, согласно инструкции из командной строки после завершения компиляции, я открыл (папку с бинарниками из пункта 4)/install. Там находятся динамические и статические библиотеки (библиотеки импорта, как я понял) в соответствующих папках. Эти файлы переносим в проект. Файлы заголовков лежат в /install/include.
  6. После чего уже, соответственно, можно линковаться со всеми необходимыми вам статическими библиотеками, и, либо положить .dll-ки в папку с исполняемым файлом, либо добавить в Path.

target_link_libraries(
        Target
        ${PROJECT_SOURCE_DIR}/lib/OpenCV/lib/libopencv_imgcodecs455.dll.a
        ${PROJECT_SOURCE_DIR}/lib/OpenCV/lib/libopencv_imgproc455.dll.a
        ${PROJECT_SOURCE_DIR}/lib/OpenCV/lib/libopencv_core455.dll.a
        ${PROJECT_SOURCE_DIR}/lib/OpenCV/lib/libopencv_highgui455.dll.a
        ${PROJECT_SOURCE_DIR}/lib/OpenCV/lib/libopencv_gapi455.dll.a
        ${PROJECT_SOURCE_DIR}/lib/OpenCV/lib/libopencv_video455.dll.a
        ${PROJECT_SOURCE_DIR}/lib/OpenCV/lib/libopencv_videoio455.dll.a
        ${PROJECT_SOURCE_DIR}/lib/OpenCV/lib/libopencv_photo455.dll.a)

После проделанных махинаций проект успешно запускается без каких-либо ошибок.

Это копия моего же ответа на StackOverflow. Решил дописать ещё и сюда, вдруг кому пригодится.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы