[CMake] How to specify debug version of CRT library for Visual Studio generator?

David Aldrich david.aldrich.ntml at gmail.com
Wed Jun 19 05:29:12 EDT 2019


>
> > On Tue, Jun 18, 2019 at 3:07 PM Eric Dönges <doenges at mvtec.com> wrote:
> > On 18.06.19 12:53, David Aldrich wrote:
> > > I have a simple CMake project that builds an executable using Visual
> > > Studio 2017:
> >
> >
> > >
> > > ################ Files ################
> > > #   --   Add files to project.   --   #
> > > #######################################
> > >
> > > file(GLOB SRC_FILES
> > >     ${CPP_DIR_1}/*.cpp
> > >     ${CPP_DIR_2}/*.cpp
> > >     ${CPP_DIR_3}/*.cpp
> > >     ${CPP_DIR_4}/*.cpp
> > >     ${HEADER_DIR_1}/*.h
> > > )
> > >
> > > # Add executable to build.
> > > add_executable(${PROJECT_NAME}
> > >    ${SRC_FILES}
> > > )
> > >
> > > if(MSVC)
> > >    target_link_libraries(${PROJECT_NAME} ws2_32.lib )
> > > endif(MSVC)
> > >
> > > #=====================================
> > >
> > > The Release build succeeds but the Debug build fails with linker errors
> > > such as:
> > >
> > > [build] CPlaneTest.obj : error LNK2001: unresolved external symbol
> > > __imp___CrtDbgReport
> > >
> > > I think this is because the linker is not using the debug version of
> CRT
> > > (C Run-time Library).
> > >
> > > Should CMake select the debug build of CRT automatically or do I need
> to
> > > specify it manually? If so, should I do so using
> CMAKE_EXE_LINKER_FLAGS?
> > >
> >
> > CMake will select the correct CRT automatically if you let it (unless
> > you want the static CRT, in which case you have to override CMake's
> > default settings). You are setting your CMAKE_CXX_FLAGS_DEBUG
> incorrectly:
> >
> > > if(MSVC)
> > >    #set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D _DEBUG /W3
> > > /MD /Od /Zi /EHsc")
> > >    set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /GL /Od
> > > /Oi /Gy /Zi /EHsc")
> > >    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_RELEASE} /D _DEBUG /W3
> > > /GL /Od /Oi /Gy /Zi /EHsc")
> > > endif(MSVC)
> >
> > In case of the setting you've commented out, you are explicitly telling
> > CMake to use /MD. CMAKE_CXX_FLAGS_DEBUG should already contain /MDd, but
> > since you append the /MD, that is what the compiler will actually use.
> >
> > For the setting that is not commented out, you set CMAKE_CXX_FLAGS_DEBUG
> > to the contents of CMAKE_CXX_FLAGS_RELEASE - which is certainly not what
> > you want (and also specifies /MD).
> >
> > I would suggest looking at what flags CMake sets by default (look at the
> > Windows-MSVC.cmake file in CMake's 'Modules/Platform' directory) and
> > only setting those flags that CMake doesn't already. For version 3.14,
> > CMake should be setting the following flags for CMAKE_CXX_FLAGS_DEBUG by
> > default (assuming you are using MVSC >= 1310, no Clang toolset):
> >
> >         /MDd /Zi /Ob0 /Od /GR /EHSC
> >
> > So in your case, it would probably be enough to
> >
> >         string(APPEND CMAKE_CXX_FLAGS_DEBUG " /D_DEBUG /W3")
> >
> > As a final recommendation, use string(APPEND <var> ...) (or list(APPEND
> > <list> ...), if the variable is interpreted as a list) when appending
> > values to existing variables. This makes your intent clearer.
> >
> >
> >  - when appending compiler flags, use the "string(APPEND ...)" command
> > to make is clearer what you are doing).
>
> Thanks for your help and advice. I've followed your suggestions and the
> debug
> and release builds are now working correctly. I produced my CMakeLists.txt
> from
> a Visual Studio solution using a conversion utility. I will need to rework
> it to adopt best practices.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20190619/0b8cc69d/attachment.html>


More information about the CMake mailing list