VS: Add option for per-target PlatformToolset

Add a `VS_PLATFORM_TOOLSET` target property to set `PlatformToolset` in
the `.vcxproj` file for specific targets.  Document that this is safe
only when the named toolset uses the same underlying compiler as the
primary toolset.

Fixes: #17429
This commit is contained in:
Julien Jemine
2020-04-28 16:55:03 +02:00
committed by Brad King
parent 73f81c5070
commit 197b4cbe18
7 changed files with 68 additions and 2 deletions

View File

@@ -372,6 +372,7 @@ Properties on Targets
/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION
/prop_tgt/VS_NO_SOLUTION_DEPLOY
/prop_tgt/VS_PACKAGE_REFERENCES
/prop_tgt/VS_PLATFORM_TOOLSET
/prop_tgt/VS_PROJECT_IMPORT
/prop_tgt/VS_SCC_AUXPATH
/prop_tgt/VS_SCC_LOCALPATH

View File

@@ -0,0 +1,10 @@
VS_PLATFORM_TOOLSET
-------------------
Overrides the platform toolset used to build a target.
Only supported when the compiler used by the given toolset is the
same as the compiler used to build the whole source tree.
This is especially useful to create driver projects with the toolsets
"WindowsUserModeDriver10.0" or "WindowsKernelModeDriver10.0".

View File

@@ -0,0 +1,6 @@
vs-platform-toolset
-------------------
* The :prop_tgt:`VS_PLATFORM_TOOLSET` target property was added to tell
:ref:`Visual Studio Generators` for VS 2010 and above to override
the platform toolset.

View File

@@ -1236,7 +1236,10 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValues(
} else {
e1.Element("CharacterSet", "MultiByte");
}
if (const char* toolset = gg->GetPlatformToolset()) {
if (const char* projectToolsetOverride =
this->GeneratorTarget->GetProperty("VS_PLATFORM_TOOLSET")) {
e1.Element("PlatformToolset", projectToolsetOverride);
} else if (const char* toolset = gg->GetPlatformToolset()) {
e1.Element("PlatformToolset", toolset);
}
if (this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT") ||
@@ -1279,7 +1282,10 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged(
o.RemoveFlag("Platform");
}
if (const char* toolset = gg->GetPlatformToolset()) {
if (const char* projectToolsetOverride =
this->GeneratorTarget->GetProperty("VS_PLATFORM_TOOLSET")) {
e1.Element("PlatformToolset", projectToolsetOverride);
} else if (const char* toolset = gg->GetPlatformToolset()) {
e1.Element("PlatformToolset", toolset);
}

View File

@@ -33,6 +33,7 @@ run_cmake(VsPrecompileHeadersReuseFromCompilePDBName)
run_cmake(VsDeployEnabled)
run_cmake(VsSettings)
run_cmake(VsSourceSettingsTool)
run_cmake(VsPlatformToolset)
run_cmake(VsWinRTByDefault)

View File

@@ -0,0 +1,36 @@
macro(ReadPlatformToolset tgt outvar)
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_PlatformToolset 0)
file(STRINGS "${vcProjectFile}" lines)
foreach(line IN LISTS lines)
if(line MATCHES "^ *<PlatformToolset>([^<>]+)</PlatformToolset>")
set(${outvar} "${CMAKE_MATCH_1}")
set(HAVE_PlatformToolset 1)
break()
endif()
endforeach()
if(NOT HAVE_PlatformToolset)
set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not have a <PlatformToolset> field.")
return()
endif()
endmacro()
ReadPlatformToolset(NormalPlatformToolset NORMAL_TOOLSET)
ReadPlatformToolset(OverridenPlatformToolset OVERRIDEN_TOOLSET)
if (NOT "${OVERRIDEN_TOOLSET}" STREQUAL "MyCustomToolset")
set(RunCMake_TEST_FAILED "Failed to override the platform toolset")
return()
endif()
if ("${NORMAL_TOOLSET}" STREQUAL "MyCustomToolset")
set(RunCMake_TEST_FAILED "Main toolset was overriden (it shouldn't)")
return()
endif()

View File

@@ -0,0 +1,6 @@
enable_language(CXX)
add_library(NormalPlatformToolset foo.cpp)
add_library(OverridenPlatformToolset foo.cpp)
set_target_properties(OverridenPlatformToolset
PROPERTIES VS_PLATFORM_TOOLSET MyCustomToolset)