3

I'm using Conan as my package manager. My CMakeLists.txt looks like this:

cmake_minimum_required(VERSION 3.20)


project(opencv-test)


set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS true)


include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup(NO_OUTPUT_DIRS)


add_executable(
    ${PROJECT_NAME}

    main.cpp
)


target_include_directories(
    ${PROJECT_NAME}
    PRIVATE

    ${PROJECT_SOURCE_DIR}
    ${CONAN_INCLUDE_DIRS_OPENCV}
)


target_link_libraries(
    ${PROJECT_NAME}
    PRIVATE

    ${CONAN_LIBS_OPENCV}
)

When I try to build it, I get a lot of linking errors on both Windows and Linux. If I replace add_executable with add_library everything works fine. What am I doing wrong? How can I link OpenCV to the executable directly without using an additional library?

Build steps:

conan install . --install-folder Build
cmake -S . -B Build -DCMAKE_BUILD_TYPE=Debug
cmake --build Build

conanfile.txt:

[requires]
opencv/4.5.2

[generators]
cmake

Conan profile:

> conan profile show default                                                                               
Configuration for profile default:

[settings]
os=Linux
os_build=Linux
arch=x86_64
arch_build=x86_64
compiler=gcc
compiler.version=9
compiler.libcxx=libstdc++11
build_type=Debug
[options]
[build_requires]
[env]

main.cpp:

#include <iostream>

#include "opencv2/imgcodecs.hpp"


