twistedfall / opencv-rust

Rust bindings for OpenCV 3 & 4
MIT License
1.86k stars 144 forks source link

Cannot link against vcpkg debug libraries on Windows #307

Closed Kazurin-775 closed 2 months ago

Kazurin-775 commented 2 years ago

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?

twistedfall commented 2 years ago

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.

Kazurin-775 commented 2 years ago

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

OK, here you go: clean-build.log

twistedfall commented 2 years ago

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
Kazurin-775 commented 2 years ago
OPENCV_DISABLE_PROBES=vcpkg_cmake

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

twistedfall commented 2 years ago

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

Kazurin-775 commented 2 years ago

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

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

3togo commented 1 year ago

set OPENCV_DISABLE_PROBES=vcpkg_cmake before running

cargo clean
cargo build

won't work.

Any help?

clean-build.log

Kazurin-775 commented 1 year ago

@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 commented 1 year ago

@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.

twistedfall commented 2 months ago

@Kazurin-775 This task is quite old, I'm going to close it in the hope that you don't have this problem any more, but feel free to reopen in case it's not true.

Kazurin-775 commented 2 months ago

Yes, I haven't been using OpenCV for quite a long time... :(

Just took some time to play around, it looks like that with $env:VCPKGRS_DYNAMIC = '1' the build process is working perfectly now. Without $env:VCPKGRS_DYNAMIC = '1' I encountered the same problem as #340 , and I have yet no idea how to fix it. But anyway, this one should be different from what I reported 2 years ago.

Thank you for your hard work :)

twistedfall commented 2 months ago

Well, we managed to solve it in that issue, so I suppose keep googling the symbol and add the dependencies as mentioned in that issue :)

Kazurin-775 commented 2 months ago

Yeah, I got that working for me too. The correct setting for me is:

$env:OPENCV_LINK_LIBS = '+user32,gdi32,comdlg32'

(I suppose that this value could be set as the default, as these 3 libraries seem to be the hard dependencies of OpenCV?)

twistedfall commented 2 months ago

Probably worth adding to the troubleshooting at least, thank you for checking!