opencv-rust icon indicating copy to clipboard operation
opencv-rust copied to clipboard

Cannot link against vcpkg debug libraries on Windows

Open Kazurin-775 opened this issue 3 years ago • 9 comments

  • OS: Windows 11
  • OpenCV: v4.5.3 installed with vcpkg
  • LLVM: installed from official binary distribution; llvm-config.exe compiled by hand
  • rustc version: 1.56.1
  • Library version: 0.60.0 (also tried 0.61.0)

Phenomenon: the debug build of a fresh (but non-empty) project fails with the following linker error (full build.log):

  = note: libopencv-6ddd1601c5d0aec8.rlib(highgui.o) : error LNK2019: unresolved external symbol "void __cdecl cv::imshow(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class cv::_InputArray const &)" (?imshow@cv@@YAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBV_InputArray@1@@Z) referenced in function cv_imshow_const_StringR_const__InputArrayR
          libopencv-6ddd1601c5d0aec8.rlib(highgui.o) : error LNK2019: unresolved external symbol "class cv::Rect_<int> __cdecl cv::selectROI(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class cv::_InputArray const &,bool,bool)" (?selectROI@cv@@YA?AV?$Rect_@H@1@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBV_InputArray@1@_N2@Z) referenced in function cv_selectROI_const_StringR_const__InputArrayR_bool_bool
          libopencv-6ddd1601c5d0aec8.rlib(highgui.o) : error LNK2019: unresolved external symbol "class cv::Rect_<int> __cdecl cv::selectROI(class cv::_InputArray const &,bool,bool)" (?selectROI@cv@@YA?AV?$Rect_@H@1@AEBV_InputArray@1@_N1@Z) referenced in function cv_selectROI_const__InputArrayR_bool_bool
          libopencv-6ddd1601c5d0aec8.rlib(highgui.o) : error LNK2019: unresolved external symbol "void __cdecl cv::selectROIs(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class cv::_InputArray const &,class std::vector<class cv::Rect_<int>,class std::allocator<class cv::Rect_<int> > > &,bool,bool)" (?selectROIs@cv@@YAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBV_InputArray@1@AEAV?$vector@V?$Rect_@H@cv@@V?$allocator@V?$Rect_@H@cv@@@std@@@3@_N3@Z) referenced in function cv_selectROIs_const_StringR_const__InputArrayR_vector_Rect_R_bool_bool
          libopencv-6ddd1601c5d0aec8.rlib(aruco.o) : error LNK2019: unresolved external symbol "public: int __cdecl cv::aruco::Dictionary::getDistanceToId(class cv::_InputArray const &,int,bool)const " (?getDistanceToId@Dictionary@aruco@cv@@QEBAHAEBV_InputArray@3@H_N@Z) referenced in function cv_aruco_Dictionary_getDistanceToId_const_const__InputArrayR_int_bool

          ... (omitted, too long)

But the release build works like a charm, and can produce a working executable file. Setting $env:VCPKGRS_DYNAMIC = 1 does not solve the problem for me, and will give the same error as above.

Later I managed to make the linking process work by manually linking against the release build of the library (with .cargo/config.toml):

[target.x86_64-pc-windows-msvc]
rustflags = [
    '-LC:\vcpkg\installed\x64-windows\lib',
    '-lopencv_core',
    '-lopencv_highgui',
    '-lopencv_imgcodecs',
    '-lopencv_imgproc',
    # ... omitted
]

However, the output executable file suffers from DLL version inconsistency, as it depends on both opencv_***.dll and opencv_***d.dll, and will fail miserably with a C++ assertion error even if both DLLs are provided.

What's more, the DLLs copied by vcpkg are wrongly placed in my-fancy-project\target\debug\build\opencv-f4083f72defdfbbf\out instead of my-fancy-project\target\debug, and the release builds of the DLLs are copied instead of debug builds, causing a "DLL not found" error at program startup.

Is there any way to get the debug build working?

Kazurin-775 avatar Dec 03 '21 13:12 Kazurin-775

Can you please provide a full output of cargo build -vv after doing a cargo clean? It should contain the necessary information to help debug this issue. -vv is important as it adds a lot of auxiliary debug logging.

twistedfall avatar Dec 03 '21 13:12 twistedfall

Can you please provide a full output of cargo build -vv after doing a cargo clean?

OK, here you go: clean-build.log

Kazurin-775 avatar Dec 03 '21 14:12 Kazurin-775

The problem is that vcpkg helper copies release versions of the OpenCV but links to the debug ones. This can happen because of the fact that actual discovery is done with cmake without using vcpkg. Can you please try building with the following environment variable:

OPENCV_DISABLE_PROBES=vcpkg_cmake

twistedfall avatar Dec 03 '21 14:12 twistedfall

OPENCV_DISABLE_PROBES=vcpkg_cmake

This seems to be a working solution (no more link errors, and produces a working executable file)! Thank you!

Kazurin-775 avatar Dec 03 '21 14:12 Kazurin-775

Can you please also share the full build log of this successful build?

twistedfall avatar Dec 03 '21 14:12 twistedfall

Can you please also share the full build log of this successful build?

OK, here it is: clean-build-without-cmake.log

Kazurin-775 avatar Dec 03 '21 14:12 Kazurin-775

set OPENCV_DISABLE_PROBES=vcpkg_cmake before running

cargo clean
cargo build

won't work.

Any help?

clean-build.log

3togo avatar Apr 14 '23 03:04 3togo

@3togo I'm sorry, but I'm afraid that your issue is not related to mine. Your build log states that:

[opencv 0.78.2] === Probing OpenCV library using vcpkg
[opencv 0.78.2] === Can't probe using: vcpkg, continuing with other methods because: Could not find library in Vcpkg tree package opencv4 is not installed for vcpkg triplet x64-windows-static-md, Could not find library in Vcpkg tree package opencv3 is not installed for vcpkg triplet x64-windows-static-md

Therefore, you may have forgotten to install opencv4:x64-windows-static-md, or you may have to set VCPKGRS_DYNAMIC = 1 if you prefer to link against the DLL version, as stated in this project's README.md.

Kazurin-775 avatar Apr 14 '23 04:04 Kazurin-775

@Kazurin-775 ,

Setting VCPKGRS_DYNAMIC = 1 can fix the problem.

many thanks.

@3togo I'm sorry, but I'm afraid that your issue is not related to mine. Your build log states that:

[opencv 0.78.2] === Probing OpenCV library using vcpkg
[opencv 0.78.2] === Can't probe using: vcpkg, continuing with other methods because: Could not find library in Vcpkg tree package opencv4 is not installed for vcpkg triplet x64-windows-static-md, Could not find library in Vcpkg tree package opencv3 is not installed for vcpkg triplet x64-windows-static-md

Therefore, you may have forgotten to install opencv4:x64-windows-static-md, or you may have to set VCPKGRS_DYNAMIC = 1 if you prefer to link against the DLL version, as stated in this project's README.md.

3togo avatar Apr 14 '23 09:04 3togo