mirror of
https://github.com/Kitware/CMake.git
synced 2026-03-13 12:59:55 -05:00
VS: Add [CMAKE_]VS_USE_DEBUG_LIBRARIES options to control UseDebugLibraries
This indicates to MSBuild which configurations are considered debug configurations. This is useful for reference both by humans and tools. Issue: #25327
This commit is contained in:
@@ -445,6 +445,7 @@ Properties on Targets
|
|||||||
/prop_tgt/VS_SDK_REFERENCES
|
/prop_tgt/VS_SDK_REFERENCES
|
||||||
/prop_tgt/VS_SOLUTION_DEPLOY
|
/prop_tgt/VS_SOLUTION_DEPLOY
|
||||||
/prop_tgt/VS_SOURCE_SETTINGS_tool
|
/prop_tgt/VS_SOURCE_SETTINGS_tool
|
||||||
|
/prop_tgt/VS_USE_DEBUG_LIBRARIES
|
||||||
/prop_tgt/VS_USER_PROPS
|
/prop_tgt/VS_USER_PROPS
|
||||||
/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
|
/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
|
||||||
/prop_tgt/VS_WINRT_COMPONENT
|
/prop_tgt/VS_WINRT_COMPONENT
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ Variables that Provide Information
|
|||||||
/variable/CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER
|
/variable/CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER
|
||||||
/variable/CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION
|
/variable/CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION
|
||||||
/variable/CMAKE_VS_TARGET_FRAMEWORK_VERSION
|
/variable/CMAKE_VS_TARGET_FRAMEWORK_VERSION
|
||||||
|
/variable/CMAKE_VS_USE_DEBUG_LIBRARIES
|
||||||
/variable/CMAKE_VS_VERSION_BUILD_NUMBER
|
/variable/CMAKE_VS_VERSION_BUILD_NUMBER
|
||||||
/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
|
/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
|
||||||
/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
|
/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
|
||||||
|
|||||||
18
Help/prop_tgt/VS_USE_DEBUG_LIBRARIES-PURPOSE.txt
Normal file
18
Help/prop_tgt/VS_USE_DEBUG_LIBRARIES-PURPOSE.txt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
Indicate to :ref:`Visual Studio Generators` what configurations are considered
|
||||||
|
debug configurations. This controls the ``UseDebugLibraries`` setting in
|
||||||
|
each configuration of a ``.vcxproj`` file.
|
||||||
|
|
||||||
|
The "Use Debug Libraries" setting in Visual Studio projects, despite its
|
||||||
|
specific-sounding name, is a general-purpose indicator of what configurations
|
||||||
|
are considered debug configurations. In standalone projects, this may affect
|
||||||
|
MSBuild's default selection of MSVC runtime library, optimization flags,
|
||||||
|
runtime checks, and similar settings. In CMake projects those settings are
|
||||||
|
typically generated explicitly based on the project's specification, e.g.,
|
||||||
|
the MSVC runtime library is controlled by |MSVC_RUNTIME_LIBRARY|. However,
|
||||||
|
the ``UseDebugLibraries`` indicator is useful for reference by both humans
|
||||||
|
and tools, and may also affect the behavior of platform-specific SDKs.
|
||||||
|
|
||||||
|
Set |VS_USE_DEBUG_LIBRARIES| to a true or false value to indicate whether
|
||||||
|
each configuration is considered a debug configuration. The value may also
|
||||||
|
be the empty string (``""``) in which case no ``UseDebugLibraries`` will be
|
||||||
|
added explicitly by CMake, and MSBuild will use its default value, ``false``.
|
||||||
27
Help/prop_tgt/VS_USE_DEBUG_LIBRARIES.rst
Normal file
27
Help/prop_tgt/VS_USE_DEBUG_LIBRARIES.rst
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
VS_USE_DEBUG_LIBRARIES
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
.. versionadded:: 3.30
|
||||||
|
|
||||||
|
.. |VS_USE_DEBUG_LIBRARIES| replace:: ``VS_USE_DEBUG_LIBRARIES``
|
||||||
|
.. |MSVC_RUNTIME_LIBRARY| replace:: :prop_tgt:`MSVC_RUNTIME_LIBRARY`
|
||||||
|
|
||||||
|
.. include:: VS_USE_DEBUG_LIBRARIES-PURPOSE.txt
|
||||||
|
|
||||||
|
Use :manual:`generator expressions <cmake-generator-expressions(7)>`
|
||||||
|
for per-configuration specification. For example, the code:
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
add_executable(foo foo.c)
|
||||||
|
set_property(TARGET foo PROPERTY
|
||||||
|
VS_USE_DEBUG_LIBRARIES "$<CONFIG:Debug,Custom>")
|
||||||
|
|
||||||
|
indicates that target ``foo`` considers its "Debug" and "Custom"
|
||||||
|
configurations to be debug configurations, and its other configurations
|
||||||
|
to be non-debug configurations.
|
||||||
|
|
||||||
|
The property is initialized from the value of the
|
||||||
|
:variable:`CMAKE_VS_USE_DEBUG_LIBRARIES` variable, if it is set.
|
||||||
|
If the property is not set, then CMake does not generate any
|
||||||
|
``UseDebugLibraries`` indicator.
|
||||||
6
Help/release/dev/vs-UseDebugLibraries.rst
Normal file
6
Help/release/dev/vs-UseDebugLibraries.rst
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
vs-UseDebugLibraries
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
* The :variable:`CMAKE_VS_USE_DEBUG_LIBRARIES` variable and corresponding
|
||||||
|
:prop_tgt:`VS_USE_DEBUG_LIBRARIES` target property were added to explicitly
|
||||||
|
control ``UseDebugLibraries`` indicators in ``.vcxproj`` files.
|
||||||
28
Help/variable/CMAKE_VS_USE_DEBUG_LIBRARIES.rst
Normal file
28
Help/variable/CMAKE_VS_USE_DEBUG_LIBRARIES.rst
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
CMAKE_VS_USE_DEBUG_LIBRARIES
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
.. versionadded:: 3.30
|
||||||
|
|
||||||
|
.. |VS_USE_DEBUG_LIBRARIES| replace:: ``CMAKE_VS_USE_DEBUG_LIBRARIES``
|
||||||
|
.. |MSVC_RUNTIME_LIBRARY| replace:: :variable:`CMAKE_MSVC_RUNTIME_LIBRARY`
|
||||||
|
|
||||||
|
.. include:: ../prop_tgt/VS_USE_DEBUG_LIBRARIES-PURPOSE.txt
|
||||||
|
|
||||||
|
Use :manual:`generator expressions <cmake-generator-expressions(7)>`
|
||||||
|
for per-configuration specification. For example, the code:
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
set(CMAKE_VS_USE_DEBUG_LIBRARIES "$<CONFIG:Debug,Custom>")
|
||||||
|
|
||||||
|
indicates that all following targets consider their "Debug" and "Custom"
|
||||||
|
configurations to be debug configurations, and their other configurations
|
||||||
|
to be non-debug configurations.
|
||||||
|
|
||||||
|
This variable is used to initialize the :prop_tgt:`VS_USE_DEBUG_LIBRARIES`
|
||||||
|
property on all targets as they are created. It is also propagated by
|
||||||
|
calls to the :command:`try_compile` command into its test project.
|
||||||
|
|
||||||
|
If this variable is not set then the :prop_tgt:`VS_USE_DEBUG_LIBRARIES`
|
||||||
|
property will not be set automatically. If that property is not set
|
||||||
|
then CMake does not generate any ``UseDebugLibraries`` indicator.
|
||||||
@@ -1151,6 +1151,7 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
|
|||||||
vars.emplace("CMAKE_WATCOM_RUNTIME_LIBRARY"_s);
|
vars.emplace("CMAKE_WATCOM_RUNTIME_LIBRARY"_s);
|
||||||
vars.emplace("CMAKE_MSVC_DEBUG_INFORMATION_FORMAT"_s);
|
vars.emplace("CMAKE_MSVC_DEBUG_INFORMATION_FORMAT"_s);
|
||||||
vars.emplace("CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS"_s);
|
vars.emplace("CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS"_s);
|
||||||
|
vars.emplace("CMAKE_VS_USE_DEBUG_LIBRARIES"_s);
|
||||||
|
|
||||||
if (cmValue varListStr = this->Makefile->GetDefinition(
|
if (cmValue varListStr = this->Makefile->GetDefinition(
|
||||||
kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {
|
kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {
|
||||||
|
|||||||
@@ -404,6 +404,7 @@ TargetProperty const StaticTargetProperties[] = {
|
|||||||
{ "VS_DEBUGGER_COMMAND_ARGUMENTS"_s, IC::ExecutableTarget },
|
{ "VS_DEBUGGER_COMMAND_ARGUMENTS"_s, IC::ExecutableTarget },
|
||||||
{ "VS_DEBUGGER_ENVIRONMENT"_s, IC::ExecutableTarget },
|
{ "VS_DEBUGGER_ENVIRONMENT"_s, IC::ExecutableTarget },
|
||||||
{ "VS_DEBUGGER_WORKING_DIRECTORY"_s, IC::ExecutableTarget },
|
{ "VS_DEBUGGER_WORKING_DIRECTORY"_s, IC::ExecutableTarget },
|
||||||
|
{ "VS_USE_DEBUG_LIBRARIES"_s, IC::NonImportedTarget },
|
||||||
// ---- OpenWatcom
|
// ---- OpenWatcom
|
||||||
{ "WATCOM_RUNTIME_LIBRARY"_s, IC::CanCompileSources },
|
{ "WATCOM_RUNTIME_LIBRARY"_s, IC::CanCompileSources },
|
||||||
// -- Language
|
// -- Language
|
||||||
|
|||||||
@@ -1622,6 +1622,25 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesCommon(
|
|||||||
} else if (const char* toolset = gg->GetPlatformToolset()) {
|
} else if (const char* toolset = gg->GetPlatformToolset()) {
|
||||||
e1.Element("PlatformToolset", toolset);
|
e1.Element("PlatformToolset", toolset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cm::optional<bool> maybeUseDebugLibraries;
|
||||||
|
if (cmValue useDebugLibrariesProp =
|
||||||
|
this->GeneratorTarget->GetProperty("VS_USE_DEBUG_LIBRARIES")) {
|
||||||
|
// The project explicitly specified a value for this target.
|
||||||
|
// An empty string suppresses generation of the setting altogether.
|
||||||
|
std::string const useDebugLibraries = cmGeneratorExpression::Evaluate(
|
||||||
|
*useDebugLibrariesProp, this->LocalGenerator, config);
|
||||||
|
if (!useDebugLibraries.empty()) {
|
||||||
|
maybeUseDebugLibraries = cmIsOn(useDebugLibraries);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (maybeUseDebugLibraries) {
|
||||||
|
if (*maybeUseDebugLibraries) {
|
||||||
|
e1.Element("UseDebugLibraries", "true");
|
||||||
|
} else {
|
||||||
|
e1.Element("UseDebugLibraries", "false");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -731,6 +731,7 @@ if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([^9]|9[0-9])")
|
|||||||
-DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
|
-DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
|
||||||
-DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION}
|
-DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION}
|
||||||
)
|
)
|
||||||
|
add_RunCMake_test(VS10ProjectUseDebugLibraries)
|
||||||
if( vs12 AND wince )
|
if( vs12 AND wince )
|
||||||
add_RunCMake_test( VS10ProjectWinCE "-DRunCMake_GENERATOR_PLATFORM=${wince_sdk}")
|
add_RunCMake_test( VS10ProjectWinCE "-DRunCMake_GENERATOR_PLATFORM=${wince_sdk}")
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.29)
|
||||||
|
project(${RunCMake_TEST} NONE)
|
||||||
|
include(${RunCMake_TEST}.cmake)
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/check-common.cmake)
|
||||||
|
|
||||||
|
UseDebugLibraries_check(default "" "")
|
||||||
|
UseDebugLibraries_check(defaultCLR "" "")
|
||||||
|
UseDebugLibraries_check(defaultUtil "" "")
|
||||||
|
UseDebugLibraries_check(defaultRTL "" "")
|
||||||
|
UseDebugLibraries_check(ALL_BUILD "" "")
|
||||||
|
UseDebugLibraries_check(ZERO_CHECK "" "")
|
||||||
10
Tests/RunCMake/VS10ProjectUseDebugLibraries/Default.cmake
Normal file
10
Tests/RunCMake/VS10ProjectUseDebugLibraries/Default.cmake
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
set(CMAKE_CONFIGURATION_TYPES Debug Release)
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
# Test several generator code paths covering different target types.
|
||||||
|
add_library(default empty.cxx)
|
||||||
|
add_library(defaultCLR empty.cxx)
|
||||||
|
set_property(TARGET defaultCLR PROPERTY COMMON_LANGUAGE_RUNTIME "")
|
||||||
|
add_library(defaultRTL empty.cxx)
|
||||||
|
set_property(TARGET defaultRTL PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
|
||||||
|
add_custom_target(defaultUtil)
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/check-common.cmake)
|
||||||
|
|
||||||
|
UseDebugLibraries_check(empty "" "")
|
||||||
|
UseDebugLibraries_check(emptyCLR "" "")
|
||||||
|
UseDebugLibraries_check(emptyUtil "" "")
|
||||||
|
UseDebugLibraries_check(genex "true" "false")
|
||||||
|
UseDebugLibraries_check(genexCLR "true" "false")
|
||||||
|
UseDebugLibraries_check(genexUtil "true" "false")
|
||||||
|
UseDebugLibraries_check(ALL_BUILD "false" "false")
|
||||||
|
UseDebugLibraries_check(ZERO_CHECK "false" "false")
|
||||||
20
Tests/RunCMake/VS10ProjectUseDebugLibraries/Explicit.cmake
Normal file
20
Tests/RunCMake/VS10ProjectUseDebugLibraries/Explicit.cmake
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
set(CMAKE_CONFIGURATION_TYPES Debug Release)
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
# An empty string suppresses generation of the setting.
|
||||||
|
set(CMAKE_VS_USE_DEBUG_LIBRARIES "")
|
||||||
|
add_library(empty empty.cxx)
|
||||||
|
add_library(emptyCLR empty.cxx)
|
||||||
|
set_property(TARGET emptyCLR PROPERTY COMMON_LANGUAGE_RUNTIME "")
|
||||||
|
add_custom_target(emptyUtil)
|
||||||
|
|
||||||
|
# A generator expression can encode per-config values.
|
||||||
|
set(CMAKE_VS_USE_DEBUG_LIBRARIES "$<CONFIG:Debug>")
|
||||||
|
add_library(genex empty.cxx)
|
||||||
|
add_library(genexCLR empty.cxx)
|
||||||
|
set_property(TARGET genexCLR PROPERTY COMMON_LANGUAGE_RUNTIME "")
|
||||||
|
add_custom_target(genexUtil)
|
||||||
|
|
||||||
|
# The last setting in the top-level directcory affects
|
||||||
|
# the builtin targets like ALL_BUILD and ZERO_CHECK.
|
||||||
|
set(CMAKE_VS_USE_DEBUG_LIBRARIES 0)
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.29)
|
||||||
|
include(RunCMake)
|
||||||
|
|
||||||
|
run_cmake(Default)
|
||||||
|
run_cmake(Explicit)
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
cmake_policy(SET CMP0140 NEW)
|
||||||
|
function(UseDebugLibraries_check tgt udl_expect_debug udl_expect_release)
|
||||||
|
set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/${tgt}.vcxproj")
|
||||||
|
if(NOT EXISTS "${vcProjectFile}")
|
||||||
|
set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not exist.")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(have_udl_debug 0)
|
||||||
|
set(have_udl_release 0)
|
||||||
|
set(inConfig "")
|
||||||
|
|
||||||
|
file(STRINGS "${vcProjectFile}" lines)
|
||||||
|
foreach(line IN LISTS lines)
|
||||||
|
if(line MATCHES [[^ *<PropertyGroup Condition="'\$\(Configuration\)\|\$\(Platform\)'=='([^"|]+)\|[^"]+" Label="Configuration">.*$]])
|
||||||
|
string(TOLOWER "${CMAKE_MATCH_1}" inConfig)
|
||||||
|
elseif(inConfig)
|
||||||
|
if(line MATCHES "^ *</PropertyGroup>.*$")
|
||||||
|
set(inConfig "")
|
||||||
|
elseif(line MATCHES "^ *<UseDebugLibraries>([^<>]+)</UseDebugLibraries>")
|
||||||
|
set(udl_actual "${CMAKE_MATCH_1}")
|
||||||
|
set(have_udl_${inConfig} 1)
|
||||||
|
if (NOT "${udl_expect_${inConfig}}" STREQUAL "")
|
||||||
|
if(NOT "${udl_actual}" STREQUAL "${udl_expect_${inConfig}}")
|
||||||
|
string(APPEND RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj has ${inConfig} UseDebugLibraries '${udl_actual}', not '${udl_expect_${inConfig}}'.\n")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
string(APPEND RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj has ${inConfig} UseDebugLibraries '${udl_actual}', but should not have one.\n")
|
||||||
|
endif()
|
||||||
|
unset(udl_actual)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
if(NOT have_udl_debug AND NOT "${udl_expect_debug}" STREQUAL "")
|
||||||
|
string(APPEND RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not have a debug UseDebugLibraries field, but should have one.\n")
|
||||||
|
endif()
|
||||||
|
if(NOT have_udl_release AND NOT "${udl_expect_release}" STREQUAL "")
|
||||||
|
string(APPEND RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not have a release UseDebugLibraries field, but should have one.\n")
|
||||||
|
endif()
|
||||||
|
return(PROPAGATE RunCMake_TEST_FAILED)
|
||||||
|
endfunction()
|
||||||
Reference in New Issue
Block a user