VS: Add support to override VCTargetsPath through toolset

Fixes: #19708
This commit is contained in:
Alexander Boczar
2019-09-16 14:14:20 -07:00
committed by Brad King
parent 99e83d4235
commit 548e9051a4
13 changed files with 99 additions and 1 deletions

View File

@@ -0,0 +1,6 @@
vs-vctargetspath
----------------
* With :ref:`Visual Studio Generators` for VS 2010 and above,
the :variable:`CMAKE_GENERATOR_TOOLSET` setting gained an option
to specify the ``VCTargetsPath`` value for project files.

View File

@@ -58,3 +58,8 @@ Supported pairs are:
Specify the toolset version to use. Supported by VS 2017
and above with the specified toolset installed.
See the :variable:`CMAKE_VS_PLATFORM_TOOLSET_VERSION` variable.
``VCTargetsPath=<path>``
Specify an alternative ``VCTargetsPath`` value for Visual Studio
project files. This allows use of VS platform extension configuration
files (``.props`` and ``.targets``) that are not installed with VS.

View File

@@ -317,6 +317,9 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION)
set(id_WindowsTargetPlatformVersion "<WindowsTargetPlatformVersion>${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}</WindowsTargetPlatformVersion>")
endif()
if(CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR)
set(id_ToolsetVCTargetsDir "<VCTargetsPath>${CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR}</VCTargetsPath>")
endif()
if(id_platform STREQUAL ARM64)
set(id_WindowsSDKDesktopARMSupport "<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>")
elseif(id_platform STREQUAL ARM)

View File

@@ -15,6 +15,7 @@
@id_WindowsTargetPlatformVersion@
@id_WindowsSDKDesktopARMSupport@
@id_CudaToolkitCustomDir@
@id_ToolsetVCTargetsDir@
</PropertyGroup>
@id_toolset_version_props@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

View File

@@ -26,6 +26,16 @@
static const char vs10generatorName[] = "Visual Studio 10 2010";
static std::map<std::string, std::vector<cmIDEFlagTable>> loadedFlagJsonFiles;
static void ConvertToWindowsSlashes(std::string& s)
{
// first convert all of the slashes
for (auto& ch : s) {
if (ch == '/') {
ch = '\\';
}
}
}
// Map generator name without year to name with year.
static const char* cmVS10GenName(const std::string& name, std::string& genName)
{
@@ -212,7 +222,7 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
return true;
}
if (!this->FindVCTargetsPath(mf)) {
if (this->CustomVCTargetsPath.empty() && !this->FindVCTargetsPath(mf)) {
return false;
}
@@ -353,6 +363,11 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
if (const char* cudaDir = this->GetPlatformToolsetCudaCustomDir()) {
mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR", cudaDir);
}
if (const char* vcTargetsDir = this->GetCustomVCTargetsPath()) {
mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR",
vcTargetsDir);
}
return true;
}
@@ -446,6 +461,11 @@ bool cmGlobalVisualStudio10Generator::ProcessGeneratorToolsetField(
this->GeneratorToolsetVersion = value;
return true;
}
if (key == "VCTargetsPath") {
this->CustomVCTargetsPath = value;
ConvertToWindowsSlashes(this->CustomVCTargetsPath);
return true;
}
return false;
}
@@ -607,6 +627,14 @@ void cmGlobalVisualStudio10Generator::EnableLanguage(
cmGlobalVisualStudio8Generator::EnableLanguage(lang, mf, optional);
}
const char* cmGlobalVisualStudio10Generator::GetCustomVCTargetsPath() const
{
if (this->CustomVCTargetsPath.empty()) {
return nullptr;
}
return this->CustomVCTargetsPath.c_str();
}
const char* cmGlobalVisualStudio10Generator::GetPlatformToolset() const
{
std::string const& toolset = this->GetPlatformToolsetString();

View File

@@ -46,6 +46,9 @@ public:
bool IsNsightTegra() const;
std::string GetNsightTegraVersion() const;
/** The vctargets path for the target platform. */
const char* GetCustomVCTargetsPath() const;
/** The toolset name for the target platform. */
const char* GetPlatformToolset() const;
std::string const& GetPlatformToolsetString() const;
@@ -156,6 +159,7 @@ protected:
std::string GeneratorToolset;
std::string GeneratorToolsetVersion;
std::string GeneratorToolsetHostArchitecture;
std::string GeneratorToolsetCustomVCTargetsDir;
std::string GeneratorToolsetCuda;
std::string GeneratorToolsetCudaCustomDir;
std::string DefaultPlatformToolset;
@@ -207,6 +211,7 @@ private:
bool ParseGeneratorToolset(std::string const& ts, cmMakefile* mf);
std::string CustomVCTargetsPath;
std::string VCTargetsPath;
bool FindVCTargetsPath(cmMakefile* mf);

View File

@@ -543,6 +543,11 @@ void cmVisualStudio10TargetGenerator::Generate()
e1.Element("VCProjectUpgraderObjectName", "NoUpgrade");
}
if (const char* vcTargetsPath =
this->GlobalGenerator->GetCustomVCTargetsPath()) {
e1.Element("VCTargetsPath", vcTargetsPath);
}
std::vector<std::string> keys = this->GeneratorTarget->GetPropertyKeys();
for (std::string const& keyIt : keys) {
static const char* prefix = "VS_GLOBAL_";

View File

@@ -30,6 +30,8 @@ if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012456]")
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64,host=x86")
run_cmake(BadToolsetHostArchTwice)
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[56]")
set(RunCMake_GENERATOR_TOOLSET "VCTargetsPath=Test Path")
run_cmake(TestToolsetVCTargetsPathOnly)
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,version=Test Toolset Version")
run_cmake(TestToolsetVersionBoth)
set(RunCMake_GENERATOR_TOOLSET ",version=Test Toolset Version")

