Can I use a Release config of OpenCV with Debug config of my app?
Asked Answered
H

3

10

I am writing a Universal Windows application that uses OpenCV to do camera calibration and tag detection, among other things.

I'd like to be able to use release mode, fully-optimized OpenCV DLLs while my own is in debug mode. Is this possible? If so, how do I configure CMake to make it happen?

I do want to debug my own application, naturally. However, I do not want to debug OpenCV itself. I do not want to deal with the performance drop of an OpenCV debug build, even while I'm debugging my own project. I do not want to deal with the overhead of the additional libs and dlls, and setting up my build configuration properly (this is part of a larger project, including a Unity app, so build configuration is a significant issue).

I'm using OpenCV DLLs, not static libs, so issues of differences in implementations of the STD library, etc. should not make any difference (unless OpenCV is passing those across the DLL boundary... which would be naughty indeed). Yet, when I try to build my app in Debug mode, while referencing OpenCV Release DLLs, I encounter the debug_build_guard:

error LNK2019: unresolved external symbol "bool __cdecl cv::imencode(class cv::String const &,class cv::debug_build_guard::_InputArray const &,...

It seems like what I want would be a really common use case. Unfortunately I can't seem to find anything about it anywhere. Thanks for any help!

Hooray answered 7/11, 2017 at 20:18 Comment(7)
Perhaps this is what you are looking for: #24262581Vitality
Can you show your CMakeLists, how you are finding the OpenCV libraries, how you are linking them to you app etc?Scrope
I start with the default CMakeLists in the OpenCV Repo. My modifications: CMAKE_SYSTEM_NAME=WindowsStore CMAKE_SYSTEM_VERSION=10.0 RelWithDebInfo does not sound like what I'm looking for at all, though I will try it. It sounds like it's exactly the same as Release, but generates a PDB.Hooray
thank you both for your help, but atm the way OpenCV is set up I do not believe that it's possible to do what I'm looking for. In either case, we decided to switch to static libraries rather than dynamic. It simplifies our overall build configuration logic, but concedes any potential to avoid using debug builds of OpenCV. Oh well! Thanks again. :)Hooray
P.S. I did try RelWithDebInfo, and as I suspected it's identical to Release with the exception that it produces a PDB.Hooray
@EvanLang Why did you need this in the first place? Was it because of the OpenCV is slower in debug? If so, did the static lib linking solve this?Horsey
Looking at the code in cvdef.h it seems that you can bypass the check by defining CV_IGNORE_DEBUG_BUILD_GUARD in your own project. But do so at your own risk, it's probably a bad idea to mix debug and release runtimes when using OpenCV if they added this check.Peavey
J
6

Add CV_IGNORE_DEBUG_BUILD_GUARD as one of the preprocessor definitions, which is defined in /path/to/opencv/opencv2/core/cvdef.h

Jiujitsu answered 15/8, 2021 at 10:53 Comment(1)
You can, but apparently it's a frequent source of problems: github.com/opencv/opencv/pull/9161Procurable
T
0

There are two kind of DLL/LIB in the build folder of the OpenCV.

Release DLL/LIB: In these files, the debug guard is activated. For example in version 4.01 the DLL is opencv_world401.dll and the associated LIB is opencv_world401.lib

Debug DLL/LIB: These are designed for debug perposes and the name of fine ends with d (e.g. opencv_world401d.dlland opencv_world401d.lib).

You need to add the debug DLL and the associated LIB to the Linker in the debug mode.

Instead of using CMAKE, I use #pragma to include my lib dynamically. Here is the method I used the preprocessor to solve this issue and load my lib dynamically.

#include <opencv2/opencv.hpp>            
#include "opencv2/core/version.hpp"
#include "opencv2/videoio/videoio.hpp"
#define OPENCV_VERSION CVAUX_STR(CV_VERSION_MAJOR)"" CVAUX_STR(CV_VERSION_MINOR)"" CVAUX_STR(CV_VERSION_REVISION)
#if NDEBUG 
#pragma comment(lib, "opencv_world" OPENCV_VERSION ".lib")
#else
#pragma comment(lib, "opencv_world" OPENCV_VERSION "d.lib")
#endif
Th answered 15/2, 2019 at 5:43 Comment(0)
G
0

For Release build configuration of the app you could disable optimizations. This would still pick the release opencvworld (build with full optimizations) from the un-optimized (Release CRT) app code. Using this we can step through the app's code line by line with full variable visibility. Something on the lines of below. The only thing that the default cmake Release flags differs in is I believe with the /O2 level optimizations as opposed to the /Od which we use here. I use it for debugging my app. I never do a debug build of my app and I never do a debug opencv build. Works fine.

if (WIN32)

  SET (CMAKE_CXX_FLAGS_RELEASE "/Zi /Od")

  SET_TARGET_PROPERTIES(
   xyz PROPERTIES 
   LINK_FLAGS 
   "/DEBUG /OPT:REF /OPT:ICF"
  )

endif (WIN32)
Gurias answered 16/9, 2020 at 15:16 Comment(1)
Putting the original condition in endif() has not been required for nearly 15 years.Axes

© 2022 - 2024 — McMap. All rights reserved.