CMake RelWithDebInfo links to Debug libs
Asked Answered
H

5

12

I have a project which links to half a dozen libraries, among them OpenCV.
Since Release variant is crashing, while Debug is working fine (just a lot slower), I wanted to compile my project in RelWithDebInfo configuration.
However, Debug version of OpenCV libraries gets included instead of Release (OpenCV doesn’t have RelWithDebInfo variant). This causes linking errors such as:

opencv_core249d.lib(alloc.obj) : error LNK2038: mismatch detected for ‘RuntimeLibrary’: value ‘MDd_DynamicDebug’ doesn’t match value ‘MD_DynamicRelease’ in MyProject.obj

How to solve this problem?

Haematocryal answered 17/6, 2014 at 11:0 Comment(2)
I solve this by never using the INSTALL target in windows. Instead point the PROJECTNAME_DIR variables to the root folder where you built the library. I also build all dependencies with the compiler I am using and never use binary packages. If you build opencv from source does it still eliminate the RelWithDebInfo configuration?Stefan
I have built OpenCV from source. I did not have this problem with pre-compiled OpenCV.Intensify
H
22

Solution: add to CMakeLists.txt, after the call to FIND_PACKAGE(OpenCV):

set_target_properties(${OpenCV_LIBS} PROPERTIES MAP_IMPORTED_CONFIG_RELWITHDEBINFO RELEASE)
Haematocryal answered 25/6, 2014 at 8:13 Comment(3)
This saved me a lot of searching and work. Thanks :)Drudgery
This works most of the time for me but some of the targets still come through as debug libraries. I've listed every single possible opencv target to make sure it also gets dependent targets.Exalted
@DanielMoodie how did you do that? The latest version of OpenCV requires protobuf dependency (opencv_dnn module). Regardless of how I configure MAP_IMPORTED_CONFIG it still tries to link Debug protobuf to my RelWithDebInfo build.Periclean
E
3

I've used the above answer by Dženan but found that some opencv libraries ignore this and still link debug! This results in an msvc project that links mixed release and debug libraries for opencv. My solution was to create a new OpenCVModules-relwithdebinfo.cmake in your the opencv installation's lib dir, which is a copy of the OpenCVModules-release.cmake file. Then replacing all references to RELEASE with RELWITHDEBINFO. This produces a msvc project linking entirely to opencv release libs. The added benefit is that you don't need to change your project's CMake files to account for this.

Exalted answered 18/1, 2016 at 4:18 Comment(2)
Have you submitted a bug report for CMake? It is better to solve a problem than work around it, which is what you suggest.Intensify
I can't be sure if this is a CMake problem or a problem with OpenCV's CMake scripts. I'm still investigating further when I have time.Exalted
L
1

I also had this issue; but None of the answers above solved it.

Eventually I solved it by putting these two lines at the start of my CMakeLists.txt:

cmake_policy(SET CMP0091 NEW)
# Make the project use static libraries (*.lib) instead of DLLs.
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Release>")

I think $CONFIG:Debug:Release is doing the magic...

Gr,

Michiel

Laryngo answered 14/3, 2023 at 13:3 Comment(0)
G
0

you could disable level 2 optimizations with the default cmake release build using the below snippet. This would still pick release opencvworld (build with full optimizations) from the un-optimized (yet Release) app code. Using this we can step through the app's code line-by-line with full variable visibility.. as good as the debug build minus the need to link with debug opencv or mixing the CRTs or doing a full debug build of all components involved.

if (WIN32)

  SET (CMAKE_CXX_FLAGS_RELEASE "/Zi /Od")

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

endif (WIN32)
Gastrovascular answered 16/9, 2020 at 15:25 Comment(0)
W
0

I really had problems with the "3rd Party libs" / OpenCVModules. @dženan 's Answer lead me into the right direction, but his solution didn't work out for me, however, adding this line before using FIND_PACKAGE solved my problem:

SET(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO "RelWithDebInfo;Release;")

Be aware, it will set a fallback to Release for everything.

Whitsuntide answered 31/3, 2022 at 9:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.