int main()
{
    cv::imread("test.png");
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

Errors:

> cmake --build Build
Scanning dependencies of target OpenCVTest
[ 50%] Building CXX object CMakeFiles/OpenCVTest.dir/main.cpp.o
[100%] Linking CXX executable OpenCVTest
ld: error: undefined symbol: Imf_2_5::Chromaticities::Chromaticities(Imath_2_5::Vec2<float> const&, Imath_2_5::Vec2<float> const&, Imath_2_5::Vec2<float> const&, Imath_2_5::Vec2<float> const&)
>>> referenced by grfmt_exr.cpp:83 (/home/conan/w/BuildSingleReference/.conan/data/opencv/4.5.2/_/_/build/5d6fbfde15f1610a06b48504503efbd94beae363/source_subfolder/modules/imgcodecs/src/grfmt_exr.cpp:83)
>>>               grfmt_exr.cpp.o:(cv::ExrDecoder::ExrDecoder()) in archive /home/work/.conan/data/opencv/4.5.2/_/_/package/5d6fbfde15f1610a06b48504503efbd94beae363/lib/libopencv_imgcodecs.a

ld: error: undefined symbol: Imf_2_5::globalThreadCount()
>>> referenced by grfmt_exr.cpp:125 (/home/conan/w/BuildSingleReference/.conan/data/opencv/4.5.2/_/_/build/5d6fbfde15f1610a06b48504503efbd94beae363/source_subfolder/modules/imgcodecs/src/grfmt_exr.cpp:125)
>>>               grfmt_exr.cpp.o:(cv::ExrDecoder::readHeader()) in archive /home/work/.conan/data/opencv/4.5.2/_/_/package/5d6fbfde15f1610a06b48504503efbd94beae363/lib/libopencv_imgcodecs.a
>>> referenced by grfmt_exr.cpp:681 (/home/conan/w/BuildSingleReference/.conan/data/opencv/4.5.2/_/_/build/5d6fbfde15f1610a06b48504503efbd94beae363/source_subfolder/modules/imgcodecs/src/grfmt_exr.cpp:681)
>>>               grfmt_exr.cpp.o:(cv::ExrEncoder::write(cv::Mat const&, std::vector<int, std::allocator<int> > const&)) in archive /home/work/.conan/data/opencv/4.5.2/_/_/package/5d6fbfde15f1610a06b48504503efbd94beae363/lib/libopencv_imgcodecs.a

...

This is what conanbuildinfo.cmake contains:

...
#################
###  OPENCV
#################
set(CONAN_OPENCV_ROOT "/home/work/.conan/data/opencv/4.5.2/_/_/package/5d6fbfde15f1610a06b48504503efbd94beae363")
set(CONAN_INCLUDE_DIRS_OPENCV "/home/work/.conan/data/opencv/4.5.2/_/_/package/5d6fbfde15f1610a06b48504503efbd94beae363/include"
            "/home/work/.conan/data/opencv/4.5.2/_/_/package/5d6fbfde15f1610a06b48504503efbd94beae363/include/opencv4")
set(CONAN_LIB_DIRS_OPENCV "/home/work/.conan/data/opencv/4.5.2/_/_/package/5d6fbfde15f1610a06b48504503efbd94beae363/lib")
set(CONAN_BIN_DIRS_OPENCV "/home/work/.conan/data/opencv/4.5.2/_/_/package/5d6fbfde15f1610a06b48504503efbd94beae363/bin")
set(CONAN_RES_DIRS_OPENCV "/home/work/.conan/data/opencv/4.5.2/_/_/package/5d6fbfde15f1610a06b48504503efbd94beae363/res")
set(CONAN_SRC_DIRS_OPENCV )
set(CONAN_BUILD_DIRS_OPENCV "/home/work/.conan/data/opencv/4.5.2/_/_/package/5d6fbfde15f1610a06b48504503efbd94beae363/"
            "/home/work/.conan/data/opencv/4.5.2/_/_/package/5d6fbfde15f1610a06b48504503efbd94beae363/lib/cmake")
set(CONAN_FRAMEWORK_DIRS_OPENCV )
set(CONAN_LIBS_OPENCV opencv_ml opencv_photo opencv_highgui opencv_videoio opencv_imgcodecs opencv_objdetect opencv_stitching opencv_video opencv_calib3d opencv_features2d opencv_flann opencv_dnn opencv_imgproc opencv_core)
...
Max Ignatyev
  • 31
  • 1
  • 4
  • 1
    ***If I replace add_executable with add_library everything works fine*** I think it does so because then you create a static library out of your code and don't need to link to anything. – drescherjm Aug 19 '21 at 20:01
  • Can you show the steps you are using to build from scratch, including Conan and the contents of any configuration files? – Alex Reinking Aug 19 '21 at 20:08
  • I would also strongly encourage you to use Conan's [`cmake_paths`](https://docs.conan.io/en/latest/integrations/build_system/cmake/cmake_paths_generator.html) or [`cmake_find_package`](https://docs.conan.io/en/latest/integrations/build_system/cmake/cmake_find_package_generator.html) generator instead of plain `cmake`. – Alex Reinking Aug 19 '21 at 20:11
  • @drescherjm you are right, thanks for the clarification. – Max Ignatyev Aug 19 '21 at 20:15
  • 1
    @AlexReinking I edited the original post. – Max Ignatyev Aug 19 '21 at 20:30
  • This seems to say the problem is not linking to `OpenEXR`: [https://www.reddit.com/r/opencv/comments/dziaak/question_undefined_references_to_libimf_in_opencv/](https://www.reddit.com/r/opencv/comments/dziaak/question_undefined_references_to_libimf_in_opencv/) I can that EXR is not in the ${CONAN_LIBS_OPENCV} – drescherjm Aug 19 '21 at 20:40
  • @drescherjm Hmm, It looks like my system has an old version of this library. I will look into this, thank you! – Max Ignatyev Aug 19 '21 at 21:01
  • 2
    When you are linking with ``${CONAN_LIBS_OPENCV}`` you are exclusively linking with the OpenCV libraries, but these libraries have in turn other transitive dependencies that need to be linked too when creating executables. This is the reason the Conan docs uses ``${CONAN_LIBS}`` instead, because that aggregates the direct and transitive dependencies. In any case, I agree with Alex, it is better to use ``cmake_find_package`` generator, or if want to live on the edge the new ``CMakeDeps`` experimental one. – drodri Aug 19 '21 at 23:11

0 Answers0