View File

@@ -0,0 +1,2 @@
-- CMAKE_VS_PLATFORM_TOOLSET='v[0-9]+'
-- CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR='Test Path'

View File

@@ -0,0 +1,2 @@
message(STATUS "CMAKE_VS_PLATFORM_TOOLSET='${CMAKE_VS_PLATFORM_TOOLSET}'")
message(STATUS "CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR='${CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR}'")

View File

@@ -28,6 +28,10 @@ run_cmake(VsDpiAwareBadParam)
run_cmake(VsPrecompileHeaders)
run_cmake(VsPrecompileHeadersReuseFromCompilePDBName)
set(RunCMake_GENERATOR_TOOLSET "VCTargetsPath=$(VCTargetsPath)")
run_cmake(VsVCTargetsPath)
unset(RunCMake_GENERATOR_TOOLSET)
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.05)
run_cmake(VsJustMyCode)
endif()

View File

@@ -0,0 +1,32 @@
macro(check_project_file projectFile)
set(insideGlobals FALSE)
set(pathFound FALSE)
if(NOT EXISTS "${projectFile}")
set(RunCMake_TEST_FAILED "Project file ${projectFile} does not exist.")
return()
endif()
string(REPLACE "${RunCMake_TEST_BINARY_DIR}/" "" projectName ${projectFile})
file(STRINGS "${projectFile}" lines)
foreach(line IN LISTS lines)
if(line MATCHES "^ *<PropertyGroup Label=\"Globals\">.*$")
set(insideGlobals TRUE)
elseif(insideGlobals)
if(line MATCHES "^ *</PropertyGroup>.*$")
set(insideGlobals FALSE)
elseif(line MATCHES "^ *<VCTargetsPath>(.+)</VCTargetsPath>*$")
message(STATUS "Found VCTargetsPath = ${CMAKE_MATCH_1} in PropertyGroup 'Globals' in ${projectName}")
set(pathFound TRUE)
endif()
endif()
endforeach()
if(NOT pathFound)
set(RunCMake_TEST_FAILED "VCTargetsPath not found in \"Globals\" propertygroup in ${projectName}")
return() # This should intentionally return from the caller, not the macro
endif()
endmacro()
check_project_file("${RunCMake_TEST_BINARY_DIR}/CMakeFiles/${CMAKE_VERSION}/CompilerIdCXX/CompilerIdCXX.vcxproj")
check_project_file("${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")

View File

@@ -0,0 +1,3 @@
enable_language(CXX)
add_library(foo foo.cpp)