Commit b34b4c5e authored by Brad King's avatar Brad King Committed by Kitware Robot

Merge topic 'vs-vctargetspath'

e7d57bc3 VS: Propagate CMAKE_VS_GLOBALS into custom targets
45b4b4b9 VS: Propagate CMAKE_VS_GLOBALS into compiler id projects
548e9051 VS: Add support to override VCTargetsPath through toolset
99e83d42 cmake: Teach --build mode to load CMAKE_GENERATOR_TOOLSET
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Merge-request: !3817
parents c867981c e7d57bc3
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.
* The :variable:`CMAKE_VS_GLOBALS` variable value now applies during
compiler identification and in targets created by the
:command:`add_custom_target` command.
......@@ -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.
......@@ -317,6 +317,15 @@ 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()
set(id_CustomGlobals "")
foreach(pair IN LISTS CMAKE_VS_GLOBALS)
if("${pair}" MATCHES "([^=]+)=(.*)$")
string(APPEND id_CustomGlobals "<${CMAKE_MATCH_1}>${CMAKE_MATCH_2}</${CMAKE_MATCH_1}>\n ")
endif()
endforeach()
if(id_platform STREQUAL ARM64)
set(id_WindowsSDKDesktopARMSupport "<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>")
elseif(id_platform STREQUAL ARM)
......
......@@ -15,6 +15,8 @@
@id_WindowsTargetPlatformVersion@
@id_WindowsSDKDesktopARMSupport@
@id_CudaToolkitCustomDir@
@id_ToolsetVCTargetsDir@
@id_CustomGlobals@
</PropertyGroup>
@id_toolset_version_props@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
......
......@@ -165,7 +165,7 @@ bool cmGlobalGenerator::SetGeneratorPlatform(std::string const& p,
return false;
}
bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts,
bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts, bool,
cmMakefile* mf)
{
if (ts.empty()) {
......@@ -650,7 +650,7 @@ void cmGlobalGenerator::EnableLanguage(
// Tell the generator about the toolset, if any.
std::string toolset = mf->GetSafeDefinition("CMAKE_GENERATOR_TOOLSET");
if (!this->SetGeneratorToolset(toolset, mf)) {
if (!this->SetGeneratorToolset(toolset, false, mf)) {
cmSystemTools::SetFatalErrorOccured();
return;
}
......
......@@ -128,7 +128,8 @@ public:
/** Set the generator-specific toolset name. Returns true if toolset
is supported and false otherwise. */
virtual bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf);
virtual bool SetGeneratorToolset(std::string const& ts, bool build,
cmMakefile* mf);
/**
* Create LocalGenerators and process the CMakeLists files. This does not
......
......@@ -64,8 +64,11 @@ void cmGlobalGhsMultiGenerator::ComputeTargetObjectDirectory(
}
bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
cmMakefile* mf)
bool build, cmMakefile* mf)
{
if (build) {
return true;
}
std::string tsp; /* toolset path */
this->GetToolset(mf, tsp, ts);
......
......@@ -58,7 +58,8 @@ public:
static bool SupportsPlatform() { return true; }
// Toolset / Platform Support
bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) override;
bool SetGeneratorToolset(std::string const& ts, bool build,
cmMakefile* mf) override;
bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf) override;
/**
......
......@@ -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)
{
......@@ -193,7 +203,7 @@ static void cmCudaToolVersion(std::string& s)
}
bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
std::string const& ts, cmMakefile* mf)
std::string const& ts, bool build, cmMakefile* mf)
{
if (this->SystemIsWindowsCE && ts.empty() &&
this->DefaultPlatformToolset.empty()) {
......@@ -208,7 +218,11 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
return false;
}
if (!this->FindVCTargetsPath(mf)) {
if (build) {
return true;
}
if (this->CustomVCTargetsPath.empty() && !this->FindVCTargetsPath(mf)) {
return false;
}
......@@ -349,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;
}
......@@ -442,6 +461,11 @@ bool cmGlobalVisualStudio10Generator::ProcessGeneratorToolsetField(
this->GeneratorToolsetVersion = value;
return true;
}
if (key == "VCTargetsPath") {
this->CustomVCTargetsPath = value;
ConvertToWindowsSlashes(this->CustomVCTargetsPath);
return true;
}
return false;
}
......@@ -603,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();
......
......@@ -20,7 +20,8 @@ public:
bool SetSystemName(std::string const& s, cmMakefile* mf) override;
bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf) override;
bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) override;
bool SetGeneratorToolset(std::string const& ts, bool build,
cmMakefile* mf) override;
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
......@@ -45,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;
......@@ -155,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;
......@@ -206,6 +211,7 @@ private:
bool ParseGeneratorToolset(std::string const& ts, cmMakefile* mf);
std::string CustomVCTargetsPath;
std::string VCTargetsPath;
bool FindVCTargetsPath(cmMakefile* mf);
......
......@@ -267,7 +267,7 @@ std::string cmGlobalXCodeGenerator::FindXcodeBuildCommand()
}
bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts,
cmMakefile* mf)
bool build, cmMakefile* mf)
{
if (ts.find_first_of(",=") != std::string::npos) {
std::ostringstream e;
......@@ -283,6 +283,9 @@ bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts,
return false;
}
this->GeneratorToolset = ts;
if (build) {
return true;
}
if (!this->GeneratorToolset.empty()) {
mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET", this->GeneratorToolset);
}
......
......@@ -103,7 +103,8 @@ public:
bool ShouldStripResourcePath(cmMakefile*) const override;
bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) override;
bool SetGeneratorToolset(std::string const& ts, bool build,
cmMakefile* mf) override;
void AppendFlag(std::string& flags, std::string const& flag) const;
protected:
......
......@@ -511,8 +511,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("DOTNET_TARGET_FRAMEWORK_VERSION");
}
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
this->GetType() != cmStateEnums::UTILITY) {
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
// check for "CMAKE_VS_GLOBALS" variable and set up target properties
// if any
......
......@@ -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_";
......
......@@ -2619,6 +2619,14 @@ int cmake::Build(int jobs, const std::string& dir,
return 1;
}
}
const char* cachedGeneratorToolset =
this->State->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET");
if (cachedGeneratorToolset) {
cmMakefile mf(gen, this->GetCurrentSnapshot());
if (!gen->SetGeneratorToolset(cachedGeneratorToolset, true, &mf)) {
return 1;
}
}
std::string output;
std::string projName;
const char* cachedProjectName =
......
......@@ -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")
......
-- CMAKE_VS_PLATFORM_TOOLSET='v[0-9]+'
-- CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR='Test Path'
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}'")
......@@ -29,6 +29,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()
......
set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
if(NOT EXISTS "${vcProjectFile}")
set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
return()
endif()
macro(check_project_file projectFile)
if(NOT EXISTS "${projectFile}")
set(RunCMake_TEST_FAILED "Project file ${projectFile} does not exist.")
return()
endif()
string(REPLACE "${RunCMake_TEST_BINARY_DIR}/" "" projectName ${projectFile})
set(InsideGlobals FALSE)
set(DefaultLanguageSet FALSE)
set(MinimumVisualStudioVersionSet FALSE)
set(InsideGlobals FALSE)
set(DefaultLanguageSet FALSE)
set(MinimumVisualStudioVersionSet FALSE)
set(TestPropertySet FALSE)
file(STRINGS "${vcProjectFile}" lines)
foreach(line IN LISTS lines)
if(line MATCHES "^ *<PropertyGroup Label=\"Globals\"> *$")
set(InsideGlobals TRUE)
elseif(line MATCHES "^ *<DefaultLanguage>([a-zA-Z\\-]+)</DefaultLanguage> *$")
if("${CMAKE_MATCH_1}" STREQUAL "en-US")
if(InsideGlobals)
message(STATUS "foo.vcxproj has correct DefaultLanguage global property")
set(DefaultLanguageSet TRUE)
else()
message(STATUS "DefaultLanguage is set but not within \"Globals\" property group")
file(STRINGS "${projectFile}" lines)
foreach(line IN LISTS lines)
if(line MATCHES "^ *<PropertyGroup Label=\"Globals\"> *$")
set(InsideGlobals TRUE)
elseif(line MATCHES "^ *<DefaultLanguage>([a-zA-Z\\-]+)</DefaultLanguage> *$")
if("${CMAKE_MATCH_1}" STREQUAL "en-US")
if(InsideGlobals)
message(STATUS "${projectName} has correct DefaultLanguage global property")
set(DefaultLanguageSet TRUE)
else()
message(STATUS "DefaultLanguage is set but not within \"Globals\" property group")
endif()
endif()
endif()
elseif(line MATCHES "^ *<MinimumVisualStudioVersion>([0-9\\.]+)</MinimumVisualStudioVersion> *$")
if("${CMAKE_MATCH_1}" STREQUAL "14.0")
if(InsideGlobals)
message(STATUS "foo.vcxproj has correct MinimumVisualStudioVersion global property")
set(MinimumVisualStudioVersionSet TRUE)
else()
message(STATUS "MinimumVisualStudioVersion is set but not within \"Globals\" property group")
elseif(line MATCHES "^ *<MinimumVisualStudioVersion>([0-9\\.]+)</MinimumVisualStudioVersion> *$")
if("${CMAKE_MATCH_1}" STREQUAL "10.0")
if(InsideGlobals)
message(STATUS "${projectName} has correct MinimumVisualStudioVersion global property")
set(MinimumVisualStudioVersionSet TRUE)
else()
message(STATUS "MinimumVisualStudioVersion is set but not within \"Globals\" property group")
endif()
endif()
elseif(line MATCHES "^ *<TestProperty>(.+)</TestProperty> *$")
if("${CMAKE_MATCH_1}" STREQUAL "TestValue")
if(InsideGlobals)
message(STATUS "${projectName} has correct TestProperty global property")
set(TestPropertySet TRUE)
else()
message(STATUS "TestProperty is set but not within \"Globals\" property group")
endif()
endif()
endif()
endforeach()
if(NOT DefaultLanguageSet)
set(RunCMake_TEST_FAILED "DefaultLanguage not found or not set correctly in ${projectName}.")
return()
endif()
if(NOT MinimumVisualStudioVersionSet)
set(RunCMake_TEST_FAILED "MinimumVisualStudioVersion not found or not set correctly in ${projectName}.")
return()
endif()
endforeach()
if(NOT DefaultLanguageSet)
set(RunCMake_TEST_FAILED "DefaultLanguageSet not found or not set correctly.")
return()
endif()
if(NOT TestPropertySet)
set(RunCMake_TEST_FAILED "TestProperty not found or not set correctly in ${projectName}.")
return()
endif()
endmacro()
if(NOT MinimumVisualStudioVersionSet)
set(RunCMake_TEST_FAILED "MinimumVisualStudioVersionSet not found or not set correctly.")
return()
endif()
check_project_file("${RunCMake_TEST_BINARY_DIR}/CMakeFiles/${CMAKE_VERSION}/CompilerIdCXX/CompilerIdCXX.vcxproj")
check_project_file("${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
enable_language(CXX)
set(CMAKE_VS_GLOBALS
"DefaultLanguage=en-US"
"MinimumVisualStudioVersion=14.0"
"MinimumVisualStudioVersion=10.0"
"TestProperty=TestValue"
)
enable_language(CXX)
add_library(foo foo.cpp)
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")
enable_language(CXX)
add_library(foo foo.cpp)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment