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