UseDebugLibraries and Wrong Defaults for VC++ Project Properties

Many of the projects I’m working on seem to have wrong default properties in Debug configuration.  For example, ‘Runtime Library’ is explicitly set to /MDd but defaults to /MD. ‘Basic Runtime Checks’ is explicitly set to /RTC1 but defaults to  none. ‘Optimization’ is explicitly set to /Od but defaults to /O2, and so on:

image

image

This recently caused us some trouble, and the investigation results are dumped below.

The direct reason is that these vcxproj’s are missing the ‘UseDebugLibraries’ element, under the ‘Configuration’ PropertyGroup: it should be set to true in Debug and false in Release.   A correct vcxproj should include some elements like –

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    <ConfigurationType>StaticLibrary</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v120</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <ConfigurationType>StaticLibrary</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>v120</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

Most ‘Configuration’ sub-elements (CharacterSet, ConfigurationType etc.) directly control import of custom property sheets, but UseDebugLibraries doesn’t. Instead, it is expected in various hooks around regular property sheets. For example, Microsoft.Cpp.mfcDynamic.props includes the following –

<ClCompile>
<RuntimeLibrary Condition="'$(UseDebugLibraries)' != 'true'">MultiThreadedDll</RuntimeLibrary>
<RuntimeLibrary Condition="'$(UseDebugLibraries)' == 'true'">MultiThreadedDebugDll</RuntimeLibrary>
</ClCompile>

Why UseDebugLibraries was missing from some libraries and present in others remained a mystery until I noticed that the younger libraries tended to have this element. Indeed, the real culprit is the migration from VS2008- (vcproj format) to VS2010+ (vcxproj/MSBuild format).  MS’s migration code just did not add this element. The generated projects are functional – they just explicitly set every individual compilation switch affected by UseDebugLibraries, which makes it overly verbose and a bit sensitive – especially in the presence of junior devs who tend to stick to defaults…

So every library you have which is 4Y+ old is susceptible to this migration bug, and I suggest you manually add UseDebugLibraries.  If you have a central prop sheet where you can control multiple projects – add it there.

Not much point in reporting this to MS, is there? The chances of a fix are practically zero, and the issue would get equal web-presence here.

This entry was posted in MSBuild, VC++. Bookmark the permalink.

5 Responses to UseDebugLibraries and Wrong Defaults for VC++ Project Properties

  1. John Schroedl says:

    I just checked and that element is missing in some of our projects too. And sure enough, those were migrated from old projects. I’ve seen and wondered about the bold (ie. non-default) highlight on a few of those settings over the years. But since they were correct settings I didn’t investigate more deeply. Thanks Ofek!

  2. Alexander Stohr says:

    Thanks for your article.
    It was definitely relevant as certain items are not compatible between debug and release. These might be std::string and maybe even the exception management.

  3. logischdede says:

    Thanks for your article.
    Its relevant because a build mixed from debug and release items can fail badly on you.
    Probably incompatible items between the two variants are std::string and exception handling.

  4. Steve says:

    Thank you for this.
    I was having the same problem and still cannot find any other article on the internet describing it.
    Does anyone know if there is a way to modify UseDebugLibraries from the GUI? I do not mind editing the file directly, but I am amazed that this item effects defaults but cannot be edited through visual studio. It seems to be an important distinction between release and debug configurations.

    I tried creating a new blank project in Visual Studio 2017 and sure enough the release configuration has false while debug has true. I then tried creating a new empty configuration and that element was absent. It seems the only way to create a new configuration which has the value true is to select the debug configuration for the Copy Settings From option.

    This really puzzles me. Does MS expect that the effect of having the wrong value for UseDebugLibraries will be trivial, or that all of us developers will find this obscurity?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s