VS: Add a mostly-undocumented hook to load custom JSON flag tables
The names and formats of our VS flag tables are internal implementation details. However, some institutions need to maintain support for non-public VS platforms and toolsets. Provide a hook that their projects can use to load custom flag table files. This helps avoid distributing a custom CMake package within such institutions. Document the hook itself, but explicitly specify that the files the hook loads are not considered a stable interface.
This commit is contained in:
parent
8dd8d63665
commit
608ef8a6fc
@ -63,3 +63,27 @@ Supported pairs are:
|
||||
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.
|
||||
|
||||
Visual Studio Toolset Customization
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
**These are unstable interfaces with no compatibility guarantees**
|
||||
because they hook into undocumented internal CMake implementation details.
|
||||
Institutions may use these to internally maintain support for non-public
|
||||
Visual Studio platforms and toolsets, but must accept responsibility to
|
||||
make updates as changes are made to CMake.
|
||||
|
||||
Additional ``key=value`` pairs are available:
|
||||
|
||||
``customFlagTableDir=<path>``
|
||||
.. versionadded:: 3.21
|
||||
|
||||
Specify the absolute path to a directory from which to load custom
|
||||
flag tables stored as JSON documents with file names of the form
|
||||
``<platform>_<toolset>_<tool>.json`` or ``<platform>_<tool>.json``,
|
||||
where ``<platform>`` is the :variable:`CMAKE_VS_PLATFORM_NAME`,
|
||||
``<toolset>`` is the :variable:`CMAKE_VS_PLATFORM_TOOLSET`,
|
||||
and ``<tool>`` is the tool for which the flag table is meant.
|
||||
**This naming pattern is an internal CMake implementation detail.**
|
||||
The ``<tool>`` names are undocumented. The format of the ``.json``
|
||||
flag table files is undocumented.
|
||||
|
@ -231,6 +231,23 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this->CustomFlagTableDir.empty() &&
|
||||
!(cmSystemTools::FileIsFullPath(this->CustomFlagTableDir) &&
|
||||
cmSystemTools::FileIsDirectory(this->CustomFlagTableDir))) {
|
||||
std::ostringstream e;
|
||||
/* clang-format off */
|
||||
e <<
|
||||
"Generator\n"
|
||||
" " << this->GetName() << "\n"
|
||||
"given toolset\n"
|
||||
" customFlagTableDir=" << this->CustomFlagTableDir << "\n"
|
||||
"that is not an absolute path to an existing directory.";
|
||||
/* clang-format on */
|
||||
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
|
||||
cmSystemTools::SetFatalErrorOccured();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cmHasLiteralPrefix(this->GetPlatformToolsetString(), "v140")) {
|
||||
// The GenerateDebugInformation link setting for the v140 toolset
|
||||
// in VS 2015 was originally an enum with "No" and "Debug" values,
|
||||
@ -486,6 +503,11 @@ bool cmGlobalVisualStudio10Generator::ProcessGeneratorToolsetField(
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (key == "customFlagTableDir") {
|
||||
this->CustomFlagTableDir = value;
|
||||
cmSystemTools::ConvertToUnixSlashes(this->CustomFlagTableDir);
|
||||
return true;
|
||||
}
|
||||
if (key == "version") {
|
||||
this->GeneratorToolsetVersion = value;
|
||||
return true;
|
||||
@ -1375,6 +1397,20 @@ static cmIDEFlagTable const* cmLoadFlagTableJson(
|
||||
cm::optional<std::string> cmGlobalVisualStudio10Generator::FindFlagTable(
|
||||
cm::string_view toolsetName, cm::string_view table) const
|
||||
{
|
||||
if (!this->CustomFlagTableDir.empty()) {
|
||||
std::string customFlagTableFile =
|
||||
cmStrCat(this->CustomFlagTableDir, '/', this->GetPlatformName(), '_',
|
||||
toolsetName, '_', table, ".json");
|
||||
if (cmSystemTools::FileExists(customFlagTableFile)) {
|
||||
return customFlagTableFile;
|
||||
}
|
||||
customFlagTableFile =
|
||||
cmStrCat(this->CustomFlagTableDir, '/', this->GetPlatformName(), '_',
|
||||
table, ".json");
|
||||
if (cmSystemTools::FileExists(customFlagTableFile)) {
|
||||
return customFlagTableFile;
|
||||
}
|
||||
}
|
||||
std::string fullPath =
|
||||
cmStrCat(cmSystemTools::GetCMakeRoot(), "/Templates/MSBuild/FlagTables/",
|
||||
toolsetName, '_', table, ".json");
|
||||
|
@ -262,6 +262,8 @@ private:
|
||||
cm::optional<std::string> FindFlagTable(cm::string_view toolsetName,
|
||||
cm::string_view table) const;
|
||||
|
||||
std::string CustomFlagTableDir;
|
||||
|
||||
std::string CustomVCTargetsPath;
|
||||
std::string VCTargetsPath;
|
||||
bool FindVCTargetsPath(cmMakefile* mf);
|
||||
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1,11 @@
|
||||
CMake Error at CMakeLists.txt:[0-9]+ \(project\):
|
||||
Generator
|
||||
|
||||
Visual Studio [^
|
||||
]*
|
||||
|
||||
given toolset
|
||||
|
||||
customFlagTableDir=does_not_exist
|
||||
|
||||
that is not an absolute path to an existing directory.$
|
@ -0,0 +1 @@
|
||||
message(FATAL_ERROR "This should not be reached!")
|
@ -1,5 +1,11 @@
|
||||
include(RunCMake)
|
||||
|
||||
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012456]")
|
||||
run_cmake(VsNormal)
|
||||
include("${RunCMake_BINARY_DIR}/VsNormal-build/defaults.cmake" OPTIONAL)
|
||||
message(STATUS "VsNormal: platform='${VsNormal_Platform}' toolset='${VsNormal_Toolset}'")
|
||||
endif()
|
||||
|
||||
set(RunCMake_GENERATOR_TOOLSET "")
|
||||
run_cmake(NoToolset)
|
||||
|
||||
@ -18,6 +24,25 @@ if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012456]")
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/CudaStandaloneToolset/CUDAVisualStudioIntegration")
|
||||
run_cmake(TestToolsetCudaPathOnlyOldLayout)
|
||||
file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/CudaStandaloneToolset")
|
||||
if (VsNormal_Platform MATCHES "^(x64|Win32)$" AND
|
||||
EXISTS "${CMAKE_ROOT}/Templates/MSBuild/FlagTables/${VsNormal_Toolset}_CL.json")
|
||||
set(flagTableDir "${RunCMake_BINARY_DIR}/FlagTables")
|
||||
file(READ "${CMAKE_ROOT}/Templates/MSBuild/FlagTables/${VsNormal_Toolset}_CL.json" flagTableContent)
|
||||
string(REPLACE [["WX-"]] [["TESTWX-"]] flagTableContent "${flagTableContent}")
|
||||
file(REMOVE_RECURSE "${flagTableDir}")
|
||||
file(WRITE "${flagTableDir}/${VsNormal_Platform}_${VsNormal_Toolset}_CL.json" "${flagTableContent}")
|
||||
set(RunCMake_GENERATOR_TOOLSET "${VsNormal_Toolset},customFlagTableDir=${flagTableDir}")
|
||||
set(RunCMake_TEST_VARIANT_DESCRIPTION ":${VsNormal_Platform}_${VsNormal_Toolset}_CL.json")
|
||||
run_cmake(TestToolsetCustomFlagTableDir)
|
||||
file(REMOVE_RECURSE "${flagTableDir}")
|
||||
file(WRITE "${flagTableDir}/${VsNormal_Platform}_CL.json" "${flagTableContent}")
|
||||
set(RunCMake_GENERATOR_TOOLSET "${VsNormal_Toolset},customFlagTableDir=${flagTableDir}")
|
||||
set(RunCMake_TEST_VARIANT_DESCRIPTION ":${VsNormal_Platform}_CL.json")
|
||||
run_cmake(TestToolsetCustomFlagTableDir)
|
||||
unset(RunCMake_TEST_VARIANT_DESCRIPTION)
|
||||
set(RunCMake_GENERATOR_TOOLSET "${VsNormal_Toolset},customFlagTableDir=does_not_exist")
|
||||
run_cmake(BadToolsetCustomFlagTableDir)
|
||||
endif()
|
||||
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[2456]")
|
||||
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64")
|
||||
run_cmake(TestToolsetHostArchBoth)
|
||||
|
@ -0,0 +1,24 @@
|
||||
set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/main.vcxproj")
|
||||
if(NOT EXISTS "${vcProjectFile}")
|
||||
set(RunCMake_TEST_FAILED "Project file\n ${vcProjectFile}\ndoes not exist.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(TreatWarningAsError_FOUND FALSE)
|
||||
file(STRINGS "${vcProjectFile}" lines)
|
||||
foreach(line IN LISTS lines)
|
||||
if(line MATCHES "^ *<TreatWarningAsError>([^<>]*)</TreatWarningAsError>$")
|
||||
set(TreatWarningAsError_FOUND TRUE)
|
||||
set(expectedValue "false")
|
||||
set(actualValue "${CMAKE_MATCH_1}")
|
||||
if(NOT (${actualValue} STREQUAL ${expectedValue}))
|
||||
set(RunCMake_TEST_FAILED "TreatWarningAsError \"${actualValue}\" differs from expected value \"${expectedValue}\".")
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(NOT TreatWarningAsError_FOUND)
|
||||
set(RunCMake_TEST_FAILED "Property TreatWarningAsError not found in project file:\n ${vcProjectFile}.")
|
||||
return()
|
||||
endif()
|
@ -0,0 +1,3 @@
|
||||
enable_language(C)
|
||||
string(APPEND CMAKE_C_FLAGS " -TESTWX-")
|
||||
add_executable(main main.c)
|
2
Tests/RunCMake/GeneratorToolset/VsNormal-stdout.txt
Normal file
2
Tests/RunCMake/GeneratorToolset/VsNormal-stdout.txt
Normal file
@ -0,0 +1,2 @@
|
||||
-- CMAKE_VS_PLATFORM_NAME='[^']+'
|
||||
-- CMAKE_VS_PLATFORM_TOOLSET='v[0-9]+'
|
6
Tests/RunCMake/GeneratorToolset/VsNormal.cmake
Normal file
6
Tests/RunCMake/GeneratorToolset/VsNormal.cmake
Normal file
@ -0,0 +1,6 @@
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/defaults.cmake" "# VS Defaults
|
||||
set(VsNormal_Platform [[${CMAKE_VS_PLATFORM_NAME}]])
|
||||
set(VsNormal_Toolset [[${CMAKE_VS_PLATFORM_TOOLSET}]])
|
||||
")
|
||||
message(STATUS "CMAKE_VS_PLATFORM_NAME='${CMAKE_VS_PLATFORM_NAME}'")
|
||||
message(STATUS "CMAKE_VS_PLATFORM_TOOLSET='${CMAKE_VS_PLATFORM_TOOLSET}'")
|
4
Tests/RunCMake/GeneratorToolset/main.c
Normal file
4
Tests/RunCMake/GeneratorToolset/main.c
Normal file
@ -0,0 +1,4 @@
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user