summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt7
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.cxx2
-rw-r--r--Source/CPack/cpack.cxx187
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx2
-rw-r--r--Source/CTest/cmCTestConfigureCommand.cxx7
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx1
-rw-r--r--Source/CTest/cmCTestCurl.cxx6
-rw-r--r--Source/CTest/cmCTestGenericHandler.cxx16
-rw-r--r--Source/CTest/cmCTestGenericHandler.h12
-rw-r--r--Source/CTest/cmCTestHandlerCommand.cxx4
-rw-r--r--Source/CursesDialog/ccmake.cxx40
-rw-r--r--Source/QtDialog/CMakeSetup.cxx37
-rw-r--r--Source/QtDialog/CMakeSetupDialog.cxx3
-rw-r--r--Source/QtDialog/EnvironmentDialog.cxx14
-rw-r--r--Source/QtDialog/QCMakeCacheView.cxx8
-rw-r--r--Source/QtDialog/QCMakeCacheView.h7
-rw-r--r--Source/QtDialog/QCMakeWidgets.cxx34
-rw-r--r--Source/QtDialog/QCMakeWidgets.h8
-rw-r--r--Source/cmBinUtilsLinuxELFLinker.cxx9
-rw-r--r--Source/cmCMakePresetsGraphInternal.h2
-rw-r--r--Source/cmCMakePresetsGraphReadJSON.cxx4
-rw-r--r--Source/cmCPluginAPI.h2
-rw-r--r--Source/cmCTest.cxx50
-rw-r--r--Source/cmCTest.h2
-rw-r--r--Source/cmCallVisualStudioMacro.h3
-rw-r--r--Source/cmCommandLineArgument.h11
-rw-r--r--Source/cmConfigureLog.cxx261
-rw-r--r--Source/cmConfigureLog.h68
-rw-r--r--Source/cmCoreTryCompile.cxx79
-rw-r--r--Source/cmCoreTryCompile.h20
-rw-r--r--Source/cmCustomCommandGenerator.cxx27
-rw-r--r--Source/cmCustomCommandGenerator.h2
-rw-r--r--Source/cmCxxModuleMapper.cxx36
-rw-r--r--Source/cmCxxModuleMapper.h1
-rw-r--r--Source/cmDocumentation.cxx169
-rw-r--r--Source/cmDocumentation.h57
-rw-r--r--Source/cmDocumentationEntry.h29
-rw-r--r--Source/cmDocumentationFormatter.cxx234
-rw-r--r--Source/cmDocumentationFormatter.h56
-rw-r--r--Source/cmDocumentationSection.cxx28
-rw-r--r--Source/cmDocumentationSection.h22
-rw-r--r--Source/cmDyndepCollation.cxx652
-rw-r--r--Source/cmDyndepCollation.h52
-rw-r--r--Source/cmExperimental.cxx2
-rw-r--r--Source/cmExportFileGenerator.cxx13
-rw-r--r--Source/cmExportInstallFileGenerator.cxx4
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx2
-rw-r--r--Source/cmFileAPI.cxx96
-rw-r--r--Source/cmFileAPI.h8
-rw-r--r--Source/cmFileAPICodemodel.cxx112
-rw-r--r--Source/cmFileAPIConfigureLog.cxx67
-rw-r--r--Source/cmFileAPIConfigureLog.h12
-rw-r--r--Source/cmFileCommand.cxx57
-rw-r--r--Source/cmFileLockPool.cxx4
-rw-r--r--Source/cmFileSet.cxx9
-rw-r--r--Source/cmFileSet.h4
-rw-r--r--Source/cmFindPackageCommand.cxx14
-rw-r--r--Source/cmGeneratedFileStream.cxx11
-rw-r--r--Source/cmGeneratorExpression.cxx80
-rw-r--r--Source/cmGeneratorExpression.h13
-rw-r--r--Source/cmGeneratorExpressionEvaluationFile.cxx2
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx31
-rw-r--r--Source/cmGeneratorExpressionNode.cxx18
-rw-r--r--Source/cmGeneratorTarget.cxx255
-rw-r--r--Source/cmGeneratorTarget.h32
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx7
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.cxx7
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.h3
-rw-r--r--Source/cmGlobalCommonGenerator.cxx24
-rw-r--r--Source/cmGlobalCommonGenerator.h13
-rw-r--r--Source/cmGlobalGenerator.cxx31
-rw-r--r--Source/cmGlobalGenerator.h6
-rw-r--r--Source/cmGlobalGeneratorFactory.h23
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx10
-rw-r--r--Source/cmGlobalGhsMultiGenerator.h3
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.cxx8
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.h3
-rw-r--r--Source/cmGlobalMSYSMakefileGenerator.cxx8
-rw-r--r--Source/cmGlobalMSYSMakefileGenerator.h9
-rw-r--r--Source/cmGlobalMinGWMakefileGenerator.cxx8
-rw-r--r--Source/cmGlobalMinGWMakefileGenerator.h5
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.cxx16
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.h3
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx422
-rw-r--r--Source/cmGlobalNinjaGenerator.h16
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx19
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h6
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx115
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h15
-rw-r--r--Source/cmGlobalVisualStudio11Generator.cxx30
-rw-r--r--Source/cmGlobalVisualStudio11Generator.h3
-rw-r--r--Source/cmGlobalVisualStudio12Generator.cxx17
-rw-r--r--Source/cmGlobalVisualStudio14Generator.cxx17
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx17
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx67
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h8
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx52
-rw-r--r--Source/cmGlobalVisualStudio9Generator.cxx11
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx19
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h7
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.cxx81
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.h11
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.cxx8
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.h3
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx53
-rw-r--r--Source/cmGlobalXCodeGenerator.h8
-rw-r--r--Source/cmIDEOptions.cxx15
-rw-r--r--Source/cmInstalledFile.cxx4
-rw-r--r--Source/cmLocalGenerator.cxx71
-rw-r--r--Source/cmLocalGenerator.h4
-rw-r--r--Source/cmLocalNinjaGenerator.cxx2
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx6
-rw-r--r--Source/cmLocalVisualStudio10Generator.cxx12
-rw-r--r--Source/cmLocalVisualStudio10Generator.h2
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx109
-rw-r--r--Source/cmLocalVisualStudio7Generator.h4
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx8
-rw-r--r--Source/cmLocalVisualStudioGenerator.h4
-rw-r--r--Source/cmMakefile.cxx33
-rw-r--r--Source/cmMakefileProfilingData.cxx57
-rw-r--r--Source/cmMakefileProfilingData.h30
-rw-r--r--Source/cmMakefileTargetGenerator.cxx27
-rw-r--r--Source/cmMessenger.cxx4
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx20
-rw-r--r--Source/cmNinjaTargetGenerator.cxx439
-rw-r--r--Source/cmNinjaTargetGenerator.h21
-rw-r--r--Source/cmPolicies.h5
-rw-r--r--Source/cmProjectCommand.cxx9
-rw-r--r--Source/cmQtAutoGenInitializer.cxx5
-rw-r--r--Source/cmQtAutoMocUic.cxx3
-rw-r--r--Source/cmRulePlaceholderExpander.cxx5
-rw-r--r--Source/cmRulePlaceholderExpander.h2
-rw-r--r--Source/cmSearchPath.cxx15
-rw-r--r--Source/cmState.cxx2
-rw-r--r--Source/cmState.h1
-rw-r--r--Source/cmStringAlgorithms.cxx44
-rw-r--r--Source/cmStringAlgorithms.h42
-rw-r--r--Source/cmStringCommand.cxx64
-rw-r--r--Source/cmSystemTools.cxx44
-rw-r--r--Source/cmSystemTools.h8
-rw-r--r--Source/cmTarget.cxx8
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.cxx5
-rw-r--r--Source/cmTargetPropCommandBase.cxx2
-rw-r--r--Source/cmTargetPropCommandBase.h7
-rw-r--r--Source/cmTestGenerator.cxx3
-rw-r--r--Source/cmTimestamp.cxx63
-rw-r--r--Source/cmTimestamp.h4
-rw-r--r--Source/cmTryCompileCommand.cxx31
-rw-r--r--Source/cmTryRunCommand.cxx121
-rw-r--r--Source/cmUVProcessChain.cxx1
-rw-r--r--Source/cmVSSetupHelper.cxx93
-rw-r--r--Source/cmVSSetupHelper.h27
-rw-r--r--Source/cmVersionConfig.h.in2
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx268
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h5
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx41
-rw-r--r--Source/cmVisualStudioGeneratorOptions.h1
-rw-r--r--Source/cmVisualStudioSlnData.cxx43
-rw-r--r--Source/cmVisualStudioSlnData.h16
-rw-r--r--Source/cmVisualStudioSlnParser.cxx189
-rw-r--r--Source/cmVisualStudioSlnParser.h4
-rw-r--r--Source/cmVisualStudioWCEPlatformParser.cxx9
-rw-r--r--Source/cmVisualStudioWCEPlatformParser.h11
-rw-r--r--Source/cmake.cxx326
-rw-r--r--Source/cmake.h77
-rw-r--r--Source/cmakemain.cxx67
-rw-r--r--Source/cmcmd.cxx63
-rw-r--r--Source/ctest.cxx30
-rw-r--r--Source/kwsys/ProcessUNIX.c13
-rw-r--r--Source/kwsys/Status.hxx.in10
-rw-r--r--Source/kwsys/SystemInformation.cxx6
-rw-r--r--Source/kwsys/SystemTools.cxx100
-rw-r--r--Source/kwsys/SystemTools.hxx.in44
174 files changed, 4551 insertions, 2571 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index c268a92..e99da49 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -160,6 +160,8 @@ add_library(
cmComputeLinkInformation.h
cmComputeTargetDepends.h
cmComputeTargetDepends.cxx
+ cmConfigureLog.h
+ cmConfigureLog.cxx
cmConsoleBuf.h
cmConsoleBuf.cxx
cmConstStack.h
@@ -196,9 +198,10 @@ add_library(
cmDependsCompiler.h
cmDocumentation.cxx
cmDocumentationFormatter.cxx
- cmDocumentationSection.cxx
cmDynamicLoader.cxx
cmDynamicLoader.h
+ cmDyndepCollation.cxx
+ cmDyndepCollation.h
cmELF.h
cmELF.cxx
cmExprParserHelper.cxx
@@ -234,6 +237,8 @@ add_library(
cmFileAPICache.h
cmFileAPICodemodel.cxx
cmFileAPICodemodel.h
+ cmFileAPIConfigureLog.cxx
+ cmFileAPIConfigureLog.h
cmFileAPICMakeFiles.cxx
cmFileAPICMakeFiles.h
cmFileAPIToolchains.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 5b9df91..8aad0ae 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 25)
-set(CMake_VERSION_PATCH 1)
+set(CMake_VERSION_PATCH 20230112)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index 0579066..68e7ba3 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -451,7 +451,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
mountpoint_regex.find(attach_output.c_str());
std::string const temp_mount = mountpoint_regex.match(1);
std::string const temp_mount_name =
- temp_mount.substr(sizeof("/Volumes/") - 1);
+ temp_mount.substr(cmStrLen("/Volumes/"));
// Remove dummy padding file so we have enough space on RW image ...
std::ostringstream dummy_padding;
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index f06946b..c228f07 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -5,10 +5,12 @@
#include <cstddef>
#include <functional>
#include <iostream>
+#include <iterator>
#include <map>
#include <memory>
#include <sstream>
#include <string>
+#include <type_traits>
#include <utility>
#include <vector>
@@ -25,7 +27,6 @@
#include "cmConsoleBuf.h"
#include "cmDocumentation.h"
#include "cmDocumentationEntry.h"
-#include "cmDocumentationFormatter.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
@@ -36,19 +37,14 @@
#include "cmake.h"
namespace {
-const char* cmDocumentationName[][2] = {
- { nullptr, " cpack - Packaging driver provided by CMake." },
- { nullptr, nullptr }
+const cmDocumentationEntry cmDocumentationName = {
+ {},
+ " cpack - Packaging driver provided by CMake."
};
-const char* cmDocumentationUsage[][2] = {
- // clang-format off
- { nullptr, " cpack [options]" },
- { nullptr, nullptr }
- // clang-format on
-};
+const cmDocumentationEntry cmDocumentationUsage = { {}, " cpack [options]" };
-const char* cmDocumentationOptions[][2] = {
+const cmDocumentationEntry cmDocumentationOptions[14] = {
{ "-G <generators>", "Override/define CPACK_GENERATOR" },
{ "-C <Configuration>", "Specify the project configuration" },
{ "-D <var>=<value>", "Set a CPack variable." },
@@ -62,14 +58,30 @@ const char* cmDocumentationOptions[][2] = {
{ "-B <packageDirectory>", "Override/define CPACK_PACKAGE_DIRECTORY" },
{ "--vendor <vendorName>", "Override/define CPACK_PACKAGE_VENDOR" },
{ "--preset", "Read arguments from a package preset" },
- { "--list-presets", "List available package presets" },
- { nullptr, nullptr }
+ { "--list-presets", "List available package presets" }
};
void cpackProgressCallback(const std::string& message, float /*unused*/)
{
- std::cout << "-- " << message << std::endl;
+ std::cout << "-- " << message << '\n';
}
+
+std::vector<cmDocumentationEntry> makeGeneratorDocs(
+ const cmCPackGeneratorFactory& gf)
+{
+ const auto& generators = gf.GetGeneratorsList();
+
+ std::vector<cmDocumentationEntry> docs;
+ docs.reserve(generators.size());
+
+ std::transform(
+ generators.cbegin(), generators.cend(), std::back_inserter(docs),
+ [](const std::decay<decltype(generators)>::type::value_type& gen) {
+ return cmDocumentationEntry{ gen.first, gen.second };
+ });
+ return docs;
+}
+
} // namespace
// this is CPack.
@@ -101,8 +113,7 @@ int main(int argc, char const* const* argv)
if (cmSystemTools::GetCurrentWorkingDirectory().empty()) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
- "Current working directory cannot be established."
- << std::endl);
+ "Current working directory cannot be established.\n");
return 1;
}
@@ -129,14 +140,14 @@ int main(int argc, char const* const* argv)
auto const verboseLambda = [&log](const std::string&, cmake*,
cmMakefile*) -> bool {
log.SetVerbose(true);
- cmCPack_Log(&log, cmCPackLog::LOG_OUTPUT, "Enable Verbose" << std::endl);
+ cmCPack_Log(&log, cmCPackLog::LOG_OUTPUT, "Enable Verbose\n");
return true;
};
auto const debugLambda = [&log](const std::string&, cmake*,
cmMakefile*) -> bool {
log.SetDebug(true);
- cmCPack_Log(&log, cmCPackLog::LOG_OUTPUT, "Enable Debug" << std::endl);
+ cmCPack_Log(&log, cmCPackLog::LOG_OUTPUT, "Enable Debug\n");
return true;
};
@@ -194,26 +205,25 @@ int main(int argc, char const* const* argv)
CommandArgument::setToValue(preset) },
CommandArgument{ "--list-presets", CommandArgument::Values::Zero,
CommandArgument::setToTrue(listPresets) },
- CommandArgument{
- "-D", CommandArgument::Values::One,
- [&log, &definitions](const std::string& arg, cmake*,
- cmMakefile*) -> bool {
- std::string value = arg;
- size_t pos = value.find_first_of('=');
- if (pos == std::string::npos) {
- cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
- "Please specify CPack definitions as: KEY=VALUE"
- << std::endl);
- return false;
- }
- std::string key = value.substr(0, pos);
- value.erase(0, pos + 1);
- definitions[key] = value;
- cmCPack_Log(&log, cmCPackLog::LOG_DEBUG,
- "Set CPack variable: " << key << " to \"" << value << "\""
- << std::endl);
- return true;
- } },
+ CommandArgument{ "-D", CommandArgument::Values::One,
+ [&log, &definitions](const std::string& arg, cmake*,
+ cmMakefile*) -> bool {
+ std::string value = arg;
+ size_t pos = value.find_first_of('=');
+ if (pos == std::string::npos) {
+ cmCPack_Log(
+ &log, cmCPackLog::LOG_ERROR,
+ "Please specify CPack definitions as: KEY=VALUE\n");
+ return false;
+ }
+ std::string key = value.substr(0, pos);
+ value.erase(0, pos + 1);
+ definitions[key] = value;
+ cmCPack_Log(&log, cmCPackLog::LOG_DEBUG,
+ "Set CPack variable: " << key << " to \""
+ << value << "\"\n");
+ return true;
+ } },
};
cmake cminst(cmake::RoleScript, cmState::CPack);
@@ -262,8 +272,7 @@ int main(int argc, char const* const* argv)
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Could not read presets from "
<< workingDirectory << ": "
- << cmCMakePresetsGraph::ResultToString(result)
- << std::endl);
+ << cmCMakePresetsGraph::ResultToString(result) << '\n');
return 1;
}
@@ -276,7 +285,7 @@ int main(int argc, char const* const* argv)
if (presetPair == presetsGraph.PackagePresets.end()) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"No such package preset in " << workingDirectory << ": \""
- << preset << '"' << std::endl);
+ << preset << "\"\n");
presetsGraph.PrintPackagePresetList(presetGeneratorsPresent);
return 1;
}
@@ -284,8 +293,7 @@ int main(int argc, char const* const* argv)
if (presetPair->second.Unexpanded.Hidden) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Cannot use hidden package preset in "
- << workingDirectory << ": \"" << preset << '"'
- << std::endl);
+ << workingDirectory << ": \"" << preset << "\"\n");
presetsGraph.PrintPackagePresetList(presetGeneratorsPresent);
return 1;
}
@@ -294,7 +302,7 @@ int main(int argc, char const* const* argv)
if (!expandedPreset) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Could not evaluate package preset \""
- << preset << "\": Invalid macro expansion" << std::endl);
+ << preset << "\": Invalid macro expansion\n");
presetsGraph.PrintPackagePresetList(presetGeneratorsPresent);
return 1;
}
@@ -302,8 +310,7 @@ int main(int argc, char const* const* argv)
if (!expandedPreset->ConditionResult) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Cannot use disabled package preset in "
- << workingDirectory << ": \"" << preset << '"'
- << std::endl);
+ << workingDirectory << ": \"" << preset << "\"\n");
presetsGraph.PrintPackagePresetList(presetGeneratorsPresent);
return 1;
}
@@ -320,7 +327,7 @@ int main(int argc, char const* const* argv)
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"No such configure preset in "
<< workingDirectory << ": \""
- << expandedPreset->ConfigurePreset << '"' << std::endl);
+ << expandedPreset->ConfigurePreset << "\"\n");
presetsGraph.PrintConfigurePresetList();
return 1;
}
@@ -329,7 +336,7 @@ int main(int argc, char const* const* argv)
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Cannot use hidden configure preset in "
<< workingDirectory << ": \""
- << expandedPreset->ConfigurePreset << '"' << std::endl);
+ << expandedPreset->ConfigurePreset << "\"\n");
presetsGraph.PrintConfigurePresetList();
return 1;
}
@@ -339,7 +346,7 @@ int main(int argc, char const* const* argv)
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Could not evaluate configure preset \""
<< expandedPreset->ConfigurePreset
- << "\": Invalid macro expansion" << std::endl);
+ << "\": Invalid macro expansion\n");
return 1;
}
@@ -395,7 +402,7 @@ int main(int argc, char const* const* argv)
}
cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
- "Read CPack config file: " << cpackConfigFile << std::endl);
+ "Read CPack config file: " << cpackConfigFile << '\n');
bool cpackConfigFileSpecified = true;
if (cpackConfigFile.empty()) {
@@ -423,7 +430,7 @@ int main(int argc, char const* const* argv)
globalMF.GetModulesFile("CMakeDetermineSystem.cmake");
if (!globalMF.ReadListFile(systemFile)) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
- "Error reading CMakeDetermineSystem.cmake" << std::endl);
+ "Error reading CMakeDetermineSystem.cmake\n");
return 1;
}
@@ -431,8 +438,7 @@ int main(int argc, char const* const* argv)
globalMF.GetModulesFile("CMakeSystemSpecificInformation.cmake");
if (!globalMF.ReadListFile(systemFile)) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
- "Error reading CMakeSystemSpecificInformation.cmake"
- << std::endl);
+ "Error reading CMakeSystemSpecificInformation.cmake\n");
return 1;
}
@@ -444,17 +450,17 @@ int main(int argc, char const* const* argv)
cpackConfigFile = cmSystemTools::CollapseFullPath(cpackConfigFile);
cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
"Read CPack configuration file: " << cpackConfigFile
- << std::endl);
+ << '\n');
if (!globalMF.ReadListFile(cpackConfigFile)) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
- "Problem reading CPack config file: \""
- << cpackConfigFile << "\"" << std::endl);
+ "Problem reading CPack config file: \"" << cpackConfigFile
+ << "\"\n");
return 1;
}
} else if (cpackConfigFileSpecified) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Cannot find CPack config file: \"" << cpackConfigFile
- << "\"" << std::endl);
+ << "\"\n");
return 1;
}
@@ -503,17 +509,17 @@ int main(int argc, char const* const* argv)
cmValue genList = globalMF.GetDefinition("CPACK_GENERATOR");
if (!genList) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
- "CPack generator not specified" << std::endl);
+ "CPack generator not specified\n");
} else {
std::vector<std::string> generatorsVector = cmExpandedList(*genList);
for (std::string const& gen : generatorsVector) {
cmMakefile::ScopePushPop raii(&globalMF);
cmMakefile* mf = &globalMF;
cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
- "Specified generator: " << gen << std::endl);
+ "Specified generator: " << gen << '\n');
if (!mf->GetDefinition("CPACK_PACKAGE_NAME")) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
- "CPack project name not specified" << std::endl);
+ "CPack project name not specified" << '\n');
parsed = false;
}
if (parsed &&
@@ -522,13 +528,11 @@ int main(int argc, char const* const* argv)
mf->GetDefinition("CPACK_PACKAGE_VERSION_MINOR") &&
mf->GetDefinition("CPACK_PACKAGE_VERSION_PATCH")))) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
- "CPack project version not specified"
- << std::endl
- << "Specify CPACK_PACKAGE_VERSION, or "
- "CPACK_PACKAGE_VERSION_MAJOR, "
- "CPACK_PACKAGE_VERSION_MINOR, and "
- "CPACK_PACKAGE_VERSION_PATCH."
- << std::endl);
+ "CPack project version not specified\n"
+ "Specify CPACK_PACKAGE_VERSION, or "
+ "CPACK_PACKAGE_VERSION_MAJOR, "
+ "CPACK_PACKAGE_VERSION_MINOR, and "
+ "CPACK_PACKAGE_VERSION_PATCH.\n");
parsed = false;
}
if (parsed) {
@@ -539,19 +543,12 @@ int main(int argc, char const* const* argv)
cpackGenerator->SetTraceExpand(cminst.GetTraceExpand());
} else {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
- "Could not create CPack generator: " << gen
- << std::endl);
+ "Could not create CPack generator: " << gen << '\n');
// Print out all the valid generators
cmDocumentation generatorDocs;
- std::vector<cmDocumentationEntry> v;
- for (auto const& g : generators.GetGeneratorsList()) {
- cmDocumentationEntry e;
- e.Name = g.first;
- e.Brief = g.second;
- v.push_back(std::move(e));
- }
- generatorDocs.SetSection("Generators", v);
- std::cerr << "\n";
+ generatorDocs.SetSection("Generators",
+ makeGeneratorDocs(generators));
+ std::cerr << '\n';
generatorDocs.PrintDocumentation(cmDocumentation::ListGenerators,
std::cerr);
parsed = false;
@@ -559,8 +556,7 @@ int main(int argc, char const* const* argv)
if (parsed && !cpackGenerator->Initialize(gen, mf)) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
- "Cannot initialize the generator " << gen
- << std::endl);
+ "Cannot initialize the generator " << gen << '\n');
parsed = false;
}
@@ -573,17 +569,16 @@ int main(int argc, char const* const* argv)
"Please specify build tree of the project that uses CMake "
"using CPACK_INSTALL_CMAKE_PROJECTS, specify "
"CPACK_INSTALL_COMMANDS, CPACK_INSTALL_SCRIPT, or "
- "CPACK_INSTALLED_DIRECTORIES."
- << std::endl);
+ "CPACK_INSTALLED_DIRECTORIES.\n");
parsed = false;
}
if (parsed) {
cmValue projName = mf->GetDefinition("CPACK_PACKAGE_NAME");
cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
"Use generator: " << cpackGenerator->GetNameOfClass()
- << std::endl);
+ << '\n');
cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
- "For project: " << *projName << std::endl);
+ "For project: " << *projName << '\n');
cmValue projVersion = mf->GetDefinition("CPACK_PACKAGE_VERSION");
if (!projVersion) {
@@ -594,7 +589,7 @@ int main(int argc, char const* const* argv)
cmValue projVersionPatch =
mf->GetDefinition("CPACK_PACKAGE_VERSION_PATCH");
std::ostringstream ostr;
- ostr << *projVersionMajor << "." << *projVersionMinor << "."
+ ostr << *projVersionMajor << "." << *projVersionMinor << '.'
<< *projVersionPatch;
mf->AddDefinition("CPACK_PACKAGE_VERSION", ostr.str());
}
@@ -603,7 +598,7 @@ int main(int argc, char const* const* argv)
if (!res) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Error when generating package: " << *projName
- << std::endl);
+ << '\n');
return 1;
}
}
@@ -618,27 +613,13 @@ int main(int argc, char const* const* argv)
*/
if (help) {
// Construct and print requested documentation.
-
doc.SetName("cpack");
doc.SetSection("Name", cmDocumentationName);
doc.SetSection("Usage", cmDocumentationUsage);
doc.PrependSection("Options", cmDocumentationOptions);
-
- std::vector<cmDocumentationEntry> v;
- for (auto const& g : generators.GetGeneratorsList()) {
- cmDocumentationEntry e;
- e.Name = g.first;
- e.Brief = g.second;
- v.push_back(std::move(e));
- }
- doc.SetSection("Generators", v);
-
- return doc.PrintRequestedDocumentation(std::cout) ? 0 : 1;
- }
-
- if (cmSystemTools::GetErrorOccurredFlag()) {
- return 1;
+ doc.SetSection("Generators", makeGeneratorDocs(generators));
+ return !doc.PrintRequestedDocumentation(std::cout);
}
- return 0;
+ return int(cmSystemTools::GetErrorOccurredFlag());
}
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index a39c52f..643bc6f 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -165,7 +165,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
if (outstring) {
*outstring = "--build-and-test requires that the generator "
"be provided using the --build-generator "
- "command line option. ";
+ "command line option.\n";
}
return 1;
}
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index fd20398..1f3633d 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -122,10 +122,15 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
cmakeConfigureCommand += "\"";
}
- cmakeConfigureCommand += " \"";
+ cmakeConfigureCommand += " \"-S";
cmakeConfigureCommand += source_dir;
cmakeConfigureCommand += "\"";
+ cmakeConfigureCommand += " \"-B";
+ cmakeConfigureCommand +=
+ this->CTest->GetCTestConfiguration("BuildDirectory");
+ cmakeConfigureCommand += "\"";
+
this->CTest->SetCTestConfiguration("ConfigureCommand",
cmakeConfigureCommand, this->Quiet);
} else {
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index f7c6a9c..5c48cbf 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -73,6 +73,7 @@ public:
bool StartProcess()
{
std::vector<const char*> args;
+ args.reserve(this->CommandLineStrings.size());
for (std::string const& cl : this->CommandLineStrings) {
args.push_back(cl.c_str());
}
diff --git a/Source/CTest/cmCTestCurl.cxx b/Source/CTest/cmCTestCurl.cxx
index 69c5793..84161f9 100644
--- a/Source/CTest/cmCTestCurl.cxx
+++ b/Source/CTest/cmCTestCurl.cxx
@@ -112,7 +112,7 @@ bool cmCTestCurl::UploadFile(std::string const& local_file,
{
response.clear();
if (!this->InitCurl()) {
- cmCTestLog(this->CTest, ERROR_MESSAGE, "Initialization of curl failed");
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Initialization of curl failed\n");
return false;
}
/* enable uploading */
@@ -176,7 +176,7 @@ bool cmCTestCurl::UploadFile(std::string const& local_file,
if (response.empty()) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"No response from server.\n"
- << curlDebug);
+ << curlDebug << std::endl);
return false;
}
return true;
@@ -192,7 +192,7 @@ bool cmCTestCurl::HttpRequest(std::string const& url,
<< "fields " << fields << "\n",
this->Quiet);
if (!this->InitCurl()) {
- cmCTestLog(this->CTest, ERROR_MESSAGE, "Initialization of curl failed");
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Initialization of curl failed\n");
return false;
}
curl_easy_setopt(this->Curl, CURLOPT_POST, 1);
diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx
index 1c292c7..dd69968 100644
--- a/Source/CTest/cmCTestGenericHandler.cxx
+++ b/Source/CTest/cmCTestGenericHandler.cxx
@@ -26,13 +26,8 @@ namespace {
* is non-null, otherwise removing key `op` (if it exists).
*/
void SetMapValue(cmCTestGenericHandler::t_StringToString& map,
- const std::string& op, const char* value)
+ const std::string& op, const std::string& value)
{
- if (!value) {
- map.erase(op);
- return;
- }
-
map[op] = value;
}
void SetMapValue(cmCTestGenericHandler::t_StringToString& map,
@@ -47,7 +42,8 @@ void SetMapValue(cmCTestGenericHandler::t_StringToString& map,
}
}
-void cmCTestGenericHandler::SetOption(const std::string& op, const char* value)
+void cmCTestGenericHandler::SetOption(const std::string& op,
+ const std::string& value)
{
SetMapValue(this->Options, op, value);
}
@@ -57,7 +53,7 @@ void cmCTestGenericHandler::SetOption(const std::string& op, cmValue value)
}
void cmCTestGenericHandler::SetPersistentOption(const std::string& op,
- const char* value)
+ const std::string& value)
{
this->SetOption(op, value);
SetMapValue(this->PersistentOptions, op, value);
@@ -121,7 +117,7 @@ bool cmCTestGenericHandler::StartResultingXML(cmCTest::Part part,
if (!name) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Cannot create resulting XML file without providing the name"
- << std::endl;);
+ << std::endl);
return false;
}
std::ostringstream ostr;
@@ -157,7 +153,7 @@ bool cmCTestGenericHandler::StartLogFile(const char* name,
if (!name) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Cannot create log file without providing the name"
- << std::endl;);
+ << std::endl);
return false;
}
std::ostringstream ostr;
diff --git a/Source/CTest/cmCTestGenericHandler.h b/Source/CTest/cmCTestGenericHandler.h
index 4bdb9c2..a0197d6 100644
--- a/Source/CTest/cmCTestGenericHandler.h
+++ b/Source/CTest/cmCTestGenericHandler.h
@@ -85,17 +85,9 @@ public:
* so calling a single-getter for a key that has only been set
* as a multi-value will return nullptr.
*/
- void SetPersistentOption(const std::string& op, const char* value);
- void SetPersistentOption(const std::string& op, const std::string& value)
- {
- this->SetPersistentOption(op, cmValue(value));
- }
+ void SetPersistentOption(const std::string& op, const std::string& value);
void SetPersistentOption(const std::string& op, cmValue value);
- void SetOption(const std::string& op, const char* value);
- void SetOption(const std::string& op, const std::string& value)
- {
- this->SetOption(op, cmValue(value));
- }
+ void SetOption(const std::string& op, const std::string& value);
void SetOption(const std::string& op, cmValue value);
cmValue GetOption(const std::string& op);
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index be952cd..c377d68 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -143,7 +143,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
"BuildDirectory", cmSystemTools::CollapseFullPath(bdir), this->Quiet);
} else {
cmCTestLog(this->CTest, ERROR_MESSAGE,
- "CTEST_BINARY_DIRECTORY not set" << std::endl;);
+ "CTEST_BINARY_DIRECTORY not set" << std::endl);
}
}
if (!this->Source.empty()) {
@@ -164,7 +164,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
this->CTest->SetCTestConfiguration("ChangeId", *changeId, this->Quiet);
}
- cmCTestLog(this->CTest, DEBUG, "Initialize handler" << std::endl;);
+ cmCTestLog(this->CTest, DEBUG, "Initialize handler" << std::endl);
cmCTestGenericHandler* handler = this->InitializeHandler();
if (!handler) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index 1f7776c..18c1a80 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -16,45 +16,38 @@
#include "cmCursesMainForm.h"
#include "cmCursesStandardIncludes.h"
#include "cmDocumentation.h"
-#include "cmDocumentationEntry.h" // IWYU pragma: keep
+#include "cmDocumentationEntry.h"
#include "cmMessageMetadata.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
-static const char* cmDocumentationName[][2] = {
- { nullptr, " ccmake - Curses Interface for CMake." },
- { nullptr, nullptr }
+namespace {
+const cmDocumentationEntry cmDocumentationName = {
+ {},
+ " ccmake - Curses Interface for CMake."
};
-static const char* cmDocumentationUsage[][2] = {
- { nullptr,
+const cmDocumentationEntry cmDocumentationUsage[2] = {
+ { {},
" ccmake <path-to-source>\n"
" ccmake <path-to-existing-build>" },
- { nullptr,
+ { {},
"Specify a source directory to (re-)generate a build system for "
"it in the current working directory. Specify an existing build "
"directory to re-generate its build system." },
- { nullptr, nullptr }
};
-static const char* cmDocumentationUsageNote[][2] = {
- { nullptr, "Run 'ccmake --help' for more information." },
- { nullptr, nullptr }
+const cmDocumentationEntry cmDocumentationUsageNote = {
+ {},
+ "Run 'ccmake --help' for more information."
};
-static const char* cmDocumentationOptions[][2] = {
- CMAKE_STANDARD_OPTIONS_TABLE,
- { nullptr, nullptr }
-};
-
-cmCursesForm* cmCursesForm::CurrentForm = nullptr;
-
#ifndef _WIN32
extern "C" {
-static void onsig(int /*unused*/)
+void onsig(int /*unused*/)
{
if (cmCursesForm::CurrentForm) {
cmCursesForm::CurrentForm->HandleResize();
@@ -63,6 +56,9 @@ static void onsig(int /*unused*/)
}
}
#endif // _WIN32
+} // anonymous namespace
+
+cmCursesForm* cmCursesForm::CurrentForm = nullptr;
int main(int argc, char const* const* argv)
{
@@ -77,7 +73,7 @@ int main(int argc, char const* const* argv)
cmDocumentation doc;
doc.addCMakeStandardDocSections();
if (doc.CheckOptions(argc, argv)) {
- cmake hcm(cmake::RoleInternal, cmState::Unknown);
+ cmake hcm(cmake::RoleInternal, cmState::Help);
hcm.SetHomeDirectory("");
hcm.SetHomeOutputDirectory("");
hcm.AddCMakePaths();
@@ -89,8 +85,8 @@ int main(int argc, char const* const* argv)
doc.AppendSection("Usage", cmDocumentationUsageNote);
}
doc.AppendSection("Generators", generators);
- doc.PrependSection("Options", cmDocumentationOptions);
- return doc.PrintRequestedDocumentation(std::cout) ? 0 : 1;
+ doc.PrependSection("Options", cmake::CMAKE_STANDARD_OPTIONS_TABLE);
+ return !doc.PrintRequestedDocumentation(std::cout);
}
bool debug = false;
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index fb12b7d..50e8e3a 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -22,26 +22,27 @@
#include "cmSystemTools.h" // IWYU pragma: keep
#include "cmake.h"
-static const char* cmDocumentationName[][2] = { { nullptr,
- " cmake-gui - CMake GUI." },
- { nullptr, nullptr } };
-
-static const char* cmDocumentationUsage[][2] = {
- { nullptr,
- " cmake-gui [options]\n"
- " cmake-gui [options] <path-to-source>\n"
- " cmake-gui [options] <path-to-existing-build>\n"
- " cmake-gui [options] -S <path-to-source> -B <path-to-build>\n"
- " cmake-gui [options] --browse-manual\n" },
- { nullptr, nullptr }
+namespace {
+const cmDocumentationEntry cmDocumentationName = {
+ {},
+ " cmake-gui - CMake GUI."
};
-static const char* cmDocumentationOptions[][2] = {
+const cmDocumentationEntry cmDocumentationUsage = {
+ {},
+ " cmake-gui [options]\n"
+ " cmake-gui [options] <path-to-source>\n"
+ " cmake-gui [options] <path-to-existing-build>\n"
+ " cmake-gui [options] -S <path-to-source> -B <path-to-build>\n"
+ " cmake-gui [options] --browse-manual"
+};
+
+const cmDocumentationEntry cmDocumentationOptions[3] = {
{ "-S <path-to-source>", "Explicitly specify a source directory." },
{ "-B <path-to-build>", "Explicitly specify a build directory." },
- { "--preset=<preset>", "Specify a configure preset." },
- { nullptr, nullptr }
+ { "--preset=<preset>", "Specify a configure preset." }
};
+} // anonymous namespace
#if defined(Q_OS_MAC)
static int cmOSXInstall(std::string dir);
@@ -79,7 +80,7 @@ int main(int argc, char** argv)
doc.addCMakeStandardDocSections();
if (argc2 > 1 && doc.CheckOptions(argc2, argv2)) {
// Construct and print requested documentation.
- cmake hcm(cmake::RoleInternal, cmState::Unknown);
+ cmake hcm(cmake::RoleInternal, cmState::Help);
hcm.SetHomeDirectory("");
hcm.SetHomeOutputDirectory("");
hcm.AddCMakePaths();
@@ -91,7 +92,7 @@ int main(int argc, char** argv)
doc.AppendSection("Generators", generators);
doc.PrependSection("Options", cmDocumentationOptions);
- return (doc.PrintRequestedDocumentation(std::cout) ? 0 : 1);
+ return !doc.PrintRequestedDocumentation(std::cout);
}
#if defined(Q_OS_MAC)
@@ -252,6 +253,7 @@ int main(int argc, char** argv)
# include <unistd.h>
# include "cm_sys_stat.h"
+
static bool cmOSXInstall(std::string const& dir, std::string const& tool)
{
if (tool.empty()) {
@@ -277,6 +279,7 @@ static bool cmOSXInstall(std::string const& dir, std::string const& tool)
<< "': " << strerror(err) << "\n";
return false;
}
+
static int cmOSXInstall(std::string dir)
{
if (!cmHasLiteralSuffix(dir, "/")) {
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index 01fa7bb..3d4d726 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -1344,7 +1344,8 @@ void CMakeSetupDialog::showUserChanges()
void CMakeSetupDialog::setSearchFilter(const QString& str)
{
this->CacheValues->selectionModel()->clear();
- this->CacheValues->setSearchFilter(str);
+ const bool valid = this->CacheValues->setSearchFilter(str);
+ QtCMake::setSearchFilterColor(this->Search, valid);
}
void CMakeSetupDialog::doOutputContextMenu(QPoint pt)
diff --git a/Source/QtDialog/EnvironmentDialog.cxx b/Source/QtDialog/EnvironmentDialog.cxx
index bf89816..2752c0f 100644
--- a/Source/QtDialog/EnvironmentDialog.cxx
+++ b/Source/QtDialog/EnvironmentDialog.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "EnvironmentDialog.h"
+#include "QCMakeWidgets.h"
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QItemSelectionModel>
@@ -110,14 +111,11 @@ EnvironmentDialog::EnvironmentDialog(const QProcessEnvironment& environment,
&EnvironmentDialog::addEntry);
QObject::connect(this->RemoveEntry, &QAbstractButton::clicked, this,
&EnvironmentDialog::removeSelectedEntries);
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
- QObject::connect(this->Search, &QLineEdit::textChanged, this->m_filter,
- QOverload<const QString&>::of(
- &EnvironmentSearchFilter::setFilterRegularExpression));
-#else
- QObject::connect(this->Search, &QLineEdit::textChanged, this->m_filter,
- &EnvironmentSearchFilter::setFilterFixedString);
-#endif
+ QObject::connect(
+ this->Search, &QLineEdit::textChanged, [this](const QString& text) {
+ const bool valid = QtCMake::setSearchFilter(this->m_filter, text);
+ QtCMake::setSearchFilterColor(this->Search, valid);
+ });
QObject::connect(this->Environment->selectionModel(),
&QItemSelectionModel::selectionChanged, this,
&EnvironmentDialog::selectionChanged);
diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx
index f79d6fc..6f19b67 100644
--- a/Source/QtDialog/QCMakeCacheView.cxx
+++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -167,13 +167,9 @@ bool QCMakeCacheView::showAdvanced() const
return this->AdvancedFilter->showAdvanced();
}
-void QCMakeCacheView::setSearchFilter(const QString& s)
+bool QCMakeCacheView::setSearchFilter(const QString& s)
{
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
- this->SearchFilter->setFilterRegularExpression(s);
-#else
- this->SearchFilter->setFilterFixedString(s);
-#endif
+ return QtCMake::setSearchFilter(this->SearchFilter, s);
}
QCMakeCacheModel::QCMakeCacheModel(QObject* p)
diff --git a/Source/QtDialog/QCMakeCacheView.h b/Source/QtDialog/QCMakeCacheView.h
index c5e6dd4..89068ab 100644
--- a/Source/QtDialog/QCMakeCacheView.h
+++ b/Source/QtDialog/QCMakeCacheView.h
@@ -28,12 +28,13 @@ public:
QSize sizeHint() const { return QSize(200, 200); }
+ // set the search filter string. any property key or value not matching will
+ // be filtered out
+ bool setSearchFilter(const QString&);
+
public slots:
// set whether to show advanced entries
void setShowAdvanced(bool);
- // set the search filter string. any property key or value not matching will
- // be filtered out
- void setSearchFilter(const QString&);
protected:
QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers);
diff --git a/Source/QtDialog/QCMakeWidgets.cxx b/Source/QtDialog/QCMakeWidgets.cxx
index 03d6ed1..f1bb2f1 100644
--- a/Source/QtDialog/QCMakeWidgets.cxx
+++ b/Source/QtDialog/QCMakeWidgets.cxx
@@ -10,8 +10,13 @@
#include <QFileDialog>
#include <QFileInfo>
#include <QResizeEvent>
+#include <QSortFilterProxyModel>
#include <QToolButton>
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
+# include <QRegularExpression>
+#endif
+
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
# include <QFileSystemModel>
#else
@@ -155,3 +160,32 @@ QString QCMakeFileCompleter::pathFromIndex(const QModelIndex& idx) const
{
return QDir::fromNativeSeparators(QCompleter::pathFromIndex(idx));
}
+
+namespace QtCMake {
+bool setSearchFilter(QSortFilterProxyModel* model, const QString& searchString)
+{
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
+ QRegularExpression const regex(searchString,
+ QRegularExpression::CaseInsensitiveOption |
+ QRegularExpression::DontCaptureOption);
+ if (regex.isValid()) {
+ model->setFilterRegularExpression(regex);
+ return true;
+ }
+ model->setFilterFixedString(QString{});
+ return false;
+#else
+ model->setFilterFixedString(searchString);
+ return true;
+#endif
+}
+
+void setSearchFilterColor(QLineEdit* edit, bool valid)
+{
+ QPalette palette;
+ if (!valid) {
+ palette.setColor(QPalette::Base, Qt::red);
+ }
+ edit->setPalette(palette);
+}
+}
diff --git a/Source/QtDialog/QCMakeWidgets.h b/Source/QtDialog/QCMakeWidgets.h
index 9a2a27e..858a913 100644
--- a/Source/QtDialog/QCMakeWidgets.h
+++ b/Source/QtDialog/QCMakeWidgets.h
@@ -9,6 +9,7 @@
#include <QLineEdit>
class QToolButton;
+class QSortFilterProxyModel;
// common widgets for Qt based CMake
@@ -76,3 +77,10 @@ public:
}
}
};
+
+namespace QtCMake {
+bool setSearchFilter(QSortFilterProxyModel* model,
+ const QString& searchString);
+
+void setSearchFilterColor(QLineEdit* edit, bool valid);
+}
diff --git a/Source/cmBinUtilsLinuxELFLinker.cxx b/Source/cmBinUtilsLinuxELFLinker.cxx
index a69c00d..5972202 100644
--- a/Source/cmBinUtilsLinuxELFLinker.cxx
+++ b/Source/cmBinUtilsLinuxELFLinker.cxx
@@ -154,8 +154,13 @@ bool cmBinUtilsLinuxELFLinker::ScanDependencies(
if (!this->Archive->IsPostExcluded(path)) {
bool unique;
this->Archive->AddResolvedPath(dep, path, unique);
- if (unique && !this->ScanDependencies(path, rpaths)) {
- return false;
+ if (unique) {
+ std::vector<std::string> combinedParentRpaths = parentRpaths;
+ combinedParentRpaths.insert(combinedParentRpaths.end(),
+ rpaths.begin(), rpaths.end());
+ if (!this->ScanDependencies(path, combinedParentRpaths)) {
+ return false;
+ }
}
}
} else {
diff --git a/Source/cmCMakePresetsGraphInternal.h b/Source/cmCMakePresetsGraphInternal.h
index 9e47a69..2726e92 100644
--- a/Source/cmCMakePresetsGraphInternal.h
+++ b/Source/cmCMakePresetsGraphInternal.h
@@ -1,5 +1,7 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
#include <memory>
#include <string>
#include <vector>
diff --git a/Source/cmCMakePresetsGraphReadJSON.cxx b/Source/cmCMakePresetsGraphReadJSON.cxx
index eec53c1..a96ab58 100644
--- a/Source/cmCMakePresetsGraphReadJSON.cxx
+++ b/Source/cmCMakePresetsGraphReadJSON.cxx
@@ -518,9 +518,7 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
PresetPair<ConfigurePreset> presetPair;
presetPair.Unexpanded = preset;
presetPair.Expanded = cm::nullopt;
- if (!this->ConfigurePresets
- .emplace(std::make_pair(preset.Name, presetPair))
- .second) {
+ if (!this->ConfigurePresets.emplace(preset.Name, presetPair).second) {
return ReadFileResult::DUPLICATE_PRESETS;
}
diff --git a/Source/cmCPluginAPI.h b/Source/cmCPluginAPI.h
index 19626f0..0d8a366 100644
--- a/Source/cmCPluginAPI.h
+++ b/Source/cmCPluginAPI.h
@@ -8,7 +8,7 @@
loosely into four groups 1) Utility 2) cmMakefile 3) cmSourceFile 4)
cmSystemTools. Within each grouping functions are listed alphabetically */
/*=========================================================================*/
-#ifndef cmCPluginAPI_h
+#ifndef cmCPluginAPI_h /* NOLINT(cmake-use-pragma-once) */
#define cmCPluginAPI_h
#define CMAKE_VERSION_MAJOR 2
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index f60a1e9..b00fa73 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -410,7 +410,8 @@ cmCTest::Part cmCTest::GetPartFromName(const std::string& name)
return PartCount;
}
-int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
+int cmCTest::Initialize(const std::string& binary_dir,
+ cmCTestStartCommand* command)
{
bool quiet = false;
if (command && command->ShouldBeQuiet()) {
@@ -683,7 +684,7 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command)
this->SetCTestConfigurationFromCMakeVariable(
mf, "BuildName", "CTEST_BUILD_NAME", command->ShouldBeQuiet());
- if (!this->Initialize(bld_dir.c_str(), command)) {
+ if (!this->Initialize(bld_dir, command)) {
return false;
}
cmCTestOptionalLog(this, OUTPUT,
@@ -943,8 +944,7 @@ int cmCTest::ProcessSteps()
(this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) {
cmCTestUpdateHandler* uphandler = this->GetUpdateHandler();
uphandler->SetPersistentOption(
- "SourceDirectory",
- this->GetCTestConfiguration("SourceDirectory").c_str());
+ "SourceDirectory", this->GetCTestConfiguration("SourceDirectory"));
update_count = uphandler->ProcessHandler();
if (update_count < 0) {
res |= cmCTest::UPDATE_ERRORS;
@@ -1691,7 +1691,7 @@ bool cmCTest::SubmitExtraFiles(std::vector<std::string> const& files)
if (!cmSystemTools::FileExists(file)) {
cmCTestLog(this, ERROR_MESSAGE,
"Cannot find extra file: " << file << " to submit."
- << std::endl;);
+ << std::endl);
return false;
}
this->AddSubmitFile(PartExtraFiles, file);
@@ -2139,9 +2139,9 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption("TestsToRunInformation",
- args[i].c_str());
+ args[i]);
this->GetMemCheckHandler()->SetPersistentOption("TestsToRunInformation",
- args[i].c_str());
+ args[i]);
} else if (this->CheckArgument(arg, "-U"_s, "--union")) {
this->GetTestHandler()->SetPersistentOption("UseUnion", "true");
this->GetMemCheckHandler()->SetPersistentOption("UseUnion", "true");
@@ -2149,9 +2149,9 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption("IncludeRegularExpression",
- args[i].c_str());
+ args[i]);
this->GetMemCheckHandler()->SetPersistentOption("IncludeRegularExpression",
- args[i].c_str());
+ args[i]);
} else if (this->CheckArgument(arg, "-L"_s, "--label-regex") &&
i < args.size() - 1) {
i++;
@@ -2172,41 +2172,40 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption("ExcludeRegularExpression",
- args[i].c_str());
+ args[i]);
this->GetMemCheckHandler()->SetPersistentOption("ExcludeRegularExpression",
- args[i].c_str());
+ args[i]);
}
else if (this->CheckArgument(arg, "-FA"_s, "--fixture-exclude-any") &&
i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption(
- "ExcludeFixtureRegularExpression", args[i].c_str());
+ "ExcludeFixtureRegularExpression", args[i]);
this->GetMemCheckHandler()->SetPersistentOption(
- "ExcludeFixtureRegularExpression", args[i].c_str());
+ "ExcludeFixtureRegularExpression", args[i]);
} else if (this->CheckArgument(arg, "-FS"_s, "--fixture-exclude-setup") &&
i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption(
- "ExcludeFixtureSetupRegularExpression", args[i].c_str());
+ "ExcludeFixtureSetupRegularExpression", args[i]);
this->GetMemCheckHandler()->SetPersistentOption(
- "ExcludeFixtureSetupRegularExpression", args[i].c_str());
+ "ExcludeFixtureSetupRegularExpression", args[i]);
} else if (this->CheckArgument(arg, "-FC"_s, "--fixture-exclude-cleanup") &&
i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption(
- "ExcludeFixtureCleanupRegularExpression", args[i].c_str());
+ "ExcludeFixtureCleanupRegularExpression", args[i]);
this->GetMemCheckHandler()->SetPersistentOption(
- "ExcludeFixtureCleanupRegularExpression", args[i].c_str());
+ "ExcludeFixtureCleanupRegularExpression", args[i]);
}
else if (this->CheckArgument(arg, "--resource-spec-file"_s) &&
i < args.size() - 1) {
i++;
- this->GetTestHandler()->SetPersistentOption("ResourceSpecFile",
- args[i].c_str());
+ this->GetTestHandler()->SetPersistentOption("ResourceSpecFile", args[i]);
this->GetMemCheckHandler()->SetPersistentOption("ResourceSpecFile",
- args[i].c_str());
+ args[i]);
}
else if (this->CheckArgument(arg, "--rerun-failed"_s)) {
@@ -2314,8 +2313,8 @@ void cmCTest::SetPersistentOptionIfNotEmpty(const std::string& value,
const std::string& optionName)
{
if (!value.empty()) {
- this->GetTestHandler()->SetPersistentOption(optionName, value.c_str());
- this->GetMemCheckHandler()->SetPersistentOption(optionName, value.c_str());
+ this->GetTestHandler()->SetPersistentOption(optionName, value);
+ this->GetMemCheckHandler()->SetPersistentOption(optionName, value);
}
}
@@ -2758,8 +2757,9 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output)
// intended
for (auto& handler : this->Impl->GetTestingHandlers()) {
if (!handler->ProcessCommandLineArguments(arg, i, args)) {
- cmCTestLog(this, ERROR_MESSAGE,
- "Problem parsing command line arguments within a handler");
+ cmCTestLog(
+ this, ERROR_MESSAGE,
+ "Problem parsing command line arguments within a handler\n");
return 0;
}
}
@@ -2903,7 +2903,7 @@ int cmCTest::ExecuteTests()
}
}
- if (!this->Initialize(workDir.c_str(), nullptr)) {
+ if (!this->Initialize(workDir, nullptr)) {
res = 12;
cmCTestLog(this, ERROR_MESSAGE,
"Problem initializing the dashboard." << std::endl);
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 0017b3e..9a8d5a6 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -481,7 +481,7 @@ private:
* call this method because it sets CTEST_COMMAND to drive a build
* through the ctest command line.
*/
- int Initialize(const char* binary_dir, cmCTestStartCommand* command);
+ int Initialize(const std::string& binary_dir, cmCTestStartCommand* command);
/** parse the option after -D and convert it into the appropriate steps */
bool AddTestsForDashboardType(std::string& targ);
diff --git a/Source/cmCallVisualStudioMacro.h b/Source/cmCallVisualStudioMacro.h
index 795b863..78f22ae 100644
--- a/Source/cmCallVisualStudioMacro.h
+++ b/Source/cmCallVisualStudioMacro.h
@@ -19,8 +19,7 @@ public:
//! given solution file open. Pass "ALL" for slnFile to call the
//! macro in each Visual Studio instance.
static int CallMacro(const std::string& slnFile, const std::string& macro,
- const std::string& args,
- const bool logErrorsAsMessages);
+ const std::string& args, bool logErrorsAsMessages);
//! Count the number of running instances of Visual Studio with the
//! given solution file open. Pass "ALL" for slnFile to count all
diff --git a/Source/cmCommandLineArgument.h b/Source/cmCommandLineArgument.h
index 33c91bc..003e972 100644
--- a/Source/cmCommandLineArgument.h
+++ b/Source/cmCommandLineArgument.h
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#pragma once
+#include <cm/optional>
+
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -250,6 +252,15 @@ private:
return true;
};
}
+
+ static std::function<bool(const std::string&, CallState...)>
+ generateSetToValue(cm::optional<std::string>& value1)
+ {
+ return [&value1](const std::string& arg, CallState&&...) -> bool {
+ value1 = arg;
+ return true;
+ };
+ }
};
std::string extract_single_value(std::string const& input,
diff --git a/Source/cmConfigureLog.cxx b/Source/cmConfigureLog.cxx
new file mode 100644
index 0000000..c2a5b5e
--- /dev/null
+++ b/Source/cmConfigureLog.cxx
@@ -0,0 +1,261 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmConfigureLog.h"
+
+#include <cassert>
+#include <cstdio>
+#include <iterator>
+#include <sstream>
+#include <utility>
+
+#include <cmext/algorithm>
+#include <cmext/string_view>
+
+#include <cm3p/json/writer.h>
+
+#include "cm_utf8.h"
+
+#include "cmListFileCache.h"
+#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+#include "cmake.h"
+
+cmConfigureLog::cmConfigureLog(std::string logDir,
+ std::vector<unsigned long> logVersions)
+ : LogDir(std::move(logDir))
+ , LogVersions(std::move(logVersions))
+{
+ // Always emit events for the latest log version.
+ static const unsigned long LatestLogVersion = 1;
+ if (!cm::contains(this->LogVersions, LatestLogVersion)) {
+ this->LogVersions.emplace_back(LatestLogVersion);
+ }
+
+ Json::StreamWriterBuilder builder;
+ this->Encoder.reset(builder.newStreamWriter());
+}
+
+cmConfigureLog::~cmConfigureLog()
+{
+ if (this->Opened) {
+ this->EndObject();
+ this->Stream << "...\n";
+ }
+}
+
+bool cmConfigureLog::IsAnyLogVersionEnabled(
+ std::vector<unsigned long> const& v) const
+{
+ // Both input lists are sorted. Look for a matching element.
+ auto i1 = v.cbegin();
+ auto i2 = this->LogVersions.cbegin();
+ while (i1 != v.cend() && i2 != this->LogVersions.cend()) {
+ if (*i1 < *i2) {
+ ++i1;
+ } else if (*i2 < *i1) {
+ ++i2;
+ } else {
+ return true;
+ }
+ }
+ return false;
+}
+
+void cmConfigureLog::WriteBacktrace(cmMakefile const& mf)
+{
+ std::vector<std::string> backtrace;
+ auto root = mf.GetCMakeInstance()->GetHomeDirectory();
+ for (auto bt = mf.GetBacktrace(); !bt.Empty(); bt = bt.Pop()) {
+ auto t = bt.Top();
+ if (!t.Name.empty() || t.Line == cmListFileContext::DeferPlaceholderLine) {
+ t.FilePath = cmSystemTools::RelativeIfUnder(root, t.FilePath);
+ std::ostringstream s;
+ s << t;
+ backtrace.emplace_back(s.str());
+ }
+ }
+ this->WriteValue("backtrace"_s, backtrace);
+}
+
+void cmConfigureLog::EnsureInit()
+{
+ if (this->Opened) {
+ return;
+ }
+ assert(!this->Stream.is_open());
+
+ std::string name = cmStrCat(this->LogDir, "/CMakeConfigureLog.yaml");
+ this->Stream.open(name.c_str(), std::ios::out | std::ios::app);
+
+ this->Opened = true;
+
+ this->Stream << "\n---\n";
+ this->BeginObject("events"_s);
+}
+
+cmsys::ofstream& cmConfigureLog::BeginLine()
+{
+ for (unsigned i = 0; i < this->Indent; ++i) {
+ this->Stream << " ";
+ }
+ return this->Stream;
+}
+
+void cmConfigureLog::EndLine()
+{
+ this->Stream << std::endl;
+}
+
+void cmConfigureLog::BeginObject(cm::string_view key)
+{
+ this->BeginLine() << key << ':';
+ this->EndLine();
+ ++this->Indent;
+}
+
+void cmConfigureLog::EndObject()
+{
+ assert(this->Indent);
+ --this->Indent;
+}
+
+void cmConfigureLog::BeginEvent(std::string const& kind)
+{
+ this->EnsureInit();
+
+ this->BeginLine() << '-';
+ this->EndLine();
+
+ ++this->Indent;
+
+ this->WriteValue("kind"_s, kind);
+}
+
+void cmConfigureLog::EndEvent()
+{
+ assert(this->Indent);
+ --this->Indent;
+}
+
+void cmConfigureLog::WriteValue(cm::string_view key, std::nullptr_t)
+{
+ this->BeginLine() << key << ": null";
+ this->EndLine();
+}
+
+void cmConfigureLog::WriteValue(cm::string_view key, bool value)
+{
+ this->BeginLine() << key << ": " << (value ? "true" : "false");
+ this->EndLine();
+}
+
+void cmConfigureLog::WriteValue(cm::string_view key, int value)
+{
+ this->BeginLine() << key << ": " << value;
+ this->EndLine();
+}
+
+void cmConfigureLog::WriteValue(cm::string_view key, std::string const& value)
+{
+ this->BeginLine() << key << ": ";
+ this->Encoder->write(value, &this->Stream);
+ this->EndLine();
+}
+
+void cmConfigureLog::WriteValue(cm::string_view key,
+ std::vector<std::string> const& list)
+{
+ this->BeginObject(key);
+ for (auto const& value : list) {
+ this->BeginLine() << "- ";
+ this->Encoder->write(value, &this->Stream);
+ this->EndLine();
+ }
+ this->EndObject();
+}
+
+void cmConfigureLog::WriteLiteralTextBlock(cm::string_view key,
+ cm::string_view text)
+{
+ this->BeginLine() << key << ": |";
+ this->EndLine();
+
+ auto const l = text.length();
+ if (l) {
+ ++this->Indent;
+ this->BeginLine();
+
+ auto i = decltype(l){ 0 };
+ while (i < l) {
+ // YAML allows ' ', '\t' and "printable characters", but NOT other
+ // ASCII whitespace; those must be escaped, as must the upper UNICODE
+ // control characters (U+0080 - U+009F)
+ static constexpr unsigned int C1_LAST = 0x9F;
+ auto const c = static_cast<unsigned char>(text[i]);
+ switch (c) {
+ case '\r':
+ // Print a carriage return only if it is not followed by a line feed.
+ ++i;
+ if (i == l || text[i] != '\n') {
+ this->WriteEscape(c);
+ }
+ break;
+ case '\n':
+ // Print any line feeds except the very last one
+ if (i + 1 < l) {
+ this->EndLine();
+ this->BeginLine();
+ }
+ ++i;
+ break;
+ case '\t':
+ // Print horizontal tab verbatim
+ this->Stream.put('\t');
+ ++i;
+ break;
+ case '\\':
+ // Escape backslash for disambiguation
+ this->Stream << "\\\\";
+ ++i;
+ break;
+ default:
+ if (c >= 32 && c < 127) {
+ // Print ascii byte.
+ this->Stream.put(text[i]);
+ ++i;
+ break;
+ } else if (c > 127) {
+ // Decode a UTF-8 sequence.
+ unsigned int c32;
+ auto const* const s = text.data() + i;
+ auto const* const e = text.data() + l;
+ auto const* const n = cm_utf8_decode_character(s, e, &c32);
+ if (n > s && c32 > C1_LAST) {
+ auto const k = std::distance(s, n);
+ this->Stream.write(s, static_cast<std::streamsize>(k));
+ i += static_cast<unsigned>(k);
+ break;
+ }
+ }
+
+ // Escape non-printable byte.
+ this->WriteEscape(c);
+ ++i;
+ break;
+ }
+ }
+
+ this->EndLine();
+ --this->Indent;
+ }
+}
+
+void cmConfigureLog::WriteEscape(unsigned char c)
+{
+ char buffer[6];
+ int n = snprintf(buffer, sizeof(buffer), "\\x%02x", c);
+ if (n > 0) {
+ this->Stream.write(buffer, n);
+ }
+}
diff --git a/Source/cmConfigureLog.h b/Source/cmConfigureLog.h
new file mode 100644
index 0000000..9caac66
--- /dev/null
+++ b/Source/cmConfigureLog.h
@@ -0,0 +1,68 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <cm/string_view>
+
+#include "cmsys/FStream.hxx"
+
+namespace Json {
+class StreamWriter;
+}
+
+class cmMakefile;
+
+class cmConfigureLog
+{
+public:
+ /** Construct with the log directory and a sorted list of enabled log
+ versions. The latest log version will be enabled regardless. */
+ cmConfigureLog(std::string logDir, std::vector<unsigned long> logVersions);
+ ~cmConfigureLog();
+
+ /** Return true if at least one of the log versions in the given sorted
+ list is enabled. */
+ bool IsAnyLogVersionEnabled(std::vector<unsigned long> const& v) const;
+
+ void WriteBacktrace(cmMakefile const& mf);
+
+ void EnsureInit();
+
+ void BeginEvent(std::string const& kind);
+ void EndEvent();
+
+ void BeginObject(cm::string_view key);
+ void EndObject();
+
+ // TODO other value types
+ void WriteValue(cm::string_view key, std::nullptr_t);
+ void WriteValue(cm::string_view key, bool value);
+ void WriteValue(cm::string_view key, int value);
+ void WriteValue(cm::string_view key, std::string const& value);
+ void WriteValue(cm::string_view key, std::vector<std::string> const& list);
+
+ void WriteTextBlock(cm::string_view key, cm::string_view text);
+ void WriteLiteralTextBlock(cm::string_view key, cm::string_view text);
+
+ void WriteLiteralTextBlock(cm::string_view key, std::string const& text)
+ {
+ this->WriteLiteralTextBlock(key, cm::string_view{ text });
+ }
+
+private:
+ std::string LogDir;
+ std::vector<unsigned long> LogVersions;
+ cmsys::ofstream Stream;
+ unsigned Indent = 0;
+ bool Opened = false;
+
+ std::unique_ptr<Json::StreamWriter> Encoder;
+
+ cmsys::ofstream& BeginLine();
+ void EndLine();
+ void WriteEscape(unsigned char c);
+};
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index b44111d..2a4ea80 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -7,6 +7,7 @@
#include <cstring>
#include <set>
#include <sstream>
+#include <type_traits>
#include <utility>
#include <cm/string_view>
@@ -16,6 +17,7 @@
#include "cmsys/FStream.hxx"
#include "cmArgumentParser.h"
+#include "cmConfigureLog.h"
#include "cmExportTryCompileFileGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
@@ -285,8 +287,8 @@ Arguments cmCoreTryCompile::ParseArgs(
return arguments;
}
-bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
- cmStateEnums::TargetType targetType)
+cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
+ Arguments& arguments, cmStateEnums::TargetType targetType)
{
this->OutputFile.clear();
// which signature were we called with ?
@@ -302,7 +304,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
arguments.SourceDirectoryOrFile->empty()) {
this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
"No <srcdir> specified.");
- return false;
+ return cm::nullopt;
}
sourceDirectory = *arguments.SourceDirectoryOrFile;
projectName = *arguments.ProjectName;
@@ -322,7 +324,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
if (!arguments.BinaryDirectory || arguments.BinaryDirectory->empty()) {
this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
"No <bindir> specified.");
- return false;
+ return cm::nullopt;
}
if (*arguments.BinaryDirectory == unique_binary_directory) {
// leave empty until we're ready to create it, so we don't try to remove
@@ -335,7 +337,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
MessageType::FATAL_ERROR,
cmStrCat("<bindir> is not an absolute path:\n '",
*arguments.BinaryDirectory, "'"));
- return false;
+ return cm::nullopt;
}
this->BinaryDirectory = *arguments.BinaryDirectory;
// compute the binary dir when TRY_COMPILE is called with a src file
@@ -367,7 +369,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
"IMPORTED LINK_LIBRARIES. Got ",
tgt->GetName(), " of type ",
cmState::GetTargetTypeName(tgt->GetType()), "."));
- return false;
+ return cm::nullopt;
}
if (tgt->IsImported()) {
targets.emplace_back(i);
@@ -379,28 +381,28 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
if (arguments.CopyFileTo && arguments.CopyFileTo->empty()) {
this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
"COPY_FILE must be followed by a file path");
- return false;
+ return cm::nullopt;
}
if (arguments.CopyFileError && arguments.CopyFileError->empty()) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"COPY_FILE_ERROR must be followed by a variable name");
- return false;
+ return cm::nullopt;
}
if (arguments.CopyFileError && !arguments.CopyFileTo) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"COPY_FILE_ERROR may be used only with COPY_FILE");
- return false;
+ return cm::nullopt;
}
if (arguments.Sources && arguments.Sources->empty()) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"SOURCES must be followed by at least one source file");
- return false;
+ return cm::nullopt;
}
if (this->SrcFileSignature) {
@@ -409,19 +411,19 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"SOURCE_FROM_CONTENT requires exactly two arguments");
- return false;
+ return cm::nullopt;
}
if (arguments.SourceFromVar && arguments.SourceFromVar->size() % 2) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"SOURCE_FROM_VAR requires exactly two arguments");
- return false;
+ return cm::nullopt;
}
if (arguments.SourceFromFile && arguments.SourceFromFile->size() % 2) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"SOURCE_FROM_FILE requires exactly two arguments");
- return false;
+ return cm::nullopt;
}
} else {
// only valid for srcfile signatures
@@ -430,19 +432,19 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
MessageType::FATAL_ERROR,
cmStrCat(arguments.LangProps.begin()->first,
" allowed only in source file signature"));
- return false;
+ return cm::nullopt;
}
if (!arguments.CompileDefs.empty()) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"COMPILE_DEFINITIONS allowed only in source file signature");
- return false;
+ return cm::nullopt;
}
if (arguments.CopyFileTo) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"COPY_FILE allowed only in source file signature");
- return false;
+ return cm::nullopt;
}
}
@@ -462,7 +464,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
e << "Attempt at a recursive or nested TRY_COMPILE in directory\n"
<< " " << this->BinaryDirectory << "\n";
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
- return false;
+ return cm::nullopt;
}
std::string outFileName = this->BinaryDirectory + "/CMakeLists.txt";
@@ -486,7 +488,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
const auto& content = (*arguments.SourceFromContent)[i + 1];
auto out = this->WriteSource(name, content, "SOURCE_FROM_CONTENT");
if (out.empty()) {
- return false;
+ return cm::nullopt;
}
sources.emplace_back(std::move(out));
}
@@ -499,7 +501,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
const auto& content = this->Makefile->GetDefinition(var);
auto out = this->WriteSource(name, content, "SOURCE_FROM_VAR");
if (out.empty()) {
- return false;
+ return cm::nullopt;
}
sources.emplace_back(std::move(out));
}
@@ -514,7 +516,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
const auto& msg =
cmStrCat("SOURCE_FROM_FILE given invalid filename \"", dst, "\"");
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg);
- return false;
+ return cm::nullopt;
}
auto dstPath = cmStrCat(this->BinaryDirectory, "/", dst);
@@ -523,7 +525,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
const auto& msg = cmStrCat("SOURCE_FROM_FILE failed to copy \"", src,
"\": ", result.GetString());
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg);
- return false;
+ return cm::nullopt;
}
sources.emplace_back(std::move(dstPath));
@@ -550,7 +552,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
err << cmJoin(langs, " ");
err << "\nSee project() command to enable other languages.";
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, err.str());
- return false;
+ return cm::nullopt;
}
}
@@ -577,7 +579,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
<< cmSystemTools::GetLastSystemError();
/* clang-format on */
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
- return false;
+ return cm::nullopt;
}
cmValue def = this->Makefile->GetDefinition("CMAKE_MODULE_PATH");
@@ -778,7 +780,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
"could not write export file.");
fclose(fout);
- return false;
+ return cm::nullopt;
}
fprintf(fout, "\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/%s\")\n\n",
fname.c_str());
@@ -1111,7 +1113,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
}
if (!arguments.CopyFileError) {
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, emsg.str());
- return false;
+ return cm::nullopt;
}
copyFileErrorMessage = emsg.str();
}
@@ -1122,7 +1124,15 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
this->Makefile->AddDefinition(copyFileError, copyFileErrorMessage);
}
}
- return res == 0;
+
+ cmTryCompileResult result;
+ result.SourceDirectory = sourceDirectory;
+ result.BinaryDirectory = this->BinaryDirectory;
+ result.Variable = *arguments.CompileResultVariable;
+ result.VariableCached = !arguments.NoCache;
+ result.Output = std::move(output);
+ result.ExitCode = res;
+ return cm::optional<cmTryCompileResult>(std::move(result));
}
bool cmCoreTryCompile::IsTemporary(std::string const& path)
@@ -1263,3 +1273,20 @@ std::string cmCoreTryCompile::WriteSource(std::string const& filename,
file.close();
return filepath;
}
+
+void cmCoreTryCompile::WriteTryCompileEventFields(
+ cmConfigureLog& log, cmTryCompileResult const& compileResult)
+{
+#ifndef CMAKE_BOOTSTRAP
+ log.BeginObject("directories"_s);
+ log.WriteValue("source"_s, compileResult.SourceDirectory);
+ log.WriteValue("binary"_s, compileResult.BinaryDirectory);
+ log.EndObject();
+ log.BeginObject("buildResult"_s);
+ log.WriteValue("variable"_s, compileResult.Variable);
+ log.WriteValue("cached"_s, compileResult.VariableCached);
+ log.WriteLiteralTextBlock("stdout"_s, compileResult.Output);
+ log.WriteValue("exitCode"_s, compileResult.ExitCode);
+ log.EndObject();
+#endif
+}
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index 3e1e12c..6d29586 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -14,10 +14,23 @@
#include "cmArgumentParserTypes.h"
#include "cmStateTypes.h"
+class cmConfigureLog;
class cmMakefile;
template <typename Iter>
class cmRange;
+struct cmTryCompileResult
+{
+ std::string SourceDirectory;
+ std::string BinaryDirectory;
+
+ bool VariableCached = true;
+ std::string Variable;
+
+ std::string Output;
+ int ExitCode = 1;
+};
+
/** \class cmCoreTryCompile
* \brief Base class for cmTryCompileCommand and cmTryRunCommand
*
@@ -80,8 +93,8 @@ public:
* This function requires at least two \p arguments and will crash if given
* fewer.
*/
- bool TryCompileCode(Arguments& arguments,
- cmStateEnums::TargetType targetType);
+ cm::optional<cmTryCompileResult> TryCompileCode(
+ Arguments& arguments, cmStateEnums::TargetType targetType);
/**
* Returns \c true if \p path resides within a CMake temporary directory,
@@ -103,6 +116,9 @@ public:
*/
void FindOutputFile(const std::string& targetName);
+ static void WriteTryCompileEventFields(
+ cmConfigureLog& log, cmTryCompileResult const& compileResult);
+
std::string BinaryDirectory;
std::string OutputFile;
std::string FindErrorMessage;
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index 41d4442..14c22e3 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -148,6 +148,14 @@ std::string EvaluateDepfile(std::string const& path,
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(path);
return cge->Evaluate(lg, config);
}
+
+std::string EvaluateComment(const char* comment,
+ cmGeneratorExpression const& ge,
+ cmLocalGenerator* lg, std::string const& config)
+{
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(comment);
+ return cge->Evaluate(lg, config);
+}
}
cmCustomCommandGenerator::cmCustomCommandGenerator(
@@ -172,7 +180,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(
};
}
- cmGeneratorExpression ge(cc.GetBacktrace());
+ cmGeneratorExpression ge(*lg->GetCMakeInstance(), cc.GetBacktrace());
cmGeneratorTarget const* target{ lg->FindGeneratorTargetToUse(
this->Target) };
@@ -417,7 +425,8 @@ std::string cmCustomCommandGenerator::GetDepfile() const
return "";
}
- cmGeneratorExpression ge(this->CC->GetBacktrace());
+ cmGeneratorExpression ge(*this->LG->GetCMakeInstance(),
+ this->CC->GetBacktrace());
return EvaluateDepfile(depfile, ge, this->LG, this->OutputConfig);
}
@@ -462,9 +471,19 @@ std::string cmCustomCommandGenerator::GetInternalDepfile() const
return this->ComputeInternalDepfile(this->OutputConfig, depfile);
}
-const char* cmCustomCommandGenerator::GetComment() const
+cm::optional<std::string> cmCustomCommandGenerator::GetComment() const
{
- return this->CC->GetComment();
+ const char* comment = this->CC->GetComment();
+ if (!comment) {
+ return cm::nullopt;
+ }
+ if (!*comment) {
+ return std::string();
+ }
+
+ cmGeneratorExpression ge(*this->LG->GetCMakeInstance(),
+ this->CC->GetBacktrace());
+ return EvaluateComment(comment, ge, this->LG, this->OutputConfig);
}
std::string cmCustomCommandGenerator::GetWorkingDirectory() const
diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h
index 73a8d38..4453654 100644
--- a/Source/cmCustomCommandGenerator.h
+++ b/Source/cmCustomCommandGenerator.h
@@ -58,7 +58,7 @@ public:
unsigned int GetNumberOfCommands() const;
std::string GetCommand(unsigned int c) const;
void AppendArguments(unsigned int c, std::string& cmd) const;
- const char* GetComment() const;
+ cm::optional<std::string> GetComment() const;
std::string GetWorkingDirectory() const;
std::vector<std::string> const& GetOutputs() const;
std::vector<std::string> const& GetByproducts() const;
diff --git a/Source/cmCxxModuleMapper.cxx b/Source/cmCxxModuleMapper.cxx
index 84691c9..cb37f2b 100644
--- a/Source/cmCxxModuleMapper.cxx
+++ b/Source/cmCxxModuleMapper.cxx
@@ -28,6 +28,38 @@ cm::optional<std::string> CxxModuleLocations::BmiGeneratorPathForModule(
namespace {
+std::string CxxModuleMapContentClang(CxxModuleLocations const& loc,
+ cmScanDepInfo const& obj)
+{
+ std::stringstream mm;
+
+ // Clang's command line only supports a single output. If more than one is
+ // expected, we cannot make a useful module map file.
+ if (obj.Provides.size() > 1) {
+ return {};
+ }
+
+ // A series of flags which tell the compiler where to look for modules.
+
+ for (auto const& p : obj.Provides) {
+ if (auto bmi_loc = loc.BmiGeneratorPathForModule(p.LogicalName)) {
+ // Force the TU to be considered a C++ module source file regardless of
+ // extension.
+ mm << "-x c++-module\n";
+
+ mm << "-fmodule-output=" << *bmi_loc << '\n';
+ break;
+ }
+ }
+ for (auto const& r : obj.Requires) {
+ if (auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName)) {
+ mm << "-fmodule-file=" << *bmi_loc << '\n';
+ }
+ }
+
+ return mm.str();
+}
+
std::string CxxModuleMapContentGcc(CxxModuleLocations const& loc,
cmScanDepInfo const& obj)
{
@@ -179,6 +211,8 @@ cm::static_string_view CxxModuleMapExtension(
{
if (format) {
switch (*format) {
+ case CxxModuleMapFormat::Clang:
+ return ".pcm"_s;
case CxxModuleMapFormat::Gcc:
return ".gcm"_s;
case CxxModuleMapFormat::Msvc:
@@ -297,6 +331,8 @@ std::string CxxModuleMapContent(CxxModuleMapFormat format,
CxxModuleUsage const& usages)
{
switch (format) {
+ case CxxModuleMapFormat::Clang:
+ return CxxModuleMapContentClang(loc, obj);
case CxxModuleMapFormat::Gcc:
return CxxModuleMapContentGcc(loc, obj);
case CxxModuleMapFormat::Msvc:
diff --git a/Source/cmCxxModuleMapper.h b/Source/cmCxxModuleMapper.h
index 8526a07..9271978 100644
--- a/Source/cmCxxModuleMapper.h
+++ b/Source/cmCxxModuleMapper.h
@@ -17,6 +17,7 @@
enum class CxxModuleMapFormat
{
+ Clang,
Gcc,
Msvc,
};
diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx
index d466a12..77c5295 100644
--- a/Source/cmDocumentation.cxx
+++ b/Source/cmDocumentation.cxx
@@ -16,7 +16,8 @@
#include "cmSystemTools.h"
#include "cmVersion.h"
-static const char* cmDocumentationStandardOptions[][2] = {
+namespace {
+const cmDocumentationEntry cmDocumentationStandardOptions[20] = {
{ "-h,-H,--help,-help,-usage,/?", "Print usage information and exit." },
{ "--version,-version,/V [<file>]", "Print version number and exit." },
{ "--help-full [<file>]", "Print all help manuals and exit." },
@@ -42,22 +43,27 @@ static const char* cmDocumentationStandardOptions[][2] = {
{ "--help-variable var [<file>]", "Print help for one variable and exit." },
{ "--help-variable-list [<file>]",
"List variables with help available and exit." },
- { "--help-variables [<file>]", "Print cmake-variables manual and exit." },
- { nullptr, nullptr }
+ { "--help-variables [<file>]", "Print cmake-variables manual and exit." }
};
-static const char* cmDocumentationCPackGeneratorsHeader[][2] = {
- { nullptr, "The following generators are available on this platform:" },
- { nullptr, nullptr }
+const cmDocumentationEntry cmDocumentationCPackGeneratorsHeader = {
+ {},
+ "The following generators are available on this platform:"
};
-static const char* cmDocumentationCMakeGeneratorsHeader[][2] = {
- { nullptr,
- "The following generators are available on this platform (* marks "
- "default):" },
- { nullptr, nullptr }
+const cmDocumentationEntry cmDocumentationCMakeGeneratorsHeader = {
+ {},
+ "The following generators are available on this platform (* marks "
+ "default):"
};
+bool isOption(const char* arg)
+{
+ return ((arg[0] == '-') || (strcmp(arg, "/V") == 0) ||
+ (strcmp(arg, "/?") == 0));
+}
+} // anonymous namespace
+
cmDocumentation::cmDocumentation()
{
this->addCommonStandardDocSections();
@@ -148,14 +154,6 @@ bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os)
return result;
}
-#define GET_OPT_ARGUMENT(target) \
- do { \
- if ((i + 1 < argc) && !this->IsOption(argv[i + 1])) { \
- (target) = argv[i + 1]; \
- i = i + 1; \
- }; \
- } while (false)
-
void cmDocumentation::WarnFormFromFilename(
cmDocumentation::RequestedHelpItem& request, bool& result)
{
@@ -217,6 +215,14 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv,
return true;
}
+ auto get_opt_argument = [=](const int nextIdx, std::string& target) -> bool {
+ if ((nextIdx < argc) && !isOption(argv[nextIdx])) {
+ target = argv[nextIdx];
+ return true;
+ }
+ return false;
+ };
+
// Search for supported help options.
bool result = false;
@@ -230,7 +236,7 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv,
(strcmp(argv[i], "/?") == 0) || (strcmp(argv[i], "-usage") == 0) ||
(strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "-H") == 0)) {
help.HelpType = cmDocumentation::Help;
- GET_OPT_ARGUMENT(help.Argument);
+ i += int(get_opt_argument(i + 1, help.Argument));
help.Argument = cmSystemTools::LowerCase(help.Argument);
// special case for single command
if (!help.Argument.empty()) {
@@ -239,25 +245,25 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv,
} else if (strcmp(argv[i], "--help-properties") == 0) {
help.HelpType = cmDocumentation::OneManual;
help.Argument = "cmake-properties.7";
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Filename));
this->WarnFormFromFilename(help, result);
} else if (strcmp(argv[i], "--help-policies") == 0) {
help.HelpType = cmDocumentation::OneManual;
help.Argument = "cmake-policies.7";
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Filename));
this->WarnFormFromFilename(help, result);
} else if (strcmp(argv[i], "--help-variables") == 0) {
help.HelpType = cmDocumentation::OneManual;
help.Argument = "cmake-variables.7";
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Filename));
this->WarnFormFromFilename(help, result);
} else if (strcmp(argv[i], "--help-modules") == 0) {
help.HelpType = cmDocumentation::OneManual;
help.Argument = "cmake-modules.7";
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Filename));
this->WarnFormFromFilename(help, result);
} else if (strcmp(argv[i], "--help-custom-modules") == 0) {
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Filename));
cmSystemTools::Message(
"Warning: --help-custom-modules no longer supported");
if (help.Filename.empty()) {
@@ -271,83 +277,79 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv,
} else if (strcmp(argv[i], "--help-commands") == 0) {
help.HelpType = cmDocumentation::OneManual;
help.Argument = "cmake-commands.7";
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Filename));
this->WarnFormFromFilename(help, result);
} else if (strcmp(argv[i], "--help-compatcommands") == 0) {
- GET_OPT_ARGUMENT(help.Filename);
cmSystemTools::Message(
"Warning: --help-compatcommands no longer supported");
return true;
} else if (strcmp(argv[i], "--help-full") == 0) {
help.HelpType = cmDocumentation::Full;
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Filename));
this->WarnFormFromFilename(help, result);
} else if (strcmp(argv[i], "--help-html") == 0) {
- GET_OPT_ARGUMENT(help.Filename);
cmSystemTools::Message("Warning: --help-html no longer supported");
return true;
} else if (strcmp(argv[i], "--help-man") == 0) {
- GET_OPT_ARGUMENT(help.Filename);
cmSystemTools::Message("Warning: --help-man no longer supported");
return true;
} else if (strcmp(argv[i], "--help-command") == 0) {
help.HelpType = cmDocumentation::OneCommand;
- GET_OPT_ARGUMENT(help.Argument);
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Argument));
+ i += int(get_opt_argument(i + 1, help.Filename));
help.Argument = cmSystemTools::LowerCase(help.Argument);
this->WarnFormFromFilename(help, result);
} else if (strcmp(argv[i], "--help-module") == 0) {
help.HelpType = cmDocumentation::OneModule;
- GET_OPT_ARGUMENT(help.Argument);
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Argument));
+ i += int(get_opt_argument(i + 1, help.Filename));
this->WarnFormFromFilename(help, result);
} else if (strcmp(argv[i], "--help-property") == 0) {
help.HelpType = cmDocumentation::OneProperty;
- GET_OPT_ARGUMENT(help.Argument);
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Argument));
+ i += int(get_opt_argument(i + 1, help.Filename));
this->WarnFormFromFilename(help, result);
} else if (strcmp(argv[i], "--help-policy") == 0) {
help.HelpType = cmDocumentation::OnePolicy;
- GET_OPT_ARGUMENT(help.Argument);
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Argument));
+ i += int(get_opt_argument(i + 1, help.Filename));
this->WarnFormFromFilename(help, result);
} else if (strcmp(argv[i], "--help-variable") == 0) {
help.HelpType = cmDocumentation::OneVariable;
- GET_OPT_ARGUMENT(help.Argument);
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Argument));
+ i += int(get_opt_argument(i + 1, help.Filename));
this->WarnFormFromFilename(help, result);
} else if (strcmp(argv[i], "--help-manual") == 0) {
help.HelpType = cmDocumentation::OneManual;
- GET_OPT_ARGUMENT(help.Argument);
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Argument));
+ i += int(get_opt_argument(i + 1, help.Filename));
this->WarnFormFromFilename(help, result);
} else if (strcmp(argv[i], "--help-command-list") == 0) {
help.HelpType = cmDocumentation::ListCommands;
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Filename));
} else if (strcmp(argv[i], "--help-module-list") == 0) {
help.HelpType = cmDocumentation::ListModules;
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Filename));
} else if (strcmp(argv[i], "--help-property-list") == 0) {
help.HelpType = cmDocumentation::ListProperties;
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Filename));
} else if (strcmp(argv[i], "--help-variable-list") == 0) {
help.HelpType = cmDocumentation::ListVariables;
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Filename));
} else if (strcmp(argv[i], "--help-policy-list") == 0) {
help.HelpType = cmDocumentation::ListPolicies;
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Filename));
} else if (strcmp(argv[i], "--help-manual-list") == 0) {
help.HelpType = cmDocumentation::ListManuals;
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Filename));
} else if (strcmp(argv[i], "--copyright") == 0) {
- GET_OPT_ARGUMENT(help.Filename);
cmSystemTools::Message("Warning: --copyright no longer supported");
return true;
} else if ((strcmp(argv[i], "--version") == 0) ||
(strcmp(argv[i], "-version") == 0) ||
(strcmp(argv[i], "/V") == 0)) {
help.HelpType = cmDocumentation::Version;
- GET_OPT_ARGUMENT(help.Filename);
+ i += int(get_opt_argument(i + 1, help.Filename));
}
if (help.HelpType != None) {
// This is a help option. See if there is a file name given.
@@ -369,56 +371,12 @@ void cmDocumentation::SetSection(const char* name,
this->SectionAtName(name) = std::move(section);
}
-void cmDocumentation::SetSection(const char* name,
- std::vector<cmDocumentationEntry>& docs)
-{
- cmDocumentationSection sec{ name };
- sec.Append(docs);
- this->SetSection(name, std::move(sec));
-}
-
-void cmDocumentation::SetSection(const char* name, const char* docs[][2])
-{
- cmDocumentationSection sec{ name };
- sec.Append(docs);
- this->SetSection(name, std::move(sec));
-}
-
-void cmDocumentation::SetSections(
- std::map<std::string, cmDocumentationSection> sections)
-{
- for (auto& s : sections) {
- this->SetSection(s.first.c_str(), std::move(s.second));
- }
-}
cmDocumentationSection& cmDocumentation::SectionAtName(const char* name)
{
return this->AllSections.emplace(name, cmDocumentationSection{ name })
.first->second;
}
-void cmDocumentation::PrependSection(const char* name, const char* docs[][2])
-{
- this->SectionAtName(name).Prepend(docs);
-}
-
-void cmDocumentation::PrependSection(const char* name,
- std::vector<cmDocumentationEntry>& docs)
-{
- this->SectionAtName(name).Prepend(docs);
-}
-
-void cmDocumentation::AppendSection(const char* name, const char* docs[][2])
-{
- this->SectionAtName(name).Append(docs);
-}
-
-void cmDocumentation::AppendSection(const char* name,
- std::vector<cmDocumentationEntry>& docs)
-{
- this->SectionAtName(name).Append(docs);
-}
-
void cmDocumentation::AppendSection(const char* name,
cmDocumentationEntry& docs)
{
@@ -465,7 +423,7 @@ void cmDocumentation::PrintNames(std::ostream& os, std::string const& pattern)
}
std::sort(names.begin(), names.end());
for (std::string const& n : names) {
- os << n << "\n";
+ os << n << '\n';
}
}
@@ -501,7 +459,7 @@ bool cmDocumentation::PrintHelpOneManual(std::ostream& os)
// Argument was not a manual. Complain.
os << "Argument \"" << this->CurrentArgument
<< "\" to --help-manual is not an available manual. "
- << "Use --help-manual-list to see all available manuals.\n";
+ "Use --help-manual-list to see all available manuals.\n";
return false;
}
@@ -520,7 +478,7 @@ bool cmDocumentation::PrintHelpOneCommand(std::ostream& os)
// Argument was not a command. Complain.
os << "Argument \"" << this->CurrentArgument
<< "\" to --help-command is not a CMake command. "
- << "Use --help-command-list to see all commands.\n";
+ "Use --help-command-list to see all commands.\n";
return false;
}
@@ -553,7 +511,7 @@ bool cmDocumentation::PrintHelpListModules(std::ostream& os)
}
std::sort(modules.begin(), modules.end());
for (std::string const& m : modules) {
- os << m << "\n";
+ os << m << '\n';
}
return true;
}
@@ -567,7 +525,7 @@ bool cmDocumentation::PrintHelpOneProperty(std::ostream& os)
// Argument was not a property. Complain.
os << "Argument \"" << this->CurrentArgument
<< "\" to --help-property is not a CMake property. "
- << "Use --help-property-list to see all properties.\n";
+ "Use --help-property-list to see all properties.\n";
return false;
}
@@ -601,7 +559,6 @@ bool cmDocumentation::PrintHelpListGenerators(std::ostream& os)
{
const auto si = this->AllSections.find("Generators");
if (si != this->AllSections.end()) {
- this->Formatter.SetIndent(" ");
this->Formatter.PrintSection(os, si->second);
}
return true;
@@ -616,7 +573,7 @@ bool cmDocumentation::PrintHelpOneVariable(std::ostream& os)
// Argument was not a variable. Complain.
os << "Argument \"" << this->CurrentArgument
<< "\" to --help-variable is not a defined variable. "
- << "Use --help-variable-list to see all defined variables.\n";
+ "Use --help-variable-list to see all defined variables.\n";
return false;
}
@@ -662,12 +619,6 @@ const char* cmDocumentation::GetNameString() const
return "CMake";
}
-bool cmDocumentation::IsOption(const char* arg) const
-{
- return ((arg[0] == '-') || (strcmp(arg, "/V") == 0) ||
- (strcmp(arg, "/?") == 0));
-}
-
bool cmDocumentation::PrintOldCustomModules(std::ostream& os)
{
// CheckOptions abuses the Argument field to give us the file name.
@@ -691,7 +642,7 @@ bool cmDocumentation::PrintOldCustomModules(std::ostream& os)
} else if ((ext.length() == 2) && (ext[1] >= '1') && (ext[1] <= '9')) {
/* clang-format off */
os <<
- ".TH " << name << " " << ext[1] << " \"" <<
+ ".TH " << name << ' ' << ext[1] << " \"" <<
cmSystemTools::GetCurrentDateTime("%B %d, %Y") <<
"\" \"cmake " << cmVersion::GetCMakeVersion() << "\"\n"
".SH NAME\n"
@@ -704,7 +655,7 @@ bool cmDocumentation::PrintOldCustomModules(std::ostream& os)
;
/* clang-format on */
} else {
- os << name << "\n\n" << summary << "\n" << detail;
+ os << name << "\n\n" << summary << '\n' << detail;
}
return true;
}
diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h
index 313be32..6930986 100644
--- a/Source/cmDocumentation.h
+++ b/Source/cmDocumentation.h
@@ -7,6 +7,7 @@
#include <iosfwd>
#include <map>
#include <string>
+#include <utility>
#include <vector>
#include "cmDocumentationFormatter.h"
@@ -15,9 +16,33 @@
struct cmDocumentationEntry;
/** Class to generate documentation. */
-class cmDocumentation : public cmDocumentationEnums
+class cmDocumentation
{
public:
+ /** Types of help provided. */
+ enum Type
+ {
+ None,
+ Version,
+ Usage,
+ Help,
+ Full,
+ ListManuals,
+ ListCommands,
+ ListModules,
+ ListProperties,
+ ListVariables,
+ ListPolicies,
+ ListGenerators,
+ OneManual,
+ OneCommand,
+ OneModule,
+ OneProperty,
+ OneVariable,
+ OnePolicy,
+ OldCustomModules
+ };
+
cmDocumentation();
/**
@@ -50,19 +75,26 @@ public:
/** Set a section of the documentation. Typical sections include Name,
Usage, Description, Options */
void SetSection(const char* sectionName, cmDocumentationSection section);
- void SetSection(const char* sectionName,
- std::vector<cmDocumentationEntry>& docs);
- void SetSection(const char* sectionName, const char* docs[][2]);
- void SetSections(std::map<std::string, cmDocumentationSection> sections);
+ template <typename Iterable>
+ void SetSection(const char* sectionName, const Iterable& docs)
+ {
+ cmDocumentationSection sec{ sectionName };
+ sec.Append(docs);
+ this->SetSection(sectionName, std::move(sec));
+ }
/** Add the documentation to the beginning/end of the section */
- void PrependSection(const char* sectionName, const char* docs[][2]);
- void PrependSection(const char* sectionName,
- std::vector<cmDocumentationEntry>& docs);
+ template <typename Iterable>
+ void PrependSection(const char* sectionName, const Iterable& docs)
+ {
+ this->SectionAtName(sectionName).Prepend(docs);
+ }
void PrependSection(const char* sectionName, cmDocumentationEntry& docs);
- void AppendSection(const char* sectionName, const char* docs[][2]);
- void AppendSection(const char* sectionName,
- std::vector<cmDocumentationEntry>& docs);
+ template <typename Iterable>
+ void AppendSection(const char* sectionName, const Iterable& docs)
+ {
+ this->SectionAtName(sectionName).Append(docs);
+ }
void AppendSection(const char* sectionName, cmDocumentationEntry& docs);
/** Add common (to all tools) documentation section(s) */
@@ -102,7 +134,6 @@ private:
bool PrintOldCustomModules(std::ostream& os);
const char* GetNameString() const;
- bool IsOption(const char* arg) const;
bool ShowGenerators;
@@ -114,7 +145,7 @@ private:
struct RequestedHelpItem
{
- cmDocumentationEnums::Type HelpType = None;
+ Type HelpType = None;
std::string Filename;
std::string Argument;
};
diff --git a/Source/cmDocumentationEntry.h b/Source/cmDocumentationEntry.h
index 89a2899..d971836 100644
--- a/Source/cmDocumentationEntry.h
+++ b/Source/cmDocumentationEntry.h
@@ -9,26 +9,15 @@
/** Standard documentation entry for cmDocumentation's formatting. */
struct cmDocumentationEntry
{
- std::string Name;
- std::string Brief;
- char CustomNamePrefix = ' ';
- cmDocumentationEntry() = default;
- cmDocumentationEntry(const char* doc[2])
- {
- if (doc[0]) {
- this->Name = doc[0];
- }
- if (doc[1]) {
- this->Brief = doc[1];
- }
- }
- cmDocumentationEntry(const char* n, const char* b)
+#if __cplusplus <= 201103L
+ cmDocumentationEntry(const std::string& name, const std::string& brief)
+ : Name{ name }
+ , Brief{ brief }
{
- if (n) {
- this->Name = n;
- }
- if (b) {
- this->Brief = b;
- }
}
+#endif
+
+ std::string Name = {};
+ std::string Brief = {};
+ char CustomNamePrefix = ' ';
};
diff --git a/Source/cmDocumentationFormatter.cxx b/Source/cmDocumentationFormatter.cxx
index 732637e..70ba1fc 100644
--- a/Source/cmDocumentationFormatter.cxx
+++ b/Source/cmDocumentationFormatter.cxx
@@ -2,7 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmDocumentationFormatter.h"
-#include <cstring>
+#include <algorithm>
+#include <cassert>
#include <iomanip>
#include <ostream>
#include <string>
@@ -11,178 +12,207 @@
#include "cmDocumentationEntry.h"
#include "cmDocumentationSection.h"
-cmDocumentationFormatter::cmDocumentationFormatter() = default;
-
-cmDocumentationFormatter::~cmDocumentationFormatter() = default;
+namespace {
+const char* skipSpaces(const char* ptr)
+{
+ assert(ptr);
+ for (; *ptr == ' '; ++ptr) {
+ ;
+ }
+ return ptr;
+}
+const char* skipToSpace(const char* ptr)
+{
+ assert(ptr);
+ for (; *ptr && (*ptr != '\n') && (*ptr != ' '); ++ptr) {
+ ;
+ }
+ return ptr;
+}
+}
void cmDocumentationFormatter::PrintFormatted(std::ostream& os,
- const char* text)
+ std::string const& text) const
{
- if (!text) {
+ if (text.empty()) {
return;
}
- const char* ptr = text;
- while (*ptr) {
- // Any ptrs starting in a space are treated as preformatted text.
- std::string preformatted;
- while (*ptr == ' ') {
- for (char ch = *ptr; ch && ch != '\n'; ++ptr, ch = *ptr) {
- preformatted.append(1, ch);
- }
- if (*ptr) {
- ++ptr;
- preformatted.append(1, '\n');
- }
- }
- if (!preformatted.empty()) {
- this->PrintPreformatted(os, preformatted.c_str());
+
+ struct Buffer
+ {
+ // clang-format off
+ using PrinterFn = void (cmDocumentationFormatter::*)(
+ std::ostream&, std::string const&
+ ) const;
+ // clang-format on
+ std::string collected;
+ const PrinterFn printer;
+ };
+ // const auto NORMAL_IDX = 0u;
+ const auto PREFORMATTED_IDX = 1u;
+ const auto HANDLERS_SIZE = 2u;
+ Buffer buffers[HANDLERS_SIZE] = {
+ { {}, &cmDocumentationFormatter::PrintParagraph },
+ { {}, &cmDocumentationFormatter::PrintPreformatted }
+ };
+
+ const auto padding = std::string(this->TextIndent, ' ');
+
+ for (std::size_t pos = 0u, eol = 0u; pos < text.size(); pos = eol) {
+ const auto current_idx = std::size_t(text[pos] == ' ');
+ // size_t(!bool(current_idx))
+ const auto other_idx = current_idx ^ 1u;
+
+ // Flush the other buffer if anything has been collected
+ if (!buffers[other_idx].collected.empty()) {
+ // NOTE Whatever the other index is, the current buffered
+ // string expected to be empty.
+ assert(buffers[current_idx].collected.empty());
+
+ (this->*buffers[other_idx].printer)(os, buffers[other_idx].collected);
+ buffers[other_idx].collected.clear();
}
- // Other ptrs are treated as paragraphs.
- std::string paragraph;
- for (char ch = *ptr; ch && ch != '\n'; ++ptr, ch = *ptr) {
- paragraph.append(1, ch);
+ // ATTENTION The previous implementation had called `PrintParagraph()`
+ // **for every processed (char by char) input line**.
+ // The method unconditionally append the `\n' character after the
+ // printed text. To keep the backward-compatible behavior it's needed to
+ // add the '\n' character to the previously collected line...
+ if (!buffers[current_idx].collected.empty() &&
+ current_idx != PREFORMATTED_IDX) {
+ buffers[current_idx].collected += '\n';
}
- if (*ptr) {
- ++ptr;
- paragraph.append(1, '\n');
+
+ // Lookup EOL
+ eol = text.find('\n', pos);
+ if (current_idx == PREFORMATTED_IDX) {
+ buffers[current_idx].collected.append(padding);
}
- if (!paragraph.empty()) {
- this->PrintParagraph(os, paragraph.c_str());
+ buffers[current_idx].collected.append(
+ text, pos, eol == std::string::npos ? eol : ++eol - pos);
+ }
+
+ for (auto& buf : buffers) {
+ if (!buf.collected.empty()) {
+ (this->*buf.printer)(os, buf.collected);
}
}
}
void cmDocumentationFormatter::PrintPreformatted(std::ostream& os,
- const char* text)
+ std::string const& text) const
{
- bool newline = true;
- for (const char* ptr = text; *ptr; ++ptr) {
- if (newline && *ptr != '\n') {
- os << this->TextIndent;
- newline = false;
- }
- os << *ptr;
- if (*ptr == '\n') {
- newline = true;
- }
- }
- os << "\n";
+ os << text << '\n';
}
void cmDocumentationFormatter::PrintParagraph(std::ostream& os,
- const char* text)
+ std::string const& text) const
{
- os << this->TextIndent;
+ if (this->TextIndent) {
+ os << std::string(this->TextIndent, ' ');
+ }
this->PrintColumn(os, text);
- os << "\n";
-}
-
-void cmDocumentationFormatter::SetIndent(const char* indent)
-{
- this->TextIndent = indent;
+ os << '\n';
}
-void cmDocumentationFormatter::PrintColumn(std::ostream& os, const char* text)
+void cmDocumentationFormatter::PrintColumn(std::ostream& os,
+ std::string const& text) const
{
// Print text arranged in an indented column of fixed width.
- const char* l = text;
- long column = 0;
bool newSentence = false;
bool firstLine = true;
- int width = this->TextWidth - static_cast<int>(strlen(this->TextIndent));
- // Loop until the end of the text.
- while (*l) {
- // Parse the next word.
- const char* r = l;
- while (*r && (*r != '\n') && (*r != ' ')) {
- ++r;
- }
+ assert(this->TextIndent < this->TextWidth);
+ const std::ptrdiff_t width = this->TextWidth - this->TextIndent;
+ std::ptrdiff_t column = 0;
+ // Loop until the end of the text.
+ for (const char *l = text.c_str(), *r = skipToSpace(text.c_str()); *l;
+ l = skipSpaces(r), r = skipToSpace(l)) {
// Does it fit on this line?
- if (r - l < (width - column - (newSentence ? 1 : 0))) {
+ if (r - l < width - column - std::ptrdiff_t(newSentence)) {
// Word fits on this line.
if (r > l) {
if (column) {
// Not first word on line. Separate from the previous word
// by a space, or two if this is a new sentence.
- if (newSentence) {
- os << " ";
- column += 2;
- } else {
- os << " ";
- column += 1;
- }
- } else {
+ os << &(" "[std::size_t(!newSentence)]);
+ column += 1u + std::ptrdiff_t(newSentence);
+ } else if (!firstLine && this->TextIndent) {
// First word on line. Print indentation unless this is the
// first line.
- os << (firstLine ? "" : this->TextIndent);
+ os << std::string(this->TextIndent, ' ');
}
// Print the word.
- os.write(l, static_cast<long>(r - l));
+ os.write(l, r - l);
newSentence = (*(r - 1) == '.');
}
if (*r == '\n') {
// Text provided a newline. Start a new line.
- os << "\n";
+ os << '\n';
++r;
column = 0;
firstLine = false;
} else {
// No provided newline. Continue this line.
- column += static_cast<long>(r - l);
+ column += r - l;
}
} else {
// Word does not fit on this line. Start a new line.
- os << "\n";
+ os << '\n';
firstLine = false;
if (r > l) {
- os << this->TextIndent;
- os.write(l, static_cast<long>(r - l));
- column = static_cast<long>(r - l);
+ os << std::string(this->TextIndent, ' ');
+ os.write(l, r - l);
+ column = r - l;
newSentence = (*(r - 1) == '.');
} else {
column = 0;
}
}
-
// Move to beginning of next word. Skip over whitespace.
- l = r;
- while (*l == ' ') {
- ++l;
- }
}
}
void cmDocumentationFormatter::PrintSection(
std::ostream& os, cmDocumentationSection const& section)
{
- os << section.GetName() << "\n";
+ const std::size_t PREFIX_SIZE =
+ sizeof(cmDocumentationEntry::CustomNamePrefix) + 1u;
+ // length of the "= " literal (see below)
+ const std::size_t SUFFIX_SIZE = 2u;
+ // legacy magic number ;-)
+ const std::size_t NAME_SIZE = 29u;
+
+ const std::size_t PADDING_SIZE = PREFIX_SIZE + SUFFIX_SIZE;
+ const std::size_t TITLE_SIZE = NAME_SIZE + PADDING_SIZE;
+
+ const auto savedIndent = this->TextIndent;
- const std::vector<cmDocumentationEntry>& entries = section.GetEntries();
- for (cmDocumentationEntry const& entry : entries) {
+ os << section.GetName() << '\n';
+
+ for (cmDocumentationEntry const& entry : section.GetEntries()) {
if (!entry.Name.empty()) {
- os << std::setw(2) << std::left << entry.CustomNamePrefix << entry.Name;
- this->TextIndent = " ";
- int align = static_cast<int>(strlen(this->TextIndent)) - 4;
- for (int i = static_cast<int>(entry.Name.size()); i < align; ++i) {
- os << " ";
- }
- if (entry.Name.size() > strlen(this->TextIndent) - 4) {
- os << "\n";
- os.write(this->TextIndent, strlen(this->TextIndent) - 2);
+ this->TextIndent = TITLE_SIZE;
+ os << std::setw(PREFIX_SIZE) << std::left << entry.CustomNamePrefix
+ << std::setw(int(std::max(NAME_SIZE, entry.Name.size())))
+ << entry.Name;
+ if (entry.Name.size() > NAME_SIZE) {
+ os << '\n' << std::setw(int(this->TextIndent - PREFIX_SIZE)) << ' ';
}
os << "= ";
- this->PrintColumn(os, entry.Brief.c_str());
- os << "\n";
+ this->PrintColumn(os, entry.Brief);
+ os << '\n';
} else {
- os << "\n";
- this->TextIndent = "";
- this->PrintFormatted(os, entry.Brief.c_str());
+ os << '\n';
+ this->TextIndent = 0u;
+ this->PrintFormatted(os, entry.Brief);
}
}
- os << "\n";
+
+ os << '\n';
+
+ this->TextIndent = savedIndent;
}
diff --git a/Source/cmDocumentationFormatter.h b/Source/cmDocumentationFormatter.h
index cb3038a..e269f6a 100644
--- a/Source/cmDocumentationFormatter.h
+++ b/Source/cmDocumentationFormatter.h
@@ -5,40 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
-
-/** This is just a helper class to make it build with MSVC 6.0.
-Actually the enums and internal classes could directly go into
-cmDocumentation, but then MSVC6 complains in RequestedHelpItem that
-cmDocumentation is an undefined type and so it doesn't know the enums.
-Moving the enums to a class which is then already completely parsed helps
-against this. */
-class cmDocumentationEnums
-{
-public:
- /** Types of help provided. */
- enum Type
- {
- None,
- Version,
- Usage,
- Help,
- Full,
- ListManuals,
- ListCommands,
- ListModules,
- ListProperties,
- ListVariables,
- ListPolicies,
- ListGenerators,
- OneManual,
- OneCommand,
- OneModule,
- OneProperty,
- OneVariable,
- OnePolicy,
- OldCustomModules
- };
-};
+#include <string>
class cmDocumentationSection;
@@ -46,18 +13,15 @@ class cmDocumentationSection;
class cmDocumentationFormatter
{
public:
- cmDocumentationFormatter();
- virtual ~cmDocumentationFormatter();
- void PrintFormatted(std::ostream& os, const char* text);
-
- virtual void PrintSection(std::ostream& os,
- cmDocumentationSection const& section);
- virtual void PrintPreformatted(std::ostream& os, const char* text);
- virtual void PrintParagraph(std::ostream& os, const char* text);
- void PrintColumn(std::ostream& os, const char* text);
- void SetIndent(const char* indent);
+ void SetIndent(std::size_t indent) { this->TextIndent = indent; }
+ void PrintFormatted(std::ostream& os, std::string const& text) const;
+ void PrintSection(std::ostream& os, cmDocumentationSection const& section);
private:
- int TextWidth = 77;
- const char* TextIndent = "";
+ void PrintPreformatted(std::ostream& os, std::string const&) const;
+ void PrintParagraph(std::ostream& os, std::string const&) const;
+ void PrintColumn(std::ostream& os, std::string const&) const;
+
+ std::size_t TextWidth = 77u;
+ std::size_t TextIndent = 0u;
};
diff --git a/Source/cmDocumentationSection.cxx b/Source/cmDocumentationSection.cxx
deleted file mode 100644
index 439da1b..0000000
--- a/Source/cmDocumentationSection.cxx
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmDocumentationSection.h"
-
-void cmDocumentationSection::Append(const char* data[][2])
-{
- int i = 0;
- while (data[i][1]) {
- this->Entries.emplace_back(data[i][0], data[i][1]);
- data += 1;
- }
-}
-
-void cmDocumentationSection::Prepend(const char* data[][2])
-{
- std::vector<cmDocumentationEntry> tmp;
- int i = 0;
- while (data[i][1]) {
- tmp.emplace_back(data[i][0], data[i][1]);
- data += 1;
- }
- this->Entries.insert(this->Entries.begin(), tmp.begin(), tmp.end());
-}
-
-void cmDocumentationSection::Append(const char* n, const char* b)
-{
- this->Entries.emplace_back(n, b);
-}
diff --git a/Source/cmDocumentationSection.h b/Source/cmDocumentationSection.h
index 276e520..b5e24fe 100644
--- a/Source/cmDocumentationSection.h
+++ b/Source/cmDocumentationSection.h
@@ -4,11 +4,10 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <iterator>
#include <string>
#include <vector>
-#include <cmext/algorithm>
-
#include "cmDocumentationEntry.h"
// Low-level interface for custom documents:
@@ -45,21 +44,20 @@ public:
{
this->Entries.push_back(entry);
}
- void Append(const std::vector<cmDocumentationEntry>& entries)
+
+ template <typename Iterable>
+ void Append(const Iterable& entries)
{
- cm::append(this->Entries, entries);
+ this->Entries.insert(std::end(this->Entries), std::begin(entries),
+ std::end(entries));
}
- /** Append an entry to this section using NULL terminated chars */
- void Append(const char* [][2]);
- void Append(const char* n, const char* b);
-
/** prepend some documentation to this section */
- void Prepend(const char* [][2]);
- void Prepend(const std::vector<cmDocumentationEntry>& entries)
+ template <typename Iterable>
+ void Prepend(const Iterable& entries)
{
- this->Entries.insert(this->Entries.begin(), entries.begin(),
- entries.end());
+ this->Entries.insert(std::begin(this->Entries), std::begin(entries),
+ std::end(entries));
}
private:
diff --git a/Source/cmDyndepCollation.cxx b/Source/cmDyndepCollation.cxx
new file mode 100644
index 0000000..2827659
--- /dev/null
+++ b/Source/cmDyndepCollation.cxx
@@ -0,0 +1,652 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmDyndepCollation.h"
+
+#include <algorithm>
+#include <map>
+#include <ostream>
+#include <set>
+#include <utility>
+#include <vector>
+
+#include <cm/memory>
+#include <cm/string_view>
+#include <cmext/string_view>
+
+#include <cm3p/json/value.h>
+
+#include "cmExportBuildFileGenerator.h"
+#include "cmExportSet.h"
+#include "cmFileSet.h"
+#include "cmGeneratedFileStream.h"
+#include "cmGeneratorExpression.h" // IWYU pragma: keep
+#include "cmGeneratorTarget.h"
+#include "cmGlobalGenerator.h"
+#include "cmInstallCxxModuleBmiGenerator.h"
+#include "cmInstallExportGenerator.h"
+#include "cmInstallFileSetGenerator.h"
+#include "cmInstallGenerator.h"
+#include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmOutputConverter.h"
+#include "cmScanDepFormat.h"
+#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+#include "cmTarget.h"
+#include "cmTargetExport.h"
+
+namespace {
+
+Json::Value CollationInformationCxxModules(
+ cmGeneratorTarget const* gt, std::string const& config,
+ cmDyndepGeneratorCallbacks const& cb)
+{
+ cmTarget const* tgt = gt->Target;
+ auto all_file_sets = tgt->GetAllFileSetNames();
+ Json::Value tdi_cxx_module_info = Json::objectValue;
+ for (auto const& file_set_name : all_file_sets) {
+ auto const* file_set = tgt->GetFileSet(file_set_name);
+ if (!file_set) {
+ gt->Makefile->IssueMessage(MessageType::INTERNAL_ERROR,
+ cmStrCat("Target \"", tgt->GetName(),
+ "\" is tracked to have file set \"",
+ file_set_name,
+ "\", but it was not found."));
+ continue;
+ }
+ auto fs_type = file_set->GetType();
+ // We only care about C++ module sources here.
+ if (fs_type != "CXX_MODULES"_s) {
+ continue;
+ }
+
+ auto fileEntries = file_set->CompileFileEntries();
+ auto directoryEntries = file_set->CompileDirectoryEntries();
+
+ auto directories = file_set->EvaluateDirectoryEntries(
+ directoryEntries, gt->LocalGenerator, config, gt);
+ std::map<std::string, std::vector<std::string>> files_per_dirs;
+ for (auto const& entry : fileEntries) {
+ file_set->EvaluateFileEntry(directories, files_per_dirs, entry,
+ gt->LocalGenerator, config, gt);
+ }
+
+ std::map<std::string, cmSourceFile const*> sf_map;
+ {
+ std::vector<cmSourceFile const*> objectSources;
+ gt->GetObjectSources(objectSources, config);
+ for (auto const* sf : objectSources) {
+ auto full_path = sf->GetFullPath();
+ if (full_path.empty()) {
+ gt->Makefile->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("Target \"", tgt->GetName(),
+ "\" has a full path-less source file."));
+ continue;
+ }
+ sf_map[full_path] = sf;
+ }
+ }
+
+ Json::Value fs_dest = Json::nullValue;
+ for (auto const& ig : gt->Makefile->GetInstallGenerators()) {
+ if (auto const* fsg =
+ dynamic_cast<cmInstallFileSetGenerator const*>(ig.get())) {
+ if (fsg->GetTarget() == gt && fsg->GetFileSet() == file_set) {
+ fs_dest = fsg->GetDestination(config);
+ continue;
+ }
+ }
+ }
+
+ for (auto const& files_per_dir : files_per_dirs) {
+ for (auto const& file : files_per_dir.second) {
+ auto lookup = sf_map.find(file);
+ if (lookup == sf_map.end()) {
+ gt->Makefile->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("Target \"", tgt->GetName(), "\" has source file \"",
+ file,
+ R"(" which is not in any of its "FILE_SET BASE_DIRS".)"));
+ continue;
+ }
+
+ auto const* sf = lookup->second;
+
+ if (!sf) {
+ gt->Makefile->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("Target \"", tgt->GetName(), "\" has source file \"",
+ file, "\" which has not been tracked properly."));
+ continue;
+ }
+
+ auto obj_path = cb.ObjectFilePath(sf, config);
+ Json::Value& tdi_module_info = tdi_cxx_module_info[obj_path] =
+ Json::objectValue;
+
+ tdi_module_info["source"] = file;
+ tdi_module_info["relative-directory"] = files_per_dir.first;
+ tdi_module_info["name"] = file_set->GetName();
+ tdi_module_info["type"] = file_set->GetType();
+ tdi_module_info["visibility"] =
+ std::string(cmFileSetVisibilityToName(file_set->GetVisibility()));
+ tdi_module_info["destination"] = fs_dest;
+ }
+ }
+ }
+
+ return tdi_cxx_module_info;
+}
+
+Json::Value CollationInformationBmiInstallation(cmGeneratorTarget const* gt,
+ std::string const& config)
+{
+ cmInstallCxxModuleBmiGenerator const* bmi_gen = nullptr;
+ for (auto const& ig : gt->Makefile->GetInstallGenerators()) {
+ if (auto const* bmig =
+ dynamic_cast<cmInstallCxxModuleBmiGenerator const*>(ig.get())) {
+ if (bmig->GetTarget() == gt) {
+ bmi_gen = bmig;
+ continue;
+ }
+ }
+ }
+ if (bmi_gen) {
+ Json::Value tdi_bmi_info = Json::objectValue;
+
+ tdi_bmi_info["permissions"] = bmi_gen->GetFilePermissions();
+ tdi_bmi_info["destination"] = bmi_gen->GetDestination(config);
+ const char* msg_level = "";
+ switch (bmi_gen->GetMessageLevel()) {
+ case cmInstallGenerator::MessageDefault:
+ break;
+ case cmInstallGenerator::MessageAlways:
+ msg_level = "MESSAGE_ALWAYS";
+ break;
+ case cmInstallGenerator::MessageLazy:
+ msg_level = "MESSAGE_LAZY";
+ break;
+ case cmInstallGenerator::MessageNever:
+ msg_level = "MESSAGE_NEVER";
+ break;
+ }
+ tdi_bmi_info["message-level"] = msg_level;
+ tdi_bmi_info["script-location"] = bmi_gen->GetScriptLocation(config);
+
+ return tdi_bmi_info;
+ }
+ return Json::nullValue;
+}
+
+Json::Value CollationInformationExports(cmGeneratorTarget const* gt)
+{
+ Json::Value tdi_exports = Json::arrayValue;
+ std::string export_name = gt->GetExportName();
+
+ auto const& all_install_exports = gt->GetGlobalGenerator()->GetExportSets();
+ for (auto const& exp : all_install_exports) {
+ // Ignore exports sets which are not for this target.
+ auto const& targets = exp.second.GetTargetExports();
+ auto tgt_export =
+ std::find_if(targets.begin(), targets.end(),
+ [gt](std::unique_ptr<cmTargetExport> const& te) {
+ return te->Target == gt;
+ });
+ if (tgt_export == targets.end()) {
+ continue;
+ }
+
+ auto const* installs = exp.second.GetInstallations();
+ for (auto const* install : *installs) {
+ Json::Value tdi_export_info = Json::objectValue;
+
+ auto const& ns = install->GetNamespace();
+ auto const& dest = install->GetDestination();
+ auto const& cxxm_dir = install->GetCxxModuleDirectory();
+ auto const& export_prefix = install->GetTempDir();
+
+ tdi_export_info["namespace"] = ns;
+ tdi_export_info["export-name"] = export_name;
+ tdi_export_info["destination"] = dest;
+ tdi_export_info["cxx-module-info-dir"] = cxxm_dir;
+ tdi_export_info["export-prefix"] = export_prefix;
+ tdi_export_info["install"] = true;
+
+ tdi_exports.append(tdi_export_info);
+ }
+ }
+
+ auto const& all_build_exports = gt->Makefile->GetExportBuildFileGenerators();
+ for (auto const& exp : all_build_exports) {
+ std::vector<std::string> targets;
+ exp->GetTargets(targets);
+
+ // Ignore exports sets which are not for this target.
+ auto const& name = gt->GetName();
+ bool has_current_target =
+ std::any_of(targets.begin(), targets.end(),
+ [name](std::string const& tname) { return tname == name; });
+ if (!has_current_target) {
+ continue;
+ }
+
+ Json::Value tdi_export_info = Json::objectValue;
+
+ auto const& ns = exp->GetNamespace();
+ auto const& main_fn = exp->GetMainExportFileName();
+ auto const& cxxm_dir = exp->GetCxxModuleDirectory();
+ auto dest = cmsys::SystemTools::GetParentDirectory(main_fn);
+ auto const& export_prefix =
+ cmSystemTools::GetFilenamePath(exp->GetMainExportFileName());
+
+ tdi_export_info["namespace"] = ns;
+ tdi_export_info["export-name"] = export_name;
+ tdi_export_info["destination"] = dest;
+ tdi_export_info["cxx-module-info-dir"] = cxxm_dir;
+ tdi_export_info["export-prefix"] = export_prefix;
+ tdi_export_info["install"] = false;
+
+ tdi_exports.append(tdi_export_info);
+ }
+
+ return tdi_exports;
+}
+}
+
+void cmDyndepCollation::AddCollationInformation(
+ Json::Value& tdi, cmGeneratorTarget const* gt, std::string const& config,
+ cmDyndepGeneratorCallbacks const& cb)
+{
+ tdi["cxx-modules"] = CollationInformationCxxModules(gt, config, cb);
+ tdi["bmi-installation"] = CollationInformationBmiInstallation(gt, config);
+ tdi["exports"] = CollationInformationExports(gt);
+ tdi["config"] = config;
+}
+
+struct CxxModuleFileSet
+{
+ std::string Name;
+ std::string RelativeDirectory;
+ std::string SourcePath;
+ std::string Type;
+ cmFileSetVisibility Visibility;
+ cm::optional<std::string> Destination;
+};
+
+struct CxxModuleBmiInstall
+{
+ std::string Component;
+ std::string Destination;
+ bool ExcludeFromAll;
+ bool Optional;
+ std::string Permissions;
+ std::string MessageLevel;
+ std::string ScriptLocation;
+};
+
+struct CxxModuleExport
+{
+ std::string Name;
+ std::string Destination;
+ std::string Prefix;
+ std::string CxxModuleInfoDir;
+ std::string Namespace;
+ bool Install;
+};
+
+struct cmCxxModuleExportInfo
+{
+ std::map<std::string, CxxModuleFileSet> ObjectToFileSet;
+ cm::optional<CxxModuleBmiInstall> BmiInstallation;
+ std::vector<CxxModuleExport> Exports;
+ std::string Config;
+};
+
+void cmCxxModuleExportInfoDeleter::operator()(cmCxxModuleExportInfo* ei) const
+{
+ delete ei;
+}
+
+std::unique_ptr<cmCxxModuleExportInfo, cmCxxModuleExportInfoDeleter>
+cmDyndepCollation::ParseExportInfo(Json::Value const& tdi)
+{
+ auto export_info =
+ std::unique_ptr<cmCxxModuleExportInfo, cmCxxModuleExportInfoDeleter>(
+ new cmCxxModuleExportInfo);
+
+ export_info->Config = tdi["config"].asString();
+ if (export_info->Config.empty()) {
+ export_info->Config = "noconfig";
+ }
+ Json::Value const& tdi_exports = tdi["exports"];
+ if (tdi_exports.isArray()) {
+ for (auto const& tdi_export : tdi_exports) {
+ CxxModuleExport exp;
+ exp.Install = tdi_export["install"].asBool();
+ exp.Name = tdi_export["export-name"].asString();
+ exp.Destination = tdi_export["destination"].asString();
+ exp.Prefix = tdi_export["export-prefix"].asString();
+ exp.CxxModuleInfoDir = tdi_export["cxx-module-info-dir"].asString();
+ exp.Namespace = tdi_export["namespace"].asString();
+
+ export_info->Exports.push_back(exp);
+ }
+ }
+ auto const& bmi_installation = tdi["bmi-installation"];
+ if (bmi_installation.isObject()) {
+ CxxModuleBmiInstall bmi_install;
+
+ bmi_install.Component = bmi_installation["component"].asString();
+ bmi_install.Destination = bmi_installation["destination"].asString();
+ bmi_install.ExcludeFromAll = bmi_installation["exclude-from-all"].asBool();
+ bmi_install.Optional = bmi_installation["optional"].asBool();
+ bmi_install.Permissions = bmi_installation["permissions"].asString();
+ bmi_install.MessageLevel = bmi_installation["message-level"].asString();
+ bmi_install.ScriptLocation =
+ bmi_installation["script-location"].asString();
+
+ export_info->BmiInstallation = bmi_install;
+ }
+ Json::Value const& tdi_cxx_modules = tdi["cxx-modules"];
+ if (tdi_cxx_modules.isObject()) {
+ for (auto i = tdi_cxx_modules.begin(); i != tdi_cxx_modules.end(); ++i) {
+ CxxModuleFileSet& fsi = export_info->ObjectToFileSet[i.key().asString()];
+ auto const& tdi_cxx_module_info = *i;
+ fsi.Name = tdi_cxx_module_info["name"].asString();
+ fsi.RelativeDirectory =
+ tdi_cxx_module_info["relative-directory"].asString();
+ fsi.SourcePath = tdi_cxx_module_info["source"].asString();
+ fsi.Type = tdi_cxx_module_info["type"].asString();
+ fsi.Visibility = cmFileSetVisibilityFromName(
+ tdi_cxx_module_info["visibility"].asString(), nullptr);
+ auto const& tdi_fs_dest = tdi_cxx_module_info["destination"];
+ if (tdi_fs_dest.isString()) {
+ fsi.Destination = tdi_fs_dest.asString();
+ }
+ }
+ }
+
+ return export_info;
+}
+
+bool cmDyndepCollation::WriteDyndepMetadata(
+ std::string const& lang, std::vector<cmScanDepInfo> const& objects,
+ cmCxxModuleExportInfo const& export_info,
+ cmDyndepMetadataCallbacks const& cb)
+{
+ // Only C++ supports any of the file-set or BMI installation considered
+ // below.
+ if (lang != "CXX"_s) {
+ return true;
+ }
+
+ bool result = true;
+
+ // Prepare the export information blocks.
+ std::string const config_upper =
+ cmSystemTools::UpperCase(export_info.Config);
+ std::vector<
+ std::pair<std::unique_ptr<cmGeneratedFileStream>, CxxModuleExport const*>>
+ exports;
+ for (auto const& exp : export_info.Exports) {
+ std::unique_ptr<cmGeneratedFileStream> properties;
+
+ std::string const export_dir =
+ cmStrCat(exp.Prefix, '/', exp.CxxModuleInfoDir, '/');
+ std::string const property_file_path = cmStrCat(
+ export_dir, "target-", exp.Name, '-', export_info.Config, ".cmake");
+ properties = cm::make_unique<cmGeneratedFileStream>(property_file_path);
+
+ // Set up the preamble.
+ *properties << "set_property(TARGET \"" << exp.Namespace << exp.Name
+ << "\"\n"
+ << " PROPERTY IMPORTED_CXX_MODULES_" << config_upper << '\n';
+
+ exports.emplace_back(std::move(properties), &exp);
+ }
+
+ std::unique_ptr<cmGeneratedFileStream> bmi_install_script;
+ if (export_info.BmiInstallation) {
+ bmi_install_script = cm::make_unique<cmGeneratedFileStream>(
+ export_info.BmiInstallation->ScriptLocation);
+ }
+
+ auto cmEscape = [](cm::string_view str) {
+ return cmOutputConverter::EscapeForCMake(
+ str, cmOutputConverter::WrapQuotes::NoWrap);
+ };
+ auto install_destination =
+ [&cmEscape](std::string const& dest) -> std::pair<bool, std::string> {
+ if (cmSystemTools::FileIsFullPath(dest)) {
+ return std::make_pair(true, cmEscape(dest));
+ }
+ return std::make_pair(false,
+ cmStrCat("${_IMPORT_PREFIX}/", cmEscape(dest)));
+ };
+
+ // public/private requirement tracking.
+ std::set<std::string> private_modules;
+ std::map<std::string, std::set<std::string>> public_source_requires;
+
+ for (cmScanDepInfo const& object : objects) {
+ // Convert to forward slashes.
+ auto output_path = object.PrimaryOutput;
+#ifdef _WIN32
+ cmSystemTools::ConvertToUnixSlashes(output_path);
+#endif
+ // Find the fileset for this object.
+ auto fileset_info_itr = export_info.ObjectToFileSet.find(output_path);
+ bool const has_provides = !object.Provides.empty();
+ if (fileset_info_itr == export_info.ObjectToFileSet.end()) {
+ // If it provides anything, it should have a `CXX_MODULES` or
+ // `CXX_MODULE_INTERNAL_PARTITIONS` type and be present.
+ if (has_provides) {
+ // Take the first module provided to provide context.
+ auto const& provides = object.Provides[0];
+ char const* ok_types = "`CXX_MODULES`";
+ if (provides.LogicalName.find(':') != std::string::npos) {
+ ok_types = "`CXX_MODULES` (or `CXX_MODULE_INTERNAL_PARTITIONS` if "
+ "it is not `export`ed)";
+ }
+ cmSystemTools::Error(cmStrCat(
+ "Output ", object.PrimaryOutput, " provides the `",
+ provides.LogicalName,
+ "` module but it is not found in a `FILE_SET` of type ", ok_types));
+ result = false;
+ }
+
+ // This object file does not provide anything, so nothing more needs to
+ // be done.
+ continue;
+ }
+
+ auto const& file_set = fileset_info_itr->second;
+
+ // Verify the fileset type for the object.
+ if (file_set.Type == "CXX_MODULES"_s) {
+ if (!has_provides) {
+ cmSystemTools::Error(
+ cmStrCat("Output ", object.PrimaryOutput,
+ " is of type `CXX_MODULES` but does not provide a module"));
+ result = false;
+ continue;
+ }
+ } else if (file_set.Type == "CXX_MODULE_INTERNAL_PARTITIONS"_s) {
+ if (!has_provides) {
+ cmSystemTools::Error(
+ cmStrCat("Source ", file_set.SourcePath,
+ " is of type `CXX_MODULE_INTERNAL_PARTITIONS` but does not "
+ "provide a module"));
+ result = false;
+ continue;
+ }
+ auto const& provides = object.Provides[0];
+ if (provides.LogicalName.find(':') == std::string::npos) {
+ cmSystemTools::Error(
+ cmStrCat("Source ", file_set.SourcePath,
+ " is of type `CXX_MODULE_INTERNAL_PARTITIONS` but does not "
+ "provide a module partition"));
+ result = false;
+ continue;
+ }
+ } else if (file_set.Type == "CXX_MODULE_HEADERS"_s) {
+ // TODO.
+ } else {
+ if (has_provides) {
+ auto const& provides = object.Provides[0];
+ char const* ok_types = "`CXX_MODULES`";
+ if (provides.LogicalName.find(':') != std::string::npos) {
+ ok_types = "`CXX_MODULES` (or `CXX_MODULE_INTERNAL_PARTITIONS` if "
+ "it is not `export`ed)";
+ }
+ cmSystemTools::Error(
+ cmStrCat("Source ", file_set.SourcePath, " provides the `",
+ provides.LogicalName, "` C++ module but is of type `",
+ file_set.Type, "` module but must be of type ", ok_types));
+ result = false;
+ }
+
+ // Not a C++ module; ignore.
+ continue;
+ }
+
+ if (!cmFileSetVisibilityIsForInterface(file_set.Visibility)) {
+ // Nothing needs to be conveyed about non-`PUBLIC` modules.
+ for (auto const& p : object.Provides) {
+ private_modules.insert(p.LogicalName);
+ }
+ continue;
+ }
+
+ // The module is public. Record what it directly requires.
+ {
+ auto& reqs = public_source_requires[file_set.SourcePath];
+ for (auto const& r : object.Requires) {
+ reqs.insert(r.LogicalName);
+ }
+ }
+
+ // Write out properties and install rules for any exports.
+ for (auto const& p : object.Provides) {
+ bool bmi_dest_is_abs = false;
+ std::string bmi_destination;
+ if (export_info.BmiInstallation) {
+ auto dest =
+ install_destination(export_info.BmiInstallation->Destination);
+ bmi_dest_is_abs = dest.first;
+ bmi_destination = cmStrCat(dest.second, '/');
+ }
+
+ std::string install_bmi_path;
+ std::string build_bmi_path;
+ auto m = cb.ModuleFile(p.LogicalName);
+ if (m) {
+ install_bmi_path = cmStrCat(
+ bmi_destination, cmEscape(cmSystemTools::GetFilenameName(*m)));
+ build_bmi_path = cmEscape(*m);
+ }
+
+ for (auto const& exp : exports) {
+ std::string iface_source;
+ if (exp.second->Install && file_set.Destination) {
+ auto dest = install_destination(*file_set.Destination);
+ iface_source = cmStrCat(
+ dest.second, '/', cmEscape(file_set.RelativeDirectory),
+ cmEscape(cmSystemTools::GetFilenameName(file_set.SourcePath)));
+ } else {
+ iface_source = cmEscape(file_set.SourcePath);
+ }
+
+ std::string bmi_path;
+ if (exp.second->Install && export_info.BmiInstallation) {
+ bmi_path = install_bmi_path;
+ } else if (!exp.second->Install) {
+ bmi_path = build_bmi_path;
+ }
+
+ if (iface_source.empty()) {
+ // No destination for the C++ module source; ignore this property
+ // value.
+ continue;
+ }
+
+ *exp.first << " \"" << cmEscape(p.LogicalName) << '='
+ << iface_source;
+ if (!bmi_path.empty()) {
+ *exp.first << ',' << bmi_path;
+ }
+ *exp.first << "\"\n";
+ }
+
+ if (bmi_install_script) {
+ auto const& bmi_install = *export_info.BmiInstallation;
+
+ *bmi_install_script << "if (CMAKE_INSTALL_COMPONENT STREQUAL \""
+ << cmEscape(bmi_install.Component) << '\"';
+ if (!bmi_install.ExcludeFromAll) {
+ *bmi_install_script << " OR NOT CMAKE_INSTALL_COMPONENT";
+ }
+ *bmi_install_script << ")\n";
+ *bmi_install_script << " file(INSTALL\n"
+ " DESTINATION \"";
+ if (!bmi_dest_is_abs) {
+ *bmi_install_script << "${CMAKE_INSTALL_PREFIX}/";
+ }
+ *bmi_install_script << cmEscape(bmi_install.Destination)
+ << "\"\n"
+ " TYPE FILE\n";
+ if (bmi_install.Optional) {
+ *bmi_install_script << " OPTIONAL\n";
+ }
+ if (!bmi_install.MessageLevel.empty()) {
+ *bmi_install_script << " " << bmi_install.MessageLevel << "\n";
+ }
+ if (!bmi_install.Permissions.empty()) {
+ *bmi_install_script << " PERMISSIONS" << bmi_install.Permissions
+ << "\n";
+ }
+ *bmi_install_script << " FILES \"" << *m << "\")\n";
+ if (bmi_dest_is_abs) {
+ *bmi_install_script
+ << " list(APPEND CMAKE_ABSOLUTE_DESTINATION_FILES\n"
+ " \""
+ << cmEscape(cmSystemTools::GetFilenameName(*m))
+ << "\")\n"
+ " if (CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)\n"
+ " message(WARNING\n"
+ " \"ABSOLUTE path INSTALL DESTINATION : "
+ "${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"
+ " endif ()\n"
+ " if (CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n"
+ " message(FATAL_ERROR\n"
+ " \"ABSOLUTE path INSTALL DESTINATION forbidden (by "
+ "caller): ${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"
+ " endif ()\n";
+ }
+ *bmi_install_script << "endif ()\n";
+ }
+ }
+ }
+
+ // Add trailing parenthesis for the `set_property` call.
+ for (auto const& exp : exports) {
+ *exp.first << ")\n";
+ }
+
+ // Check that public sources only require public modules.
+ for (auto const& pub_reqs : public_source_requires) {
+ for (auto const& req : pub_reqs.second) {
+ if (private_modules.count(req)) {
+ cmSystemTools::Error(cmStrCat(
+ "Public C++ module source `", pub_reqs.first, "` requires the `",
+ req, "` C++ module which is provided by a private source"));
+ result = false;
+ }
+ }
+ }
+
+ return result;
+}
diff --git a/Source/cmDyndepCollation.h b/Source/cmDyndepCollation.h
new file mode 100644
index 0000000..e70ac09
--- /dev/null
+++ b/Source/cmDyndepCollation.h
@@ -0,0 +1,52 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <cm/optional>
+
+class cmGeneratorTarget;
+struct cmScanDepInfo;
+class cmSourceFile;
+
+namespace Json {
+class Value;
+}
+
+struct cmDyndepGeneratorCallbacks
+{
+ std::function<std::string(cmSourceFile const* sf, std::string const& config)>
+ ObjectFilePath;
+};
+
+struct cmDyndepMetadataCallbacks
+{
+ std::function<cm::optional<std::string>(std::string const& name)> ModuleFile;
+};
+
+struct cmCxxModuleExportInfo;
+struct cmCxxModuleExportInfoDeleter
+{
+ void operator()(cmCxxModuleExportInfo* ei) const;
+};
+
+struct cmDyndepCollation
+{
+ static void AddCollationInformation(Json::Value& tdi,
+ cmGeneratorTarget const* gt,
+ std::string const& config,
+ cmDyndepGeneratorCallbacks const& cb);
+
+ static std::unique_ptr<cmCxxModuleExportInfo, cmCxxModuleExportInfoDeleter>
+ ParseExportInfo(Json::Value const& tdi);
+ static bool WriteDyndepMetadata(std::string const& lang,
+ std::vector<cmScanDepInfo> const& objects,
+ cmCxxModuleExportInfo const& export_info,
+ cmDyndepMetadataCallbacks const& cb);
+};
diff --git a/Source/cmExperimental.cxx b/Source/cmExperimental.cxx
index 922b53f..c890e4b 100644
--- a/Source/cmExperimental.cxx
+++ b/Source/cmExperimental.cxx
@@ -27,7 +27,7 @@ struct FeatureData
bool Warned;
} LookupTable[] = {
// CxxModuleCMakeApi
- { "3c375311-a3c9-4396-a187-3227ef642046",
+ { "2182bf5c-ef0d-489a-91da-49dbc3090d2a",
"CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API",
"CMake's C++ module support is experimental. It is meant only for "
"experimentation and feedback to CMake developers.",
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 50bc78c..c8e2cb8 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -379,7 +379,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
const char* propName = "INTERFACE_INCLUDE_DIRECTORIES";
cmValue input = target->GetProperty(propName);
- cmGeneratorExpression ge;
+ cmGeneratorExpression ge(*target->Makefile->GetCMakeInstance());
std::string dirs = cmGeneratorExpression::Preprocess(
cmJoin(target->Target->GetInstallIncludeDirectoriesEntries(te), ";"),
@@ -669,8 +669,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
while ((pos = input.find("$<TARGET_PROPERTY:", lastPos)) !=
std::string::npos) {
- std::string::size_type nameStartPos =
- pos + sizeof("$<TARGET_PROPERTY:") - 1;
+ std::string::size_type nameStartPos = pos + cmStrLen("$<TARGET_PROPERTY:");
std::string::size_type closePos = input.find('>', nameStartPos);
std::string::size_type commaPos = input.find(',', nameStartPos);
std::string::size_type nextOpenPos = input.find("$<", nameStartPos);
@@ -696,7 +695,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
pos = 0;
lastPos = pos;
while ((pos = input.find("$<TARGET_NAME:", lastPos)) != std::string::npos) {
- std::string::size_type nameStartPos = pos + sizeof("$<TARGET_NAME:") - 1;
+ std::string::size_type nameStartPos = pos + cmStrLen("$<TARGET_NAME:");
std::string::size_type endPos = input.find('>', nameStartPos);
if (endPos == std::string::npos) {
errorString = "$<TARGET_NAME:...> expression incomplete";
@@ -721,7 +720,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
lastPos = pos;
while (errorString.empty() &&
(pos = input.find("$<LINK_ONLY:", lastPos)) != std::string::npos) {
- std::string::size_type nameStartPos = pos + sizeof("$<LINK_ONLY:") - 1;
+ std::string::size_type nameStartPos = pos + cmStrLen("$<LINK_ONLY:");
std::string::size_type endPos = input.find('>', nameStartPos);
if (endPos == std::string::npos) {
errorString = "$<LINK_ONLY:...> expression incomplete";
@@ -939,13 +938,13 @@ void cmExportFileGenerator::GeneratePolicyHeaderCode(std::ostream& os)
// Isolate the file policy level.
// Support CMake versions as far back as 2.6 but also support using NEW
- // policy settings for up to CMake 3.23 (this upper limit may be reviewed
+ // policy settings for up to CMake 3.24 (this upper limit may be reviewed
// and increased from time to time). This reduces the opportunity for CMake
// warnings when an older export file is later used with newer CMake
// versions.
/* clang-format off */
os << "cmake_policy(PUSH)\n"
- << "cmake_policy(VERSION 2.8.3...3.23)\n";
+ << "cmake_policy(VERSION 2.8.3...3.24)\n";
/* clang-format on */
}
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 195737b..5e190f4 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -570,7 +570,7 @@ std::string cmExportInstallFileGenerator::GetFileSetDirectories(
auto configs =
gte->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
- cmGeneratorExpression ge;
+ cmGeneratorExpression ge(*gte->Makefile->GetCMakeInstance());
auto cge = ge.Parse(te->FileSetGenerators.at(fileSet)->GetDestination());
for (auto const& config : configs) {
@@ -617,7 +617,7 @@ std::string cmExportInstallFileGenerator::GetFileSetFiles(
auto fileEntries = fileSet->CompileFileEntries();
auto directoryEntries = fileSet->CompileDirectoryEntries();
- cmGeneratorExpression destGe;
+ cmGeneratorExpression destGe(*gte->Makefile->GetCMakeInstance());
auto destCge =
destGe.Parse(te->FileSetGenerators.at(fileSet)->GetDestination());
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index e98aa05..33c057d 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -70,7 +70,7 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
return std::string();
}
- cmGeneratorExpression ge;
+ cmGeneratorExpression ge(*tgt->Makefile->GetCMakeInstance());
std::unique_ptr<cmGeneratorExpressionDAGChecker> parentDagChecker;
if (propName == "INTERFACE_LINK_OPTIONS") {
diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx
index 7f8374d..d1d3d25 100644
--- a/Source/cmFileAPI.cxx
+++ b/Source/cmFileAPI.cxx
@@ -18,6 +18,7 @@
#include "cmFileAPICMakeFiles.h"
#include "cmFileAPICache.h"
#include "cmFileAPICodemodel.h"
+#include "cmFileAPIConfigureLog.h"
#include "cmFileAPIToolchains.h"
#include "cmGlobalGenerator.h"
#include "cmStringAlgorithms.h"
@@ -66,6 +67,26 @@ void cmFileAPI::ReadQueries()
}
}
+std::vector<unsigned long> cmFileAPI::GetConfigureLogVersions()
+{
+ std::vector<unsigned long> versions;
+ auto getConfigureLogVersions = [&versions](Query const& q) {
+ for (Object const& o : q.Known) {
+ if (o.Kind == ObjectKind::ConfigureLog) {
+ versions.emplace_back(o.Version);
+ }
+ }
+ };
+ getConfigureLogVersions(this->TopQuery);
+ for (auto const& client : this->ClientQueries) {
+ getConfigureLogVersions(client.second.DirQuery);
+ }
+ std::sort(versions.begin(), versions.end());
+ versions.erase(std::unique(versions.begin(), versions.end()),
+ versions.end());
+ return versions;
+}
+
void cmFileAPI::WriteReplies()
{
if (this->QueryExists) {
@@ -241,6 +262,17 @@ bool cmFileAPI::ReadQuery(std::string const& query,
objects.push_back(o);
return true;
}
+ if (kindName == ObjectKindName(ObjectKind::ConfigureLog)) {
+ Object o;
+ o.Kind = ObjectKind::ConfigureLog;
+ if (verStr == "v1") {
+ o.Version = 1;
+ } else {
+ return false;
+ }
+ objects.push_back(o);
+ return true;
+ }
if (kindName == ObjectKindName(ObjectKind::Cache)) {
Object o;
o.Kind = ObjectKind::Cache;
@@ -411,11 +443,12 @@ const char* cmFileAPI::ObjectKindName(ObjectKind kind)
{
// Keep in sync with ObjectKind enum.
static const char* objectKindNames[] = {
- "codemodel", //
- "cache", //
- "cmakeFiles", //
- "toolchains", //
- "__test" //
+ "codemodel", //
+ "configureLog", //
+ "cache", //
+ "cmakeFiles", //
+ "toolchains", //
+ "__test" //
};
return objectKindNames[static_cast<size_t>(kind)];
}
@@ -442,6 +475,9 @@ Json::Value cmFileAPI::BuildObject(Object const& object)
case ObjectKind::CodeModel:
value = this->BuildCodeModel(object);
break;
+ case ObjectKind::ConfigureLog:
+ value = this->BuildConfigureLog(object);
+ break;
case ObjectKind::Cache:
value = this->BuildCache(object);
break;
@@ -503,6 +539,8 @@ cmFileAPI::ClientRequest cmFileAPI::BuildClientRequest(
if (kindName == this->ObjectKindName(ObjectKind::CodeModel)) {
r.Kind = ObjectKind::CodeModel;
+ } else if (kindName == this->ObjectKindName(ObjectKind::ConfigureLog)) {
+ r.Kind = ObjectKind::ConfigureLog;
} else if (kindName == this->ObjectKindName(ObjectKind::Cache)) {
r.Kind = ObjectKind::Cache;
} else if (kindName == this->ObjectKindName(ObjectKind::CMakeFiles)) {
@@ -530,6 +568,9 @@ cmFileAPI::ClientRequest cmFileAPI::BuildClientRequest(
case ObjectKind::CodeModel:
this->BuildClientRequestCodeModel(r, versions);
break;
+ case ObjectKind::ConfigureLog:
+ this->BuildClientRequestConfigureLog(r, versions);
+ break;
case ObjectKind::Cache:
this->BuildClientRequestCache(r, versions);
break;
@@ -687,7 +728,7 @@ std::string cmFileAPI::NoSupportedVersion(
// The "codemodel" object kind.
// Update Help/manual/cmake-file-api.7.rst when updating this constant.
-static unsigned int const CodeModelV2Minor = 4;
+static unsigned int const CodeModelV2Minor = 5;
void cmFileAPI::BuildClientRequestCodeModel(
ClientRequest& r, std::vector<RequestVersion> const& versions)
@@ -719,6 +760,41 @@ Json::Value cmFileAPI::BuildCodeModel(Object const& object)
return codemodel;
}
+// The "configureLog" object kind.
+
+// Update Help/manual/cmake-file-api.7.rst when updating this constant.
+static unsigned int const ConfigureLogV1Minor = 0;
+
+void cmFileAPI::BuildClientRequestConfigureLog(
+ ClientRequest& r, std::vector<RequestVersion> const& versions)
+{
+ // Select a known version from those requested.
+ for (RequestVersion const& v : versions) {
+ if ((v.Major == 1 && v.Minor <= ConfigureLogV1Minor)) {
+ r.Version = v.Major;
+ break;
+ }
+ }
+ if (!r.Version) {
+ r.Error = NoSupportedVersion(versions);
+ }
+}
+
+Json::Value cmFileAPI::BuildConfigureLog(Object const& object)
+{
+ Json::Value configureLog = cmFileAPIConfigureLogDump(*this, object.Version);
+ configureLog["kind"] = this->ObjectKindName(object.Kind);
+
+ Json::Value& version = configureLog["version"];
+ if (object.Version == 1) {
+ version = BuildVersion(1, ConfigureLogV1Minor);
+ } else {
+ return configureLog; // should be unreachable
+ }
+
+ return configureLog;
+}
+
// The "cache" object kind.
static unsigned int const CacheV2Minor = 0;
@@ -870,6 +946,14 @@ Json::Value cmFileAPI::ReportCapabilities()
{
Json::Value request = Json::objectValue;
+ request["kind"] = ObjectKindName(ObjectKind::ConfigureLog);
+ Json::Value& versions = request["version"] = Json::arrayValue;
+ versions.append(BuildVersion(1, ConfigureLogV1Minor));
+ requests.append(std::move(request)); // NOLINT(*)
+ }
+
+ {
+ Json::Value request = Json::objectValue;
request["kind"] = ObjectKindName(ObjectKind::Cache);
Json::Value& versions = request["version"] = Json::arrayValue;
versions.append(BuildVersion(2, CacheV2Minor));
diff --git a/Source/cmFileAPI.h b/Source/cmFileAPI.h
index 22302b4..6d7678f 100644
--- a/Source/cmFileAPI.h
+++ b/Source/cmFileAPI.h
@@ -24,6 +24,9 @@ public:
/** Read fileapi queries from disk. */
void ReadQueries();
+ /** Get the list of configureLog object kind versions requested. */
+ std::vector<unsigned long> GetConfigureLogVersions();
+
/** Write fileapi replies to disk. */
void WriteReplies();
@@ -54,6 +57,7 @@ private:
enum class ObjectKind
{
CodeModel,
+ ConfigureLog,
Cache,
CMakeFiles,
Toolchains,
@@ -193,6 +197,10 @@ private:
ClientRequest& r, std::vector<RequestVersion> const& versions);
Json::Value BuildCodeModel(Object const& object);
+ void BuildClientRequestConfigureLog(
+ ClientRequest& r, std::vector<RequestVersion> const& versions);
+ Json::Value BuildConfigureLog(Object const& object);
+
void BuildClientRequestCache(ClientRequest& r,
std::vector<RequestVersion> const& versions);
Json::Value BuildCache(Object const& object);
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index 0581802..d3683d4 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -17,6 +17,7 @@
#include <cm/string_view>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include <cm3p/json/value.h>
@@ -44,6 +45,7 @@
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmSourceFile.h"
#include "cmSourceGroup.h"
#include "cmState.h"
@@ -434,6 +436,8 @@ class Target
std::unordered_map<CompileData, Json::ArrayIndex> CompileGroupMap;
std::vector<CompileGroup> CompileGroups;
+ using FileSetDatabase = std::map<std::string, Json::ArrayIndex>;
+
template <typename T>
JBT<T> ToJBT(BT<T> const& bt)
{
@@ -444,6 +448,7 @@ class Target
JBTs<T> ToJBTs(BTs<T> const& bts)
{
std::vector<JBTIndex> ids;
+ ids.reserve(bts.Backtraces.size());
for (cmListFileBacktrace const& backtrace : bts.Backtraces) {
ids.emplace_back(this->Backtraces.Add(backtrace));
}
@@ -466,9 +471,12 @@ class Target
Json::Value DumpPrecompileHeader(JBT<std::string> const& header);
Json::Value DumpLanguageStandard(JBTs<std::string> const& standard);
Json::Value DumpDefine(JBT<std::string> const& def);
- Json::Value DumpSources();
+ std::pair<Json::Value, FileSetDatabase> DumpFileSets();
+ Json::Value DumpFileSet(cmFileSet const* fs,
+ std::vector<std::string> const& directories);
+ Json::Value DumpSources(FileSetDatabase const& fsdb);
Json::Value DumpSource(cmGeneratorTarget::SourceAndKind const& sk,
- Json::ArrayIndex si);
+ Json::ArrayIndex si, FileSetDatabase const& fsdb);
Json::Value DumpSourceGroups();
Json::Value DumpSourceGroup(SourceGroup& sg);
Json::Value DumpCompileGroups();
@@ -1216,7 +1224,13 @@ Json::Value Target::Dump()
{
this->ProcessLanguages();
- target["sources"] = this->DumpSources();
+ auto fileSetInfo = this->DumpFileSets();
+
+ if (!fileSetInfo.first.isNull()) {
+ target["fileSets"] = fileSetInfo.first;
+ }
+
+ target["sources"] = this->DumpSources(fileSetInfo.second);
Json::Value folder = this->DumpFolder();
if (!folder.isNull()) {
@@ -1527,29 +1541,113 @@ Json::Value Target::DumpPaths()
return paths;
}
-Json::Value Target::DumpSources()
+std::pair<Json::Value, Target::FileSetDatabase> Target::DumpFileSets()
+{
+ Json::Value fsJson = Json::nullValue;
+ FileSetDatabase fsdb;
+
+ // Build the fileset database.
+ auto const* tgt = this->GT->Target;
+ auto const& fs_names = tgt->GetAllFileSetNames();
+
+ if (!fs_names.empty()) {
+ fsJson = Json::arrayValue;
+ size_t fsIndex = 0;
+ for (auto const& fs_name : fs_names) {
+ auto const* fs = tgt->GetFileSet(fs_name);
+ if (!fs) {
+ this->GT->Makefile->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("Target \"", tgt->GetName(),
+ "\" is tracked to have file set \"", fs_name,
+ "\", but it was not found."));
+ continue;
+ }
+
+ auto fileEntries = fs->CompileFileEntries();
+ auto directoryEntries = fs->CompileDirectoryEntries();
+
+ auto directories = fs->EvaluateDirectoryEntries(
+ directoryEntries, this->GT->LocalGenerator, this->Config, this->GT);
+
+ fsJson.append(this->DumpFileSet(fs, directories));
+
+ std::map<std::string, std::vector<std::string>> files_per_dirs;
+ for (auto const& entry : fileEntries) {
+ fs->EvaluateFileEntry(directories, files_per_dirs, entry,
+ this->GT->LocalGenerator, this->Config,
+ this->GT);
+ }
+
+ for (auto const& files_per_dir : files_per_dirs) {
+ auto const& dir = files_per_dir.first;
+ for (auto const& file : files_per_dir.second) {
+ std::string sf_path;
+ if (dir.empty()) {
+ sf_path = file;
+ } else {
+ sf_path = cmStrCat(dir, '/', file);
+ }
+ fsdb[sf_path] = static_cast<Json::ArrayIndex>(fsIndex);
+ }
+ }
+
+ ++fsIndex;
+ }
+ }
+
+ return std::make_pair(fsJson, fsdb);
+}
+
+Json::Value Target::DumpFileSet(cmFileSet const* fs,
+ std::vector<std::string> const& directories)
+{
+ Json::Value fileSet = Json::objectValue;
+
+ fileSet["name"] = fs->GetName();
+ fileSet["type"] = fs->GetType();
+ fileSet["visibility"] =
+ std::string(cmFileSetVisibilityToName(fs->GetVisibility()));
+
+ Json::Value baseDirs = Json::arrayValue;
+ for (auto const& directory : directories) {
+ baseDirs.append(directory);
+ }
+ fileSet["baseDirectories"] = baseDirs;
+
+ return fileSet;
+}
+
+Json::Value Target::DumpSources(FileSetDatabase const& fsdb)
{
Json::Value sources = Json::arrayValue;
cmGeneratorTarget::KindedSources const& kinded =
this->GT->GetKindedSources(this->Config);
for (cmGeneratorTarget::SourceAndKind const& sk : kinded.Sources) {
- sources.append(this->DumpSource(sk, sources.size()));
+ sources.append(this->DumpSource(sk, sources.size(), fsdb));
}
return sources;
}
Json::Value Target::DumpSource(cmGeneratorTarget::SourceAndKind const& sk,
- Json::ArrayIndex si)
+ Json::ArrayIndex si,
+ FileSetDatabase const& fsdb)
{
Json::Value source = Json::objectValue;
- std::string const path = sk.Source.Value->ResolveFullPath();
+ cmSourceFile* sf = sk.Source.Value;
+ std::string const path = sf->ResolveFullPath();
source["path"] = RelativeIfUnder(this->TopSource, path);
if (sk.Source.Value->GetIsGenerated()) {
source["isGenerated"] = true;
}
this->AddBacktrace(source, sk.Source.Backtrace);
+ auto fsit = fsdb.find(path);
+ if (fsit != fsdb.end()) {
+ source["fileSetIndex"] = fsit->second;
+ }
+
if (cmSourceGroup* sg =
this->GT->Makefile->FindSourceGroup(path, this->SourceGroupsLocal)) {
source["sourceGroupIndex"] = this->AddSourceGroup(sg, si);
diff --git a/Source/cmFileAPIConfigureLog.cxx b/Source/cmFileAPIConfigureLog.cxx
new file mode 100644
index 0000000..50189cb
--- /dev/null
+++ b/Source/cmFileAPIConfigureLog.cxx
@@ -0,0 +1,67 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmFileAPIConfigureLog.h"
+
+#include <cm3p/json/value.h>
+
+#include "cmFileAPI.h"
+#include "cmStringAlgorithms.h"
+#include "cmake.h"
+
+namespace {
+
+class ConfigureLog
+{
+ cmFileAPI& FileAPI;
+ unsigned long Version;
+
+ Json::Value DumpPath();
+ Json::Value DumpEventKindNames();
+
+public:
+ ConfigureLog(cmFileAPI& fileAPI, unsigned long version);
+ Json::Value Dump();
+};
+
+ConfigureLog::ConfigureLog(cmFileAPI& fileAPI, unsigned long version)
+ : FileAPI(fileAPI)
+ , Version(version)
+{
+ static_cast<void>(this->Version);
+}
+
+Json::Value ConfigureLog::Dump()
+{
+ Json::Value configureLog = Json::objectValue;
+ configureLog["path"] = this->DumpPath();
+ configureLog["eventKindNames"] = this->DumpEventKindNames();
+ return configureLog;
+}
+
+Json::Value ConfigureLog::DumpPath()
+{
+ return cmStrCat(this->FileAPI.GetCMakeInstance()->GetHomeOutputDirectory(),
+ "/CMakeFiles/CMakeConfigureLog.yaml");
+}
+
+Json::Value ConfigureLog::DumpEventKindNames()
+{
+ // Report at most one version of each event kind.
+ // If a new event kind is added, increment ConfigureLogV1Minor.
+ // If a new version of an existing event kind is added, a new
+ // major version of the configureLog object kind is needed.
+ Json::Value eventKindNames = Json::arrayValue;
+ if (this->Version == 1) {
+ eventKindNames.append("try_compile-v1"); // WriteTryCompileEvent
+ eventKindNames.append("try_run-v1"); // WriteTryRunEvent
+ }
+ return eventKindNames;
+}
+}
+
+Json::Value cmFileAPIConfigureLogDump(cmFileAPI& fileAPI,
+ unsigned long version)
+{
+ ConfigureLog configureLog(fileAPI, version);
+ return configureLog.Dump();
+}
diff --git a/Source/cmFileAPIConfigureLog.h b/Source/cmFileAPIConfigureLog.h
new file mode 100644
index 0000000..deaa403
--- /dev/null
+++ b/Source/cmFileAPIConfigureLog.h
@@ -0,0 +1,12 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <cm3p/json/value.h>
+
+class cmFileAPI;
+
+extern Json::Value cmFileAPIConfigureLogDump(cmFileAPI& fileAPI,
+ unsigned long version);
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index fe38db5..dfce033 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -845,8 +845,10 @@ bool HandleMakeDirectoryCommand(std::vector<std::string> const& args,
cmSystemTools::SetFatalErrorOccurred();
return false;
}
- if (!cmSystemTools::MakeDirectory(*cdir)) {
- std::string error = "problem creating directory: " + *cdir;
+ cmsys::Status mkdirStatus = cmSystemTools::MakeDirectory(*cdir);
+ if (!mkdirStatus) {
+ std::string error = cmStrCat("failed to create directory:\n ", *cdir,
+ "\nbecause: ", mkdirStatus.GetString());
status.SetError(error);
return false;
}
@@ -1408,12 +1410,14 @@ bool HandleCopyFile(std::vector<std::string> const& args,
struct Arguments
{
+ bool InputMayBeRecent = false;
bool OnlyIfDifferent = false;
std::string Result;
};
static auto const parser =
cmArgumentParser<Arguments>{}
+ .Bind("INPUT_MAY_BE_RECENT"_s, &Arguments::InputMayBeRecent)
.Bind("ONLY_IF_DIFFERENT"_s, &Arguments::OnlyIfDifferent)
.Bind("RESULT"_s, &Arguments::Result);
@@ -1456,9 +1460,13 @@ bool HandleCopyFile(std::vector<std::string> const& args,
} else {
when = cmSystemTools::CopyWhen::Always;
}
+ cmSystemTools::CopyInputRecent const inputRecent = arguments.InputMayBeRecent
+ ? cmSystemTools::CopyInputRecent::Yes
+ : cmSystemTools::CopyInputRecent::No;
std::string err;
- if (cmSystemTools::CopySingleFile(oldname, newname, when, &err) ==
+ if (cmSystemTools::CopySingleFile(oldname, newname, when, inputRecent,
+ &err) ==
cmSystemTools::CopyResult::Success) {
if (!arguments.Result.empty()) {
status.GetMakefile().AddDefinition(arguments.Result, "0");
@@ -2107,6 +2115,14 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
// Verify MD5 sum if requested:
//
if (hash) {
+ if (res != CURLE_OK) {
+ status.SetError(cmStrCat(
+ "DOWNLOAD cannot compute hash on failed download\n"
+ " status: [",
+ static_cast<int>(res), ";\"", ::curl_easy_strerror(res), "\"]"));
+ return false;
+ }
+
std::string actualHash = hash->HashFile(file);
if (actualHash.empty()) {
status.SetError("DOWNLOAD cannot compute hash on downloaded file");
@@ -2130,11 +2146,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
expectedHash,
"]\n"
" actual hash: [",
- actualHash,
- "]\n"
- " status: [",
- static_cast<int>(res), ";\"",
- ::curl_easy_strerror(res), "\"]\n"));
+ actualHash, "]\n"));
return false;
}
}
@@ -2458,11 +2470,13 @@ void AddEvaluationFile(const std::string& inputName,
{
cmListFileBacktrace lfbt = status.GetMakefile().GetBacktrace();
- cmGeneratorExpression outputGe(lfbt);
+ cmGeneratorExpression outputGe(*status.GetMakefile().GetCMakeInstance(),
+ lfbt);
std::unique_ptr<cmCompiledGeneratorExpression> outputCge =
outputGe.Parse(outputExpr);
- cmGeneratorExpression conditionGe(lfbt);
+ cmGeneratorExpression conditionGe(*status.GetMakefile().GetCMakeInstance(),
+ lfbt);
std::unique_ptr<cmCompiledGeneratorExpression> conditionCge =
conditionGe.Parse(condition);
@@ -3398,20 +3412,29 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
}
int compressionLevel = 0;
+ int minCompressionLevel = 0;
+ int maxCompressionLevel = 9;
+ if (compress == cmSystemTools::TarCompressZstd) {
+ maxCompressionLevel = 19;
+ }
+
if (!parsedArgs.CompressionLevel.empty()) {
if (parsedArgs.CompressionLevel.size() != 1 &&
!std::isdigit(parsedArgs.CompressionLevel[0])) {
- status.SetError(cmStrCat("compression level ",
- parsedArgs.CompressionLevel,
- " should be in range 0 to 9"));
+ status.SetError(
+ cmStrCat("compression level ", parsedArgs.CompressionLevel, " for ",
+ parsedArgs.Compression, " should be in range ",
+ minCompressionLevel, " to ", maxCompressionLevel));
cmSystemTools::SetFatalErrorOccurred();
return false;
}
compressionLevel = std::stoi(parsedArgs.CompressionLevel);
- if (compressionLevel < 0 || compressionLevel > 9) {
- status.SetError(cmStrCat("compression level ",
- parsedArgs.CompressionLevel,
- " should be in range 0 to 9"));
+ if (compressionLevel < minCompressionLevel ||
+ compressionLevel > maxCompressionLevel) {
+ status.SetError(
+ cmStrCat("compression level ", parsedArgs.CompressionLevel, " for ",
+ parsedArgs.Compression, " should be in range ",
+ minCompressionLevel, " to ", maxCompressionLevel));
cmSystemTools::SetFatalErrorOccurred();
return false;
}
diff --git a/Source/cmFileLockPool.cxx b/Source/cmFileLockPool.cxx
index 99f6885..c23a99c 100644
--- a/Source/cmFileLockPool.cxx
+++ b/Source/cmFileLockPool.cxx
@@ -15,7 +15,7 @@ cmFileLockPool::~cmFileLockPool() = default;
void cmFileLockPool::PushFunctionScope()
{
- this->FunctionScopes.push_back(ScopePool());
+ this->FunctionScopes.emplace_back();
}
void cmFileLockPool::PopFunctionScope()
@@ -26,7 +26,7 @@ void cmFileLockPool::PopFunctionScope()
void cmFileLockPool::PushFileScope()
{
- this->FileScopes.push_back(ScopePool());
+ this->FileScopes.emplace_back();
}
void cmFileLockPool::PopFileScope()
diff --git a/Source/cmFileSet.cxx b/Source/cmFileSet.cxx
index d6665a2..b96ba6e 100644
--- a/Source/cmFileSet.cxx
+++ b/Source/cmFileSet.cxx
@@ -78,9 +78,10 @@ bool cmFileSetVisibilityIsForInterface(cmFileSetVisibility vis)
return false;
}
-cmFileSet::cmFileSet(std::string name, std::string type,
+cmFileSet::cmFileSet(cmake& cmakeInstance, std::string name, std::string type,
cmFileSetVisibility visibility)
- : Name(std::move(name))
+ : CMakeInstance(cmakeInstance)
+ , Name(std::move(name))
, Type(std::move(type))
, Visibility(visibility)
{
@@ -113,7 +114,7 @@ cmFileSet::CompileFileEntries() const
for (auto const& entry : this->FileEntries) {
for (auto const& ex : cmExpandedList(entry.Value)) {
- cmGeneratorExpression ge(entry.Backtrace);
+ cmGeneratorExpression ge(this->CMakeInstance, entry.Backtrace);
auto cge = ge.Parse(ex);
result.push_back(std::move(cge));
}
@@ -129,7 +130,7 @@ cmFileSet::CompileDirectoryEntries() const
for (auto const& entry : this->DirectoryEntries) {
for (auto const& ex : cmExpandedList(entry.Value)) {
- cmGeneratorExpression ge(entry.Backtrace);
+ cmGeneratorExpression ge(this->CMakeInstance, entry.Backtrace);
auto cge = ge.Parse(ex);
result.push_back(std::move(cge));
}
diff --git a/Source/cmFileSet.h b/Source/cmFileSet.h
index 5357e77..54d430c 100644
--- a/Source/cmFileSet.h
+++ b/Source/cmFileSet.h
@@ -17,6 +17,7 @@ struct cmGeneratorExpressionDAGChecker;
class cmGeneratorTarget;
class cmLocalGenerator;
class cmMakefile;
+class cmake;
enum class cmFileSetVisibility
{
@@ -33,7 +34,7 @@ bool cmFileSetVisibilityIsForInterface(cmFileSetVisibility vis);
class cmFileSet
{
public:
- cmFileSet(std::string name, std::string type,
+ cmFileSet(cmake& cmakeInstance, std::string name, std::string type,
cmFileSetVisibility visibility);
const std::string& GetName() const { return this->Name; }
@@ -77,6 +78,7 @@ public:
static bool IsValidName(const std::string& name);
private:
+ cmake& CMakeInstance;
std::string Name;
std::string Type;
cmFileSetVisibility Visibility;
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 3f8378b..71c7e13 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -377,6 +377,10 @@ private:
# pragma diag_suppress 1222 // invalid error number (3288, but works anyway)
# define CM_LCC_DIAG_SUPPRESS_3288
# pragma diag_suppress 3288 // parameter was declared but never referenced
+# define CM_LCC_DIAG_SUPPRESS_3301
+# pragma diag_suppress 3301 // parameter was declared but never referenced
+# define CM_LCC_DIAG_SUPPRESS_3308
+# pragma diag_suppress 3308 // parameter was declared but never referenced
#endif
void ResetGenerator()
@@ -421,6 +425,16 @@ bool TryGeneratedPaths(CallbackFn&& filesCollector,
return false;
}
+#ifdef CM_LCC_DIAG_SUPPRESS_3308
+# undef CM_LCC_DIAG_SUPPRESS_3308
+# pragma diag_default 3308
+#endif
+
+#ifdef CM_LCC_DIAG_SUPPRESS_3301
+# undef CM_LCC_DIAG_SUPPRESS_3301
+# pragma diag_default 3301
+#endif
+
#ifdef CM_LCC_DIAG_SUPPRESS_3288
# undef CM_LCC_DIAG_SUPPRESS_3288
# pragma diag_default 3288
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index c72d6a7..133bf5f 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -27,7 +27,7 @@ cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding)
cmGeneratedFileStream::cmGeneratedFileStream(std::string const& name,
bool quiet, Encoding encoding)
: cmGeneratedFileStreamBase(name)
- , Stream(this->TempName.c_str())
+ , Stream(this->TempName.c_str()) // NOLINT(cmake-use-cmsys-fstream)
{
// Check if the file opened.
if (!*this && !quiet) {
@@ -67,10 +67,11 @@ cmGeneratedFileStream& cmGeneratedFileStream::Open(std::string const& name,
// Open the temporary output file.
if (binaryFlag) {
- this->Stream::open(this->TempName.c_str(),
- std::ios::out | std::ios::binary);
+ this->Stream::open( // NOLINT(cmake-use-cmsys-fstream)
+ this->TempName.c_str(), std::ios::out | std::ios::binary);
} else {
- this->Stream::open(this->TempName.c_str());
+ this->Stream::open( // NOLINT(cmake-use-cmsys-fstream)
+ this->TempName.c_str());
}
// Check if the file opened.
@@ -87,7 +88,7 @@ bool cmGeneratedFileStream::Close()
this->Okay = !this->fail();
// Close the temporary output file.
- this->Stream::close();
+ this->Stream::close(); // NOLINT(cmake-use-cmsys-fstream)
// Remove the temporary file (possibly by renaming to the real file).
return this->cmGeneratedFileStreamBase::Close();
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index f988e54..c5ae31b 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGeneratorExpression.h"
+#include <algorithm>
#include <cassert>
#include <memory>
#include <utility>
@@ -13,11 +14,15 @@
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorExpressionLexer.h"
#include "cmGeneratorExpressionParser.h"
+#include "cmLocalGenerator.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmake.h"
-cmGeneratorExpression::cmGeneratorExpression(cmListFileBacktrace backtrace)
- : Backtrace(std::move(backtrace))
+cmGeneratorExpression::cmGeneratorExpression(cmake& cmakeInstance,
+ cmListFileBacktrace backtrace)
+ : CMakeInstance(cmakeInstance)
+ , Backtrace(std::move(backtrace))
{
}
@@ -29,7 +34,8 @@ std::unique_ptr<cmCompiledGeneratorExpression> cmGeneratorExpression::Parse(
std::string input) const
{
return std::unique_ptr<cmCompiledGeneratorExpression>(
- new cmCompiledGeneratorExpression(this->Backtrace, std::move(input)));
+ new cmCompiledGeneratorExpression(this->CMakeInstance, this->Backtrace,
+ std::move(input)));
}
std::string cmGeneratorExpression::Evaluate(
@@ -39,7 +45,13 @@ std::string cmGeneratorExpression::Evaluate(
cmGeneratorTarget const* currentTarget, std::string const& language)
{
if (Find(input) != std::string::npos) {
- cmCompiledGeneratorExpression cge(cmListFileBacktrace(), std::move(input));
+#ifndef CMAKE_BOOTSTRAP
+ auto profilingRAII = lg->GetCMakeInstance()->CreateProfilingEntry(
+ "genex_compile_eval", input);
+#endif
+
+ cmCompiledGeneratorExpression cge(*lg->GetCMakeInstance(),
+ cmListFileBacktrace(), std::move(input));
return cge.Evaluate(lg, config, headTarget, dagChecker, currentTarget,
language);
}
@@ -97,10 +109,15 @@ const std::string& cmCompiledGeneratorExpression::EvaluateWithContext(
}
cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
- cmListFileBacktrace backtrace, std::string input)
+ cmake& cmakeInstance, cmListFileBacktrace backtrace, std::string input)
: Backtrace(std::move(backtrace))
, Input(std::move(input))
{
+#ifndef CMAKE_BOOTSTRAP
+ auto profilingRAII =
+ cmakeInstance.CreateProfilingEntry("genex_compile", this->Input);
+#endif
+
cmGeneratorExpressionLexer l;
std::vector<cmGeneratorExpressionToken> tokens = l.Tokenize(this->Input);
this->NeedsEvaluation = l.GetSawGeneratorExpression();
@@ -210,23 +227,33 @@ static std::string stripExportInterface(
while (true) {
std::string::size_type bPos = input.find("$<BUILD_INTERFACE:", lastPos);
std::string::size_type iPos = input.find("$<INSTALL_INTERFACE:", lastPos);
+ std::string::size_type lPos =
+ input.find("$<BUILD_LOCAL_INTERFACE:", lastPos);
- if (bPos == std::string::npos && iPos == std::string::npos) {
+ pos = std::min({ bPos, iPos, lPos });
+ if (pos == std::string::npos) {
break;
}
- if (bPos == std::string::npos) {
- pos = iPos;
- } else if (iPos == std::string::npos) {
- pos = bPos;
+ result += input.substr(lastPos, pos - lastPos);
+ enum class FoundGenex
+ {
+ BuildInterface,
+ InstallInterface,
+ BuildLocalInterface,
+ } foundGenex = FoundGenex::BuildInterface;
+ if (pos == bPos) {
+ foundGenex = FoundGenex::BuildInterface;
+ pos += cmStrLen("$<BUILD_INTERFACE:");
+ } else if (pos == iPos) {
+ foundGenex = FoundGenex::InstallInterface;
+ pos += cmStrLen("$<INSTALL_INTERFACE:");
+ } else if (pos == lPos) {
+ foundGenex = FoundGenex::BuildLocalInterface;
+ pos += cmStrLen("$<BUILD_LOCAL_INTERFACE:");
} else {
- pos = (bPos < iPos) ? bPos : iPos;
+ assert(false && "Invalid position found");
}
-
- result += input.substr(lastPos, pos - lastPos);
- const bool gotInstallInterface = input[pos + 2] == 'I';
- pos += gotInstallInterface ? sizeof("$<INSTALL_INTERFACE:") - 1
- : sizeof("$<BUILD_INTERFACE:") - 1;
nestingLevel = 1;
const char* c = input.c_str() + pos;
const char* const cStart = c;
@@ -242,10 +269,10 @@ static std::string stripExportInterface(
continue;
}
if (context == cmGeneratorExpression::BuildInterface &&
- !gotInstallInterface) {
+ foundGenex == FoundGenex::BuildInterface) {
result += input.substr(pos, c - cStart);
} else if (context == cmGeneratorExpression::InstallInterface &&
- gotInstallInterface) {
+ foundGenex == FoundGenex::InstallInterface) {
const std::string content = input.substr(pos, c - cStart);
if (resolveRelative) {
prefixItems(content, result, "${_IMPORT_PREFIX}/");
@@ -258,9 +285,18 @@ static std::string stripExportInterface(
}
const std::string::size_type traversed = (c - cStart) + 1;
if (!*c) {
- result += std::string(gotInstallInterface ? "$<INSTALL_INTERFACE:"
- : "$<BUILD_INTERFACE:") +
- input.substr(pos, traversed);
+ auto remaining = input.substr(pos, traversed);
+ switch (foundGenex) {
+ case FoundGenex::BuildInterface:
+ result = cmStrCat(result, "$<BUILD_INTERFACE:", remaining);
+ break;
+ case FoundGenex::InstallInterface:
+ result = cmStrCat(result, "$<INSTALL_INTERFACE:", remaining);
+ break;
+ case FoundGenex::BuildLocalInterface:
+ result = cmStrCat(result, "$<BUILD_LOCAL_INTERFACE:", remaining);
+ break;
+ }
}
pos += traversed;
lastPos = pos;
@@ -370,7 +406,7 @@ void cmGeneratorExpression::ReplaceInstallPrefix(
while ((pos = input.find("$<INSTALL_PREFIX>", lastPos)) !=
std::string::npos) {
- std::string::size_type endPos = pos + sizeof("$<INSTALL_PREFIX>") - 1;
+ std::string::size_type endPos = pos + cmStrLen("$<INSTALL_PREFIX>");
input.replace(pos, endPos - pos, replacement);
lastPos = endPos;
}
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index 188993f..e22b8ab 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -12,10 +12,11 @@
#include <vector>
#include "cmListFileCache.h"
+#include "cmLocalGenerator.h"
+class cmake;
class cmCompiledGeneratorExpression;
class cmGeneratorTarget;
-class cmLocalGenerator;
struct cmGeneratorExpressionContext;
struct cmGeneratorExpressionDAGChecker;
struct cmGeneratorExpressionEvaluator;
@@ -33,7 +34,8 @@ class cmGeneratorExpression
{
public:
/** Construct. */
- cmGeneratorExpression(cmListFileBacktrace backtrace = cmListFileBacktrace());
+ cmGeneratorExpression(cmake& cmakeInstance,
+ cmListFileBacktrace backtrace = cmListFileBacktrace());
~cmGeneratorExpression();
cmGeneratorExpression(cmGeneratorExpression const&) = delete;
@@ -82,6 +84,7 @@ public:
const std::string& replacement);
private:
+ cmake& CMakeInstance;
cmListFileBacktrace Backtrace;
};
@@ -152,7 +155,8 @@ private:
cmGeneratorExpressionContext& context,
cmGeneratorExpressionDAGChecker* dagChecker) const;
- cmCompiledGeneratorExpression(cmListFileBacktrace backtrace,
+ cmCompiledGeneratorExpression(cmake& cmakeInstance,
+ cmListFileBacktrace backtrace,
std::string input);
friend class cmGeneratorExpression;
@@ -184,7 +188,8 @@ public:
std::string config,
cmGeneratorTarget const* headTarget,
std::string language = std::string())
- : LocalGenerator(localGenerator)
+ : GeneratorExpression(*localGenerator->GetCMakeInstance())
+ , LocalGenerator(localGenerator)
, Config(std::move(config))
, HeadTarget(headTarget)
, Language(std::move(language))
diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx
index 8f3ed4d..817437e 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.cxx
+++ b/Source/cmGeneratorExpressionEvaluationFile.cxx
@@ -165,7 +165,7 @@ void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg)
}
cmListFileBacktrace lfbt = this->OutputFileExpr->GetBacktrace();
- cmGeneratorExpression contentGE(lfbt);
+ cmGeneratorExpression contentGE(*lg->GetCMakeInstance(), lfbt);
std::unique_ptr<cmCompiledGeneratorExpression> inputExpression =
contentGE.Parse(inputContent);
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index fec309c..b239408 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -4,8 +4,14 @@
#include <sstream>
+#ifndef CMAKE_BOOTSTRAP
+# include <cm3p/json/value.h>
+#endif
+
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionNode.h"
+#include "cmLocalGenerator.h"
+#include "cmake.h"
GeneratorExpressionContent::GeneratorExpressionContent(
const char* startContent, size_t length)
@@ -61,6 +67,12 @@ std::string GeneratorExpressionContent::Evaluate(
cmGeneratorExpressionContext* context,
cmGeneratorExpressionDAGChecker* dagChecker) const
{
+#ifndef CMAKE_BOOTSTRAP
+ auto evalProfilingRAII =
+ context->LG->GetCMakeInstance()->CreateProfilingEntry(
+ "genex_eval", this->GetOriginalExpression());
+#endif
+
std::string identifier;
{
for (const auto& pExprEval : this->IdentifierChildren) {
@@ -101,7 +113,24 @@ std::string GeneratorExpressionContent::Evaluate(
return std::string();
}
- return node->Evaluate(parameters, context, this, dagChecker);
+ {
+#ifndef CMAKE_BOOTSTRAP
+ auto execProfilingRAII =
+ context->LG->GetCMakeInstance()->CreateProfilingEntry(
+ "genex_exec", identifier, [&parameters]() -> Json::Value {
+ Json::Value args = Json::objectValue;
+ if (!parameters.empty()) {
+ args["genexArgs"] = Json::arrayValue;
+ for (auto const& parameter : parameters) {
+ args["genexArgs"].append(parameter);
+ }
+ }
+ return args;
+ });
+#endif
+
+ return node->Evaluate(parameters, context, this, dagChecker);
+ }
}
std::string GeneratorExpressionContent::EvaluateParameters(
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 45d5a83..e33ebd7 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -57,7 +57,7 @@ std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
cmGeneratorExpressionDAGChecker* dagChecker,
cmGeneratorTarget const* currentTarget)
{
- cmGeneratorExpression ge(context->Backtrace);
+ cmGeneratorExpression ge(*lg->GetCMakeInstance(), context->Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
cge->SetEvaluateForBuildsystem(context->EvaluateForBuildsystem);
cge->SetQuiet(context->Quiet);
@@ -114,6 +114,8 @@ static const struct OneNode buildInterfaceNode;
static const struct ZeroNode installInterfaceNode;
+static const struct OneNode buildLocalInterfaceNode;
+
struct BooleanOpNode : public cmGeneratorExpressionNode
{
BooleanOpNode(const char* op_, const char* successVal_,
@@ -1386,6 +1388,14 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
return "1";
}
}
+ } else if (!suffix.empty()) {
+ // There is no explicit mapping for the tested config, so use
+ // the configuration of the imported location that was selected.
+ for (auto const& param : parameters) {
+ if (cmStrCat('_', cmSystemTools::UpperCase(param)) == suffix) {
+ return "1";
+ }
+ }
}
}
}
@@ -1970,7 +1980,10 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
}
return std::string();
}
- target = context->LG->FindGeneratorTargetToUse(targetName);
+ cmLocalGenerator const* lg = context->CurrentTarget
+ ? context->CurrentTarget->GetLocalGenerator()
+ : context->LG;
+ target = lg->FindGeneratorTargetToUse(targetName);
if (!target) {
std::ostringstream e;
@@ -3320,6 +3333,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
{ "GENEX_EVAL", &genexEvalNode },
{ "BUILD_INTERFACE", &buildInterfaceNode },
{ "INSTALL_INTERFACE", &installInterfaceNode },
+ { "BUILD_LOCAL_INTERFACE", &buildLocalInterfaceNode },
{ "INSTALL_PREFIX", &installPrefixNode },
{ "JOIN", &joinNode },
{ "LINK_ONLY", &linkOnlyNode },
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 7d43eb1..d0d339d 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -241,15 +241,16 @@ private:
std::unique_ptr<
cmGeneratorTarget::
- TargetPropertyEntry> static CreateTargetPropertyEntry(const BT<std::
- string>&
+ TargetPropertyEntry> static CreateTargetPropertyEntry(cmake& cmakeInstance,
+ const BT<
+ std::string>&
propertyValue,
bool
evaluateForBuildsystem =
false)
{
if (cmGeneratorExpression::Find(propertyValue.Value) != std::string::npos) {
- cmGeneratorExpression ge(propertyValue.Backtrace);
+ cmGeneratorExpression ge(cmakeInstance, propertyValue.Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> cge =
ge.Parse(propertyValue.Value);
cge->SetEvaluateForBuildsystem(evaluateForBuildsystem);
@@ -262,12 +263,13 @@ std::unique_ptr<
}
static void CreatePropertyGeneratorExpressions(
- cmBTStringRange entries,
+ cmake& cmakeInstance, cmBTStringRange entries,
std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>>& items,
bool evaluateForBuildsystem = false)
{
for (auto const& entry : entries) {
- items.push_back(CreateTargetPropertyEntry(entry, evaluateForBuildsystem));
+ items.push_back(
+ CreateTargetPropertyEntry(cmakeInstance, entry, evaluateForBuildsystem));
}
}
@@ -343,29 +345,36 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
this->GlobalGenerator->ComputeTargetObjectDirectory(this);
- CreatePropertyGeneratorExpressions(t->GetIncludeDirectoriesEntries(),
+ CreatePropertyGeneratorExpressions(*lg->GetCMakeInstance(),
+ t->GetIncludeDirectoriesEntries(),
this->IncludeDirectoriesEntries);
- CreatePropertyGeneratorExpressions(t->GetCompileOptionsEntries(),
+ CreatePropertyGeneratorExpressions(*lg->GetCMakeInstance(),
+ t->GetCompileOptionsEntries(),
this->CompileOptionsEntries);
- CreatePropertyGeneratorExpressions(t->GetCompileFeaturesEntries(),
+ CreatePropertyGeneratorExpressions(*lg->GetCMakeInstance(),
+ t->GetCompileFeaturesEntries(),
this->CompileFeaturesEntries);
- CreatePropertyGeneratorExpressions(t->GetCompileDefinitionsEntries(),
+ CreatePropertyGeneratorExpressions(*lg->GetCMakeInstance(),
+ t->GetCompileDefinitionsEntries(),
this->CompileDefinitionsEntries);
- CreatePropertyGeneratorExpressions(t->GetLinkOptionsEntries(),
+ CreatePropertyGeneratorExpressions(*lg->GetCMakeInstance(),
+ t->GetLinkOptionsEntries(),
this->LinkOptionsEntries);
- CreatePropertyGeneratorExpressions(t->GetLinkDirectoriesEntries(),
+ CreatePropertyGeneratorExpressions(*lg->GetCMakeInstance(),
+ t->GetLinkDirectoriesEntries(),
this->LinkDirectoriesEntries);
- CreatePropertyGeneratorExpressions(t->GetPrecompileHeadersEntries(),
+ CreatePropertyGeneratorExpressions(*lg->GetCMakeInstance(),
+ t->GetPrecompileHeadersEntries(),
this->PrecompileHeadersEntries);
- CreatePropertyGeneratorExpressions(t->GetSourceEntries(),
- this->SourceEntries, true);
+ CreatePropertyGeneratorExpressions(
+ *lg->GetCMakeInstance(), t->GetSourceEntries(), this->SourceEntries, true);
this->PolicyMap = t->GetPolicyMap();
@@ -740,6 +749,12 @@ void cmGeneratorTarget::ClearSourcesCache()
this->VisitedConfigsForObjects.clear();
this->LinkImplMap.clear();
this->LinkImplUsageRequirementsOnlyMap.clear();
+ this->IncludeDirectoriesCache.clear();
+ this->CompileOptionsCache.clear();
+ this->CompileDefinitionsCache.clear();
+ this->PrecompileHeadersCache.clear();
+ this->LinkOptionsCache.clear();
+ this->LinkDirectoriesCache.clear();
}
void cmGeneratorTarget::ClearLinkInterfaceCache()
@@ -753,6 +768,7 @@ void cmGeneratorTarget::AddSourceCommon(const std::string& src, bool before)
this->SourceEntries.insert(
before ? this->SourceEntries.begin() : this->SourceEntries.end(),
CreateTargetPropertyEntry(
+ *this->LocalGenerator->GetCMakeInstance(),
BT<std::string>(src, this->Makefile->GetBacktrace()), true));
this->ClearSourcesCache();
}
@@ -780,6 +796,7 @@ void cmGeneratorTarget::AddIncludeDirectory(const std::string& src,
before ? this->IncludeDirectoriesEntries.begin()
: this->IncludeDirectoriesEntries.end(),
CreateTargetPropertyEntry(
+ *this->Makefile->GetCMakeInstance(),
BT<std::string>(src, this->Makefile->GetBacktrace()), true));
}
@@ -1653,7 +1670,8 @@ void AddObjectEntries(cmGeneratorTarget const* headTarget,
headTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely(
lib.Target);
std::string genex = "$<TARGET_OBJECTS:" + std::move(uniqueName) + ">";
- cmGeneratorExpression ge(lib.Backtrace);
+ cmGeneratorExpression ge(*headTarget->Makefile->GetCMakeInstance(),
+ lib.Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
cge->SetEvaluateForBuildsystem(true);
@@ -3708,6 +3726,24 @@ std::string cmGeneratorTarget::GetCreateRuleVariable(
return "";
}
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetClangTidyExportFixesDirectory(
+ const std::string& lang) const
+{
+ cmValue val =
+ this->GetProperty(cmStrCat(lang, "_CLANG_TIDY_EXPORT_FIXES_DIR"));
+ if (!cmNonempty(val)) {
+ return {};
+ }
+
+ std::string path = *val;
+ if (!cmSystemTools::FileIsFullPath(path)) {
+ path =
+ cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/', path);
+ }
+ return cmSystemTools::CollapseFullPath(path);
+}
+
namespace {
void processIncludeDirectories(cmGeneratorTarget const* tgt,
EvaluatedTargetPropertyEntries& entries,
@@ -3817,6 +3853,13 @@ void processIncludeDirectories(cmGeneratorTarget const* tgt,
std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
const std::string& config, const std::string& lang) const
{
+ ConfigAndLanguage cacheKey(config, lang);
+ {
+ auto it = this->IncludeDirectoriesCache.find(cacheKey);
+ if (it != this->IncludeDirectoriesCache.end()) {
+ return it->second;
+ }
+ }
std::vector<BT<std::string>> includes;
std::unordered_set<std::string> uniqueIncludes;
@@ -3891,6 +3934,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
processIncludeDirectories(this, entries, includes, uniqueIncludes,
debugIncludes);
+ this->IncludeDirectoriesCache.emplace(cacheKey, includes);
return includes;
}
@@ -4068,6 +4112,13 @@ void cmGeneratorTarget::GetCompileOptions(std::vector<std::string>& result,
std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions(
std::string const& config, std::string const& language) const
{
+ ConfigAndLanguage cacheKey(config, language);
+ {
+ auto it = this->CompileOptionsCache.find(cacheKey);
+ if (it != this->CompileOptionsCache.end()) {
+ return it->second;
+ }
+ }
std::vector<BT<std::string>> result;
std::unordered_set<std::string> uniqueOptions;
@@ -4094,6 +4145,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions(
processOptions(this, entries, result, uniqueOptions, debugOptions,
"compile options", OptionsParse::Shell);
+ CompileOptionsCache.emplace(cacheKey, result);
return result;
}
@@ -4155,6 +4207,13 @@ void cmGeneratorTarget::GetCompileDefinitions(
std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
std::string const& config, std::string const& language) const
{
+ ConfigAndLanguage cacheKey(config, language);
+ {
+ auto it = this->CompileDefinitionsCache.find(cacheKey);
+ if (it != this->CompileDefinitionsCache.end()) {
+ return it->second;
+ }
+ }
std::vector<BT<std::string>> list;
std::unordered_set<std::string> uniqueOptions;
@@ -4192,7 +4251,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
}
case cmPolicies::OLD: {
std::unique_ptr<TargetPropertyEntry> entry =
- CreateTargetPropertyEntry(*configProp);
+ CreateTargetPropertyEntry(
+ *this->LocalGenerator->GetCMakeInstance(), *configProp);
entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
this, config, language, &dagChecker, *entry));
} break;
@@ -4207,12 +4267,20 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
processOptions(this, entries, list, uniqueOptions, debugDefines,
"compile definitions", OptionsParse::None);
+ this->CompileDefinitionsCache.emplace(cacheKey, list);
return list;
}
std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
const std::string& config, const std::string& language) const
{
+ ConfigAndLanguage cacheKey(config, language);
+ {
+ auto it = this->PrecompileHeadersCache.find(cacheKey);
+ if (it != this->PrecompileHeadersCache.end()) {
+ return it->second;
+ }
+ }
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this, "PRECOMPILE_HEADERS",
@@ -4240,6 +4308,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
processOptions(this, entries, list, uniqueOptions, debugDefines,
"precompile headers", OptionsParse::None);
+ this->PrecompileHeadersCache.emplace(cacheKey, list);
return list;
}
@@ -4600,6 +4669,14 @@ void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result,
std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
std::string const& config, std::string const& language) const
{
+ ConfigAndLanguage cacheKey(
+ config, cmStrCat(language, this->IsDeviceLink() ? "-device" : ""));
+ {
+ auto it = this->LinkOptionsCache.find(cacheKey);
+ if (it != this->LinkOptionsCache.end()) {
+ return it->second;
+ }
+ }
std::vector<BT<std::string>> result;
std::unordered_set<std::string> uniqueOptions;
@@ -4677,7 +4754,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
// Last step: replace "LINKER:" prefixed elements by
// actual linker wrapper
- return this->ResolveLinkerWrapper(result, language);
+ result = this->ResolveLinkerWrapper(result, language);
+
+ this->LinkOptionsCache.emplace(cacheKey, result);
+ return result;
}
std::vector<BT<std::string>>& cmGeneratorTarget::ResolveLinkerWrapper(
@@ -4776,13 +4856,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions(
EvaluatedTargetPropertyEntries entries;
if (cmValue linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
- std::vector<std::string> options = cmExpandedList(*linkOptions);
- for (const auto& option : options) {
- std::unique_ptr<TargetPropertyEntry> entry =
- CreateTargetPropertyEntry(option);
- entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
- this, config, language, &dagChecker, *entry));
- }
+ std::unique_ptr<TargetPropertyEntry> entry = CreateTargetPropertyEntry(
+ *this->LocalGenerator->GetCMakeInstance(), *linkOptions);
+ entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
+ this, config, language, &dagChecker, *entry));
}
processOptions(this, entries, result, uniqueOptions, false,
"static library link options", OptionsParse::Shell);
@@ -4876,6 +4953,14 @@ void cmGeneratorTarget::GetLinkDirectories(std::vector<std::string>& result,
std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories(
std::string const& config, std::string const& language) const
{
+ ConfigAndLanguage cacheKey(
+ config, cmStrCat(language, this->IsDeviceLink() ? "-device" : ""));
+ {
+ auto it = this->LinkDirectoriesCache.find(cacheKey);
+ if (it != this->LinkDirectoriesCache.end()) {
+ return it->second;
+ }
+ }
std::vector<BT<std::string>> result;
std::unordered_set<std::string> uniqueDirectories;
@@ -4905,6 +4990,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories(
processLinkDirectories(this, entries, result, uniqueDirectories,
debugDirectories);
+ this->LinkDirectoriesCache.emplace(cacheKey, result);
return result;
}
@@ -4931,8 +5017,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends(
if (cmValue linkDepends = this->GetProperty("LINK_DEPENDS")) {
std::vector<std::string> depends = cmExpandedList(*linkDepends);
for (const auto& depend : depends) {
- std::unique_ptr<TargetPropertyEntry> entry =
- CreateTargetPropertyEntry(depend);
+ std::unique_ptr<TargetPropertyEntry> entry = CreateTargetPropertyEntry(
+ *this->LocalGenerator->GetCMakeInstance(), depend);
entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
this, config, language, &dagChecker, *entry));
}
@@ -5532,7 +5618,7 @@ cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const
} else if (cmHasLiteralPrefix(*location, "Resources/")) {
flags.Type = cmGeneratorTarget::SourceFileTypeDeepResource;
if (stripResources) {
- flags.MacFolder += strlen("Resources/");
+ flags.MacFolder += cmStrLen("Resources/");
}
} else {
flags.Type = cmGeneratorTarget::SourceFileTypeMacContent;
@@ -6705,7 +6791,7 @@ bool cmGeneratorTarget::IsLinkLookupScope(std::string const& n,
cmLocalGenerator const*& lg) const
{
if (cmHasLiteralPrefix(n, CMAKE_DIRECTORY_ID_SEP)) {
- cmDirectoryId const dirId = n.substr(sizeof(CMAKE_DIRECTORY_ID_SEP) - 1);
+ cmDirectoryId const dirId = n.substr(cmStrLen(CMAKE_DIRECTORY_ID_SEP));
if (dirId.String.empty()) {
lg = this->LocalGenerator;
return true;
@@ -6756,7 +6842,8 @@ void cmGeneratorTarget::ExpandLinkItems(
cmMakefile const* mf = this->LocalGenerator->GetMakefile();
LookupLinkItemScope scope{ this->LocalGenerator };
for (BT<std::string> const& entry : entries) {
- cmGeneratorExpression ge(entry.Backtrace);
+ cmGeneratorExpression ge(*this->LocalGenerator->GetCMakeInstance(),
+ entry.Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(entry.Value);
cge->SetEvaluateForBuildsystem(true);
std::vector<std::string> libs = cmExpandedList(
@@ -8195,7 +8282,8 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
break;
}
}
- cmGeneratorExpression ge(entry.Backtrace);
+ cmGeneratorExpression ge(*this->LocalGenerator->GetCMakeInstance(),
+ entry.Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> const cge =
ge.Parse(entry.Value);
cge->SetEvaluateForBuildsystem(true);
@@ -8515,9 +8603,14 @@ cmGeneratorTarget::ManagedType cmGeneratorTarget::CheckManagedType(
// lib
// 2. empty propval: add /clr as flag, mixed unmanaged/managed
// target, has import lib
- // 3. any value (safe,pure): add /clr:[propval] as flag, target with
+ // 3. netcore propval: add /clr:netcore as flag, mixed
+ // unmanaged/managed target, has import lib.
+ // 4. any value (safe,pure): add /clr:[propval] as flag, target with
// managed code only, no import lib
- return propval.empty() ? ManagedType::Mixed : ManagedType::Managed;
+ if (propval.empty() || propval == "netcore") {
+ return ManagedType::Mixed;
+ }
+ return ManagedType::Managed;
}
cmGeneratorTarget::ManagedType cmGeneratorTarget::GetManagedType(
@@ -8849,3 +8942,101 @@ void cmGeneratorTarget::CheckCxxModuleStatus(std::string const& config) const
}
}
}
+
+bool cmGeneratorTarget::NeedCxxModuleSupport(std::string const& lang,
+ std::string const& config) const
+{
+ if (lang != "CXX"_s) {
+ return false;
+ }
+ return this->HaveCxxModuleSupport(config) == Cxx20SupportLevel::Supported &&
+ this->GetGlobalGenerator()->CheckCxxModuleSupport();
+}
+
+bool cmGeneratorTarget::NeedDyndep(std::string const& lang,
+ std::string const& config) const
+{
+ return lang == "Fortran"_s || this->NeedCxxModuleSupport(lang, config);
+}
+
+cmFileSet const* cmGeneratorTarget::GetFileSetForSource(
+ std::string const& config, cmSourceFile const* sf) const
+{
+ this->BuildFileSetInfoCache(config);
+
+ auto const& path = sf->GetFullPath();
+ auto const& per_config = this->Configs[config];
+
+ auto const fsit = per_config.FileSetCache.find(path);
+ if (fsit == per_config.FileSetCache.end()) {
+ return nullptr;
+ }
+ return fsit->second;
+}
+
+bool cmGeneratorTarget::NeedDyndepForSource(std::string const& lang,
+ std::string const& config,
+ cmSourceFile const* sf) const
+{
+ bool const needDyndep = this->NeedDyndep(lang, config);
+ if (!needDyndep) {
+ return false;
+ }
+ auto const* fs = this->GetFileSetForSource(config, sf);
+ if (fs &&
+ (fs->GetType() == "CXX_MODULES"_s ||
+ fs->GetType() == "CXX_MODULE_HEADER_UNITS"_s)) {
+ return true;
+ }
+ auto const sfProp = sf->GetProperty("CXX_SCAN_FOR_MODULES");
+ if (sfProp.IsSet()) {
+ return sfProp.IsOn();
+ }
+ auto const tgtProp = this->GetProperty("CXX_SCAN_FOR_MODULES");
+ if (tgtProp.IsSet()) {
+ return tgtProp.IsOn();
+ }
+ return true;
+}
+
+void cmGeneratorTarget::BuildFileSetInfoCache(std::string const& config) const
+{
+ auto& per_config = this->Configs[config];
+
+ if (per_config.BuiltFileSetCache) {
+ return;
+ }
+
+ auto const* tgt = this->Target;
+
+ for (auto const& name : tgt->GetAllFileSetNames()) {
+ auto const* file_set = tgt->GetFileSet(name);
+ if (!file_set) {
+ tgt->GetMakefile()->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("Target \"", tgt->GetName(),
+ "\" is tracked to have file set \"", name,
+ "\", but it was not found."));
+ continue;
+ }
+
+ auto fileEntries = file_set->CompileFileEntries();
+ auto directoryEntries = file_set->CompileDirectoryEntries();
+ auto directories = file_set->EvaluateDirectoryEntries(
+ directoryEntries, this->LocalGenerator, config, this);
+
+ std::map<std::string, std::vector<std::string>> files;
+ for (auto const& entry : fileEntries) {
+ file_set->EvaluateFileEntry(directories, files, entry,
+ this->LocalGenerator, config, this);
+ }
+
+ for (auto const& it : files) {
+ for (auto const& filename : it.second) {
+ per_config.FileSetCache[filename] = file_set;
+ }
+ }
+ }
+
+ per_config.BuiltFileSetCache = true;
+}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 25e6a81..7fa662d 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -26,6 +26,7 @@
enum class cmBuildStep;
class cmComputeLinkInformation;
class cmCustomCommand;
+class cmFileSet;
class cmGlobalGenerator;
class cmLocalGenerator;
class cmMakefile;
@@ -489,6 +490,20 @@ public:
std::string GetCreateRuleVariable(std::string const& lang,
std::string const& config) const;
+ std::string GetClangTidyExportFixesDirectory(const std::string& lang) const;
+
+private:
+ using ConfigAndLanguage = std::pair<std::string, std::string>;
+ using ConfigAndLanguageToBTStrings =
+ std::map<ConfigAndLanguage, std::vector<BT<std::string>>>;
+ mutable ConfigAndLanguageToBTStrings IncludeDirectoriesCache;
+ mutable ConfigAndLanguageToBTStrings CompileOptionsCache;
+ mutable ConfigAndLanguageToBTStrings CompileDefinitionsCache;
+ mutable ConfigAndLanguageToBTStrings PrecompileHeadersCache;
+ mutable ConfigAndLanguageToBTStrings LinkOptionsCache;
+ mutable ConfigAndLanguageToBTStrings LinkDirectoriesCache;
+
+public:
/** Get the include directories for this target. */
std::vector<BT<std::string>> GetIncludeDirectories(
const std::string& config, const std::string& lang) const;
@@ -1229,4 +1244,21 @@ public:
// Check C++ module status for the target.
void CheckCxxModuleStatus(std::string const& config) const;
+
+ bool NeedCxxModuleSupport(std::string const& lang,
+ std::string const& config) const;
+ bool NeedDyndep(std::string const& lang, std::string const& config) const;
+ cmFileSet const* GetFileSetForSource(std::string const& config,
+ cmSourceFile const* sf) const;
+ bool NeedDyndepForSource(std::string const& lang, std::string const& config,
+ cmSourceFile const* sf) const;
+
+private:
+ void BuildFileSetInfoCache(std::string const& config) const;
+ struct InfoByConfig
+ {
+ bool BuiltFileSetCache = false;
+ std::map<std::string, cmFileSet const*> FileSetCache;
+ };
+ mutable std::map<std::string, InfoByConfig> Configs;
};
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 138d3f1..8471dfe 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -9,6 +9,8 @@
#include <utility>
#include <vector>
+#include <cm/optional>
+
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
#include "cmGeneratedFileStream.h"
@@ -411,9 +413,8 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
cmdLines.push_back("@echo off");
#endif
// Echo the custom command's comment text.
- const char* comment = ccg.GetComment();
- if (comment && *comment) {
- std::string echocmd = cmStrCat("echo ", comment);
+ if (cm::optional<std::string> comment = ccg.GetComment()) {
+ std::string echocmd = cmStrCat("echo ", *comment);
cmdLines.push_back(std::move(echocmd));
}
diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx
index 776ee40..2fd7f8a 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.cxx
+++ b/Source/cmGlobalBorlandMakefileGenerator.cxx
@@ -60,11 +60,10 @@ cmGlobalBorlandMakefileGenerator::CreateLocalGenerator(cmMakefile* mf)
return std::unique_ptr<cmLocalGenerator>(std::move(lg));
}
-void cmGlobalBorlandMakefileGenerator::GetDocumentation(
- cmDocumentationEntry& entry)
+cmDocumentationEntry cmGlobalBorlandMakefileGenerator::GetDocumentation()
{
- entry.Name = cmGlobalBorlandMakefileGenerator::GetActualName();
- entry.Brief = "Generates Borland makefiles.";
+ return { cmGlobalBorlandMakefileGenerator::GetActualName(),
+ "Generates Borland makefiles." };
}
std::vector<cmGlobalGenerator::GeneratedMakeCommand>
diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h
index a280b81..049d6ba 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.h
+++ b/Source/cmGlobalBorlandMakefileGenerator.h
@@ -13,7 +13,6 @@
class cmLocalGenerator;
class cmMakefile;
class cmake;
-struct cmDocumentationEntry;
/** \class cmGlobalBorlandMakefileGenerator
* \brief Write a Borland makefiles.
@@ -38,7 +37,7 @@ public:
static std::string GetActualName() { return "Borland Makefiles"; }
/** Get the documentation entry for this generator. */
- static void GetDocumentation(cmDocumentationEntry& entry);
+ static cmDocumentationEntry GetDocumentation();
//! Create a local generator appropriate to this Global Generator
std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx
index 3ae66f0..7a44452 100644
--- a/Source/cmGlobalCommonGenerator.cxx
+++ b/Source/cmGlobalCommonGenerator.cxx
@@ -2,11 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalCommonGenerator.h"
+#include <algorithm>
#include <memory>
#include <utility>
#include <cmext/algorithm>
+#include <cmsys/Glob.hxx>
+
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
@@ -14,6 +17,7 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
#include "cmake.h"
@@ -124,3 +128,23 @@ std::string cmGlobalCommonGenerator::GetEditCacheCommand() const
cmValue edit_cmd = cm->GetCacheDefinition("CMAKE_EDIT_COMMAND");
return edit_cmd ? *edit_cmd : std::string();
}
+
+void cmGlobalCommonGenerator::RemoveUnknownClangTidyExportFixesFiles() const
+{
+ for (auto const& dir : this->ClangTidyExportFixesDirs) {
+ cmsys::Glob g;
+ g.SetRecurse(true);
+ g.SetListDirs(false);
+ g.FindFiles(cmStrCat(dir, "/*.yaml"));
+ for (auto const& file : g.GetFiles()) {
+ if (!this->ClangTidyExportFixesFiles.count(file) &&
+ !std::any_of(this->ClangTidyExportFixesFiles.begin(),
+ this->ClangTidyExportFixesFiles.end(),
+ [&file](const std::string& knownFile) -> bool {
+ return cmSystemTools::SameFile(file, knownFile);
+ })) {
+ cmSystemTools::RemoveFile(file);
+ }
+ }
+ }
+}
diff --git a/Source/cmGlobalCommonGenerator.h b/Source/cmGlobalCommonGenerator.h
index fed9ce8..fa42674 100644
--- a/Source/cmGlobalCommonGenerator.h
+++ b/Source/cmGlobalCommonGenerator.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
+#include <set>
#include <string>
#include <vector>
@@ -42,9 +43,21 @@ public:
std::map<std::string, DirectoryTarget> ComputeDirectoryTargets() const;
bool IsExcludedFromAllInConfig(const DirectoryTarget::Target& t,
const std::string& config);
+ void AddClangTidyExportFixesDir(const std::string& dir)
+ {
+ this->ClangTidyExportFixesDirs.insert(dir);
+ }
+ void AddClangTidyExportFixesFile(const std::string& file)
+ {
+ this->ClangTidyExportFixesFiles.insert(file);
+ }
protected:
virtual bool SupportsDirectConsole() const { return true; }
const char* GetEditCacheTargetName() const override { return "edit_cache"; }
std::string GetEditCacheCommand() const override;
+
+ std::set<std::string> ClangTidyExportFixesDirs;
+ std::set<std::string> ClangTidyExportFixesFiles;
+ void RemoveUnknownClangTidyExportFixesFiles() const;
};
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index c2bf888..8ca6ee6 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -827,7 +827,8 @@ void cmGlobalGenerator::EnableLanguage(
"No " << compilerName << " could be found.\n"
;
/* clang-format on */
- } else if ((lang != "RC") && (lang != "ASM_MASM")) {
+ } else if ((lang != "RC") && (lang != "ASM_MARMASM") &&
+ (lang != "ASM_MASM")) {
if (!cmSystemTools::FileIsFullPath(*compilerFile)) {
/* clang-format off */
noCompiler <<
@@ -1438,6 +1439,19 @@ bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const
return false;
}
+void cmGlobalGenerator::CxxModuleSupportCheck() const
+{
+ bool const diagnose = !this->DiagnosedCxxModuleSupport &&
+ !this->CMakeInstance->GetIsInTryCompile();
+ if (diagnose) {
+ this->DiagnosedCxxModuleSupport = true;
+ this->GetCMakeInstance()->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ "C++20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP "
+ "is experimental. It is meant only for compiler developers to try.");
+ }
+}
+
void cmGlobalGenerator::ComputeBuildFileGenerators()
{
for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) {
@@ -1596,6 +1610,8 @@ void cmGlobalGenerator::Generate()
// it builds by default.
this->InitializeProgressMarks();
+ this->DiagnosedCxxModuleSupport = false;
+
this->ProcessEvaluationFiles();
this->CMakeInstance->UpdateProgress("Generating", 0.1f);
@@ -2943,19 +2959,18 @@ std::string cmGlobalGenerator::GetPredefinedTargetsFolder() const
bool cmGlobalGenerator::UseFolderProperty() const
{
- cmValue prop =
+ const cmValue prop =
this->GetCMakeInstance()->GetState()->GetGlobalProperty("USE_FOLDERS");
- // If this property is defined, let the setter turn this on or off...
- //
+ // If this property is defined, let the setter turn this on or off.
if (prop) {
return cmIsOn(*prop);
}
- // By default, this feature is OFF, since it is not supported in the
- // Visual Studio Express editions until VS11:
- //
- return false;
+ // If CMP0143 is NEW `treat` "USE_FOLDERS" as ON. Otherwise `treat` it as OFF
+ assert(!this->Makefiles.empty());
+ return (this->Makefiles[0]->GetPolicyStatus(cmPolicies::CMP0143) ==
+ cmPolicies::NEW);
}
void cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti,
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 076b041..66ab752 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -157,6 +157,8 @@ public:
virtual bool InspectConfigTypeVariables() { return true; }
+ virtual bool CheckCxxModuleSupport() { return false; }
+
bool Compute();
virtual void AddExtraIDETargets() {}
@@ -621,6 +623,8 @@ protected:
virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const;
+ void CxxModuleSupportCheck() const;
+
/// @brief Qt AUTOMOC/UIC/RCC target generation
/// @return true on success
bool QtAutoGen();
@@ -728,6 +732,8 @@ private:
std::map<std::string, int> LanguageToLinkerPreference;
std::map<std::string, std::string> LanguageToOriginalSharedLibFlags;
+ mutable bool DiagnosedCxxModuleSupport = false;
+
// Deferral id generation.
size_t NextDeferId = 0;
diff --git a/Source/cmGlobalGeneratorFactory.h b/Source/cmGlobalGeneratorFactory.h
index d6ababb..a935079 100644
--- a/Source/cmGlobalGeneratorFactory.h
+++ b/Source/cmGlobalGeneratorFactory.h
@@ -4,6 +4,10 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include "cmDocumentationEntry.h" // IWYU pragma: export
+
+// TODO The following headers are parts of the `cmGlobalGeneratorFactory`
+// public API, so could be defined as export to IWYU
#include <string>
#include <vector>
@@ -11,7 +15,6 @@
class cmGlobalGenerator;
class cmake;
-struct cmDocumentationEntry;
/** \class cmGlobalGeneratorFactory
* \brief Responable for creating cmGlobalGenerator instances
@@ -28,7 +31,7 @@ public:
const std::string& n, bool allowArch, cmake* cm) const = 0;
/** Get the documentation entry for this factory */
- virtual void GetDocumentation(cmDocumentationEntry& entry) const = 0;
+ virtual cmDocumentationEntry GetDocumentation() const = 0;
/** Get the names of the current registered generators */
virtual std::vector<std::string> GetGeneratorNames() const = 0;
@@ -47,7 +50,7 @@ public:
virtual std::string GetDefaultPlatformName() const = 0;
};
-template <class T>
+template <typename T>
class cmGlobalGeneratorSimpleFactory : public cmGlobalGeneratorFactory
{
public:
@@ -62,21 +65,19 @@ public:
}
/** Get the documentation entry for this factory */
- void GetDocumentation(cmDocumentationEntry& entry) const override
+ cmDocumentationEntry GetDocumentation() const override
{
- T::GetDocumentation(entry);
+ return T::GetDocumentation();
}
/** Get the names of the current registered generators */
std::vector<std::string> GetGeneratorNames() const override
{
- std::vector<std::string> names;
- names.push_back(T::GetActualName());
- return names;
+ return { T::GetActualName() };
}
std::vector<std::string> GetGeneratorNamesWithPlatform() const override
{
- return std::vector<std::string>();
+ return {};
}
/** Determine whether or not this generator supports toolsets */
@@ -89,8 +90,8 @@ public:
std::vector<std::string> GetKnownPlatforms() const override
{
// default is no platform supported
- return std::vector<std::string>();
+ return {};
}
- std::string GetDefaultPlatformName() const override { return std::string(); }
+ std::string GetDefaultPlatformName() const override { return {}; }
};
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 9c334a5..18c48d7 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -15,7 +15,6 @@
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
-#include "cmDocumentationEntry.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGhsMultiGpj.h"
@@ -58,11 +57,12 @@ cmGlobalGhsMultiGenerator::CreateLocalGenerator(cmMakefile* mf)
cm::make_unique<cmLocalGhsMultiGenerator>(this, mf));
}
-void cmGlobalGhsMultiGenerator::GetDocumentation(cmDocumentationEntry& entry)
+cmDocumentationEntry cmGlobalGhsMultiGenerator::GetDocumentation()
{
- entry.Name = GetActualName();
- entry.Brief =
- "Generates Green Hills MULTI files (experimental, work-in-progress).";
+ return {
+ GetActualName(),
+ "Generates Green Hills MULTI files (experimental, work-in-progress)."
+ };
}
void cmGlobalGhsMultiGenerator::ComputeTargetObjectDirectory(
diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h
index aa68d3b..4a79610 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -18,7 +18,6 @@ class cmGeneratorTarget;
class cmLocalGenerator;
class cmMakefile;
class cmake;
-struct cmDocumentationEntry;
class cmGlobalGhsMultiGenerator : public cmGlobalGenerator
{
@@ -46,7 +45,7 @@ public:
std::string GetName() const override { return GetActualName(); }
/// Overloaded methods. @see cmGlobalGenerator::GetDocumentation()
- static void GetDocumentation(cmDocumentationEntry& entry);
+ static cmDocumentationEntry GetDocumentation();
/**
* Utilized by the generator factory to determine if this generator
diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx
index 1a625cc..f1d4d09 100644
--- a/Source/cmGlobalJOMMakefileGenerator.cxx
+++ b/Source/cmGlobalJOMMakefileGenerator.cxx
@@ -6,7 +6,6 @@
#include <cmext/algorithm>
-#include "cmDocumentationEntry.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
@@ -36,11 +35,10 @@ void cmGlobalJOMMakefileGenerator::EnableLanguage(
this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
}
-void cmGlobalJOMMakefileGenerator::GetDocumentation(
- cmDocumentationEntry& entry)
+cmDocumentationEntry cmGlobalJOMMakefileGenerator::GetDocumentation()
{
- entry.Name = cmGlobalJOMMakefileGenerator::GetActualName();
- entry.Brief = "Generates JOM makefiles.";
+ return { cmGlobalJOMMakefileGenerator::GetActualName(),
+ "Generates JOM makefiles." };
}
void cmGlobalJOMMakefileGenerator::PrintCompilerAdvice(std::ostream& os,
diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h
index 332d1cf..5e74875 100644
--- a/Source/cmGlobalJOMMakefileGenerator.h
+++ b/Source/cmGlobalJOMMakefileGenerator.h
@@ -13,7 +13,6 @@
class cmMakefile;
class cmake;
-struct cmDocumentationEntry;
/** \class cmGlobalJOMMakefileGenerator
* \brief Write a JOM makefiles.
@@ -39,7 +38,7 @@ public:
static std::string GetActualName() { return "NMake Makefiles JOM"; }
/** Get the documentation entry for this generator. */
- static void GetDocumentation(cmDocumentationEntry& entry);
+ static cmDocumentationEntry GetDocumentation();
/**
* Try to determine system information such as shared library
diff --git a/Source/cmGlobalMSYSMakefileGenerator.cxx b/Source/cmGlobalMSYSMakefileGenerator.cxx
index d4ff1e0..e543aea 100644
--- a/Source/cmGlobalMSYSMakefileGenerator.cxx
+++ b/Source/cmGlobalMSYSMakefileGenerator.cxx
@@ -4,7 +4,6 @@
#include "cmsys/FStream.hxx"
-#include "cmDocumentationEntry.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
@@ -53,9 +52,8 @@ void cmGlobalMSYSMakefileGenerator::EnableLanguage(
}
}
-void cmGlobalMSYSMakefileGenerator::GetDocumentation(
- cmDocumentationEntry& entry)
+cmDocumentationEntry cmGlobalMSYSMakefileGenerator::GetDocumentation()
{
- entry.Name = cmGlobalMSYSMakefileGenerator::GetActualName();
- entry.Brief = "Generates MSYS makefiles.";
+ return { cmGlobalMSYSMakefileGenerator::GetActualName(),
+ "Generates MSYS makefiles." };
}
diff --git a/Source/cmGlobalMSYSMakefileGenerator.h b/Source/cmGlobalMSYSMakefileGenerator.h
index 586487f..ee9a4ee 100644
--- a/Source/cmGlobalMSYSMakefileGenerator.h
+++ b/Source/cmGlobalMSYSMakefileGenerator.h
@@ -11,7 +11,6 @@
class cmMakefile;
class cmake;
-struct cmDocumentationEntry;
/** \class cmGlobalMSYSMakefileGenerator
* \brief Write a NMake makefiles.
@@ -29,21 +28,21 @@ public:
}
//! Get the name for the generator.
- virtual std::string GetName() const
+ std::string GetName() const override
{
return cmGlobalMSYSMakefileGenerator::GetActualName();
}
static std::string GetActualName() { return "MSYS Makefiles"; }
/** Get the documentation entry for this generator. */
- static void GetDocumentation(cmDocumentationEntry& entry);
+ static cmDocumentationEntry GetDocumentation();
/**
* Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
- virtual void EnableLanguage(std::vector<std::string> const& languages,
- cmMakefile*, bool optional);
+ void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
+ bool optional) override;
private:
std::string FindMinGW(std::string const& makeloc);
diff --git a/Source/cmGlobalMinGWMakefileGenerator.cxx b/Source/cmGlobalMinGWMakefileGenerator.cxx
index 5a7edae..a0a52d3 100644
--- a/Source/cmGlobalMinGWMakefileGenerator.cxx
+++ b/Source/cmGlobalMinGWMakefileGenerator.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalMinGWMakefileGenerator.h"
-#include "cmDocumentationEntry.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmSystemTools.h"
@@ -19,9 +18,8 @@ cmGlobalMinGWMakefileGenerator::cmGlobalMinGWMakefileGenerator(cmake* cm)
cm->GetState()->SetMinGWMake(true);
}
-void cmGlobalMinGWMakefileGenerator::GetDocumentation(
- cmDocumentationEntry& entry)
+cmDocumentationEntry cmGlobalMinGWMakefileGenerator::GetDocumentation()
{
- entry.Name = cmGlobalMinGWMakefileGenerator::GetActualName();
- entry.Brief = "Generates a make file for use with mingw32-make.";
+ return { cmGlobalMinGWMakefileGenerator::GetActualName(),
+ "Generates a make file for use with mingw32-make." };
}
diff --git a/Source/cmGlobalMinGWMakefileGenerator.h b/Source/cmGlobalMinGWMakefileGenerator.h
index 92d495c..7dd968b 100644
--- a/Source/cmGlobalMinGWMakefileGenerator.h
+++ b/Source/cmGlobalMinGWMakefileGenerator.h
@@ -11,7 +11,6 @@
class cmMakefile;
class cmake;
-struct cmDocumentationEntry;
/** \class cmGlobalMinGWMakefileGenerator
* \brief Write a NMake makefiles.
@@ -28,12 +27,12 @@ public:
new cmGlobalGeneratorSimpleFactory<cmGlobalMinGWMakefileGenerator>());
}
//! Get the name for the generator.
- virtual std::string GetName() const
+ std::string GetName() const override
{
return cmGlobalMinGWMakefileGenerator::GetActualName();
}
static std::string GetActualName() { return "MinGW Makefiles"; }
/** Get the documentation entry for this generator. */
- static void GetDocumentation(cmDocumentationEntry& entry);
+ static cmDocumentationEntry GetDocumentation();
};
diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx
index eabacf6..cb53850 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.cxx
+++ b/Source/cmGlobalNMakeMakefileGenerator.cxx
@@ -8,7 +8,6 @@
#include "cmsys/RegularExpression.hxx"
-#include "cmDocumentationEntry.h"
#include "cmDuration.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
@@ -80,11 +79,10 @@ void cmGlobalNMakeMakefileGenerator::CheckNMakeFeatures()
cmSystemTools::OP_LESS, this->NMakeVersion, "9");
}
-void cmGlobalNMakeMakefileGenerator::GetDocumentation(
- cmDocumentationEntry& entry)
+cmDocumentationEntry cmGlobalNMakeMakefileGenerator::GetDocumentation()
{
- entry.Name = cmGlobalNMakeMakefileGenerator::GetActualName();
- entry.Brief = "Generates NMake makefiles.";
+ return { cmGlobalNMakeMakefileGenerator::GetActualName(),
+ "Generates NMake makefiles." };
}
void cmGlobalNMakeMakefileGenerator::PrintCompilerAdvice(
@@ -128,12 +126,8 @@ void cmGlobalNMakeMakefileGenerator::PrintBuildCommandAdvice(std::ostream& os,
if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
// nmake does not support parallel build level
// see https://msdn.microsoft.com/en-us/library/afyyse50.aspx
-
- /* clang-format off */
- os <<
- "Warning: NMake does not support parallel builds. "
- "Ignoring parallel build command line option.\n";
- /* clang-format on */
+ os << "Warning: NMake does not support parallel builds. "
+ "Ignoring parallel build command line option.\n";
}
this->cmGlobalUnixMakefileGenerator3::PrintBuildCommandAdvice(
diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h
index b3574eb..436ebca 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.h
+++ b/Source/cmGlobalNMakeMakefileGenerator.h
@@ -15,7 +15,6 @@
class cmMakefile;
class cmake;
-struct cmDocumentationEntry;
/** \class cmGlobalNMakeMakefileGenerator
* \brief Write a NMake makefiles.
@@ -45,7 +44,7 @@ public:
}
/** Get the documentation entry for this generator. */
- static void GetDocumentation(cmDocumentationEntry& entry);
+ static cmDocumentationEntry GetDocumentation();
/**
* Try to determine system information such as shared library
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 077de42..c24b1e3 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -25,8 +25,7 @@
#include "cmsys/FStream.hxx"
#include "cmCxxModuleMapper.h"
-#include "cmDocumentationEntry.h"
-#include "cmFileSet.h"
+#include "cmDyndepCollation.h"
#include "cmFortranParser.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpressionEvaluationFile.h"
@@ -554,10 +553,10 @@ codecvt::Encoding cmGlobalNinjaGenerator::GetMakefileEncoding() const
return this->NinjaExpectedEncoding;
}
-void cmGlobalNinjaGenerator::GetDocumentation(cmDocumentationEntry& entry)
+cmDocumentationEntry cmGlobalNinjaGenerator::GetDocumentation()
{
- entry.Name = cmGlobalNinjaGenerator::GetActualName();
- entry.Brief = "Generates build.ninja files.";
+ return { cmGlobalNinjaGenerator::GetActualName(),
+ "Generates build.ninja files." };
}
// Implemented in all cmGlobaleGenerator sub-classes.
@@ -592,7 +591,9 @@ void cmGlobalNinjaGenerator::Generate()
this->TargetAll = this->NinjaOutputPath("all");
this->CMakeCacheFile = this->NinjaOutputPath("CMakeCache.txt");
this->DisableCleandead = false;
- this->DiagnosedCxxModuleSupport = false;
+ this->DiagnosedCxxModuleNinjaSupport = false;
+ this->ClangTidyExportFixesDirs.clear();
+ this->ClangTidyExportFixesFiles.clear();
this->PolicyCMP0058 =
this->LocalGenerators[0]->GetMakefile()->GetPolicyStatus(
@@ -633,6 +634,8 @@ void cmGlobalNinjaGenerator::Generate()
{
this->CleanMetaData();
}
+
+ this->RemoveUnknownClangTidyExportFixesFiles();
}
void cmGlobalNinjaGenerator::CleanMetaData()
@@ -851,18 +854,12 @@ bool cmGlobalNinjaGenerator::CheckLanguages(
bool cmGlobalNinjaGenerator::CheckCxxModuleSupport()
{
- bool const diagnose = !this->DiagnosedCxxModuleSupport &&
- !this->CMakeInstance->GetIsInTryCompile();
- if (diagnose) {
- this->DiagnosedCxxModuleSupport = true;
- this->GetCMakeInstance()->IssueMessage(
- MessageType::AUTHOR_WARNING,
- "C++20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP "
- "is experimental. It is meant only for compiler developers to try.");
- }
+ this->CxxModuleSupportCheck();
if (this->NinjaSupportsDyndeps) {
return true;
}
+ bool const diagnose = !this->DiagnosedCxxModuleNinjaSupport &&
+ !this->CMakeInstance->GetIsInTryCompile();
if (diagnose) {
std::ostringstream e;
/* clang-format off */
@@ -1171,7 +1168,8 @@ void cmGlobalNinjaGenerator::AddAdditionalCleanFile(std::string fileName,
}
void cmGlobalNinjaGenerator::AddCXXCompileCommand(
- const std::string& commandLine, const std::string& sourceFile)
+ const std::string& commandLine, const std::string& sourceFile,
+ const std::string& objPath)
{
// Compute Ninja's build file path.
std::string buildFileDir =
@@ -1205,7 +1203,9 @@ void cmGlobalNinjaGenerator::AddCXXCompileCommand(
<< R"( "command": ")"
<< cmGlobalGenerator::EscapeJSON(commandLine) << "\",\n"
<< R"( "file": ")"
- << cmGlobalGenerator::EscapeJSON(sourceFileName) << "\"\n"
+ << cmGlobalGenerator::EscapeJSON(sourceFileName) << "\",\n"
+ << R"( "output": ")"
+ << cmGlobalGenerator::EscapeJSON(objPath) << "\"\n"
<< "}";
/* clang-format on */
}
@@ -1254,7 +1254,7 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
const std::string& config, cmNinjaTargetDepends depends) const
{
- // for frameworks, we want the real name, not smple name
+ // for frameworks, we want the real name, not sample name
// frameworks always appear versioned, and the build.ninja
// will always attempt to manage symbolic links instead
// of letting cmOSXBundleGenerator do it.
@@ -2098,6 +2098,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
}
std::vector<std::string> byproducts;
+ byproducts.reserve(this->CrossConfigs.size());
for (auto const& config : this->CrossConfigs) {
byproducts.push_back(
this->BuildAlias(GetByproductsForCleanTargetName(), config));
@@ -2472,45 +2473,6 @@ cm::optional<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
}
}
-struct CxxModuleFileSet
-{
- std::string Name;
- std::string RelativeDirectory;
- std::string SourcePath;
- std::string Type;
- cmFileSetVisibility Visibility;
- cm::optional<std::string> Destination;
-};
-
-struct CxxModuleBmiInstall
-{
- std::string Component;
- std::string Destination;
- bool ExcludeFromAll;
- bool Optional;
- std::string Permissions;
- std::string MessageLevel;
- std::string ScriptLocation;
-};
-
-struct CxxModuleExport
-{
- std::string Name;
- std::string Destination;
- std::string Prefix;
- std::string CxxModuleInfoDir;
- std::string Namespace;
- bool Install;
-};
-
-struct cmGlobalNinjaGenerator::CxxModuleExportInfo
-{
- std::map<std::string, CxxModuleFileSet> ObjectToFileSet;
- cm::optional<CxxModuleBmiInstall> BmiInstallation;
- std::vector<CxxModuleExport> Exports;
- std::string Config;
-};
-
bool cmGlobalNinjaGenerator::WriteDyndepFile(
std::string const& dir_top_src, std::string const& dir_top_bld,
std::string const& dir_cur_src, std::string const& dir_cur_bld,
@@ -2518,7 +2480,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
std::string const& module_dir,
std::vector<std::string> const& linked_target_dirs,
std::string const& arg_lang, std::string const& arg_modmapfmt,
- CxxModuleExportInfo const& export_info)
+ cmCxxModuleExportInfo const& export_info)
{
// Setup path conversions.
{
@@ -2610,6 +2572,8 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
cm::optional<CxxModuleMapFormat> modmap_fmt;
if (arg_modmapfmt.empty()) {
// nothing to do.
+ } else if (arg_modmapfmt == "clang") {
+ modmap_fmt = CxxModuleMapFormat::Clang;
} else if (arg_modmapfmt == "gcc") {
modmap_fmt = CxxModuleMapFormat::Gcc;
} else if (arg_modmapfmt == "msvc") {
@@ -2753,279 +2717,18 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
cmGeneratedFileStream tmf(target_mods_file);
tmf << target_module_info;
- bool result = true;
-
- // Fortran doesn't support any of the file-set or BMI installation considered
- // below.
- if (arg_lang != "Fortran"_s) {
- // Prepare the export information blocks.
- std::string const config_upper =
- cmSystemTools::UpperCase(export_info.Config);
- std::vector<std::pair<std::unique_ptr<cmGeneratedFileStream>,
- CxxModuleExport const*>>
- exports;
- for (auto const& exp : export_info.Exports) {
- std::unique_ptr<cmGeneratedFileStream> properties;
-
- std::string const export_dir =
- cmStrCat(exp.Prefix, '/', exp.CxxModuleInfoDir, '/');
- std::string const property_file_path = cmStrCat(
- export_dir, "target-", exp.Name, '-', export_info.Config, ".cmake");
- properties = cm::make_unique<cmGeneratedFileStream>(property_file_path);
-
- // Set up the preamble.
- *properties << "set_property(TARGET \"" << exp.Namespace << exp.Name
- << "\"\n"
- << " PROPERTY IMPORTED_CXX_MODULES_" << config_upper
- << '\n';
-
- exports.emplace_back(std::move(properties), &exp);
+ cmDyndepMetadataCallbacks cb;
+ cb.ModuleFile =
+ [mod_files](std::string const& name) -> cm::optional<std::string> {
+ auto m = mod_files.find(name);
+ if (m != mod_files.end()) {
+ return m->second;
}
+ return {};
+ };
- std::unique_ptr<cmGeneratedFileStream> bmi_install_script;
- if (export_info.BmiInstallation) {
- bmi_install_script = cm::make_unique<cmGeneratedFileStream>(
- export_info.BmiInstallation->ScriptLocation);
- }
-
- auto cmEscape = [](cm::string_view str) {
- return cmOutputConverter::EscapeForCMake(
- str, cmOutputConverter::WrapQuotes::NoWrap);
- };
- auto install_destination =
- [&cmEscape](std::string const& dest) -> std::pair<bool, std::string> {
- if (cmSystemTools::FileIsFullPath(dest)) {
- return std::make_pair(true, cmEscape(dest));
- }
- return std::make_pair(false,
- cmStrCat("${_IMPORT_PREFIX}/", cmEscape(dest)));
- };
-
- // public/private requirement tracking.
- std::set<std::string> private_modules;
- std::map<std::string, std::set<std::string>> public_source_requires;
-
- for (cmScanDepInfo const& object : objects) {
- // Convert to forward slashes.
- auto output_path = object.PrimaryOutput;
-# ifdef _WIN32
- cmSystemTools::ConvertToUnixSlashes(output_path);
-# endif
- // Find the fileset for this object.
- auto fileset_info_itr = export_info.ObjectToFileSet.find(output_path);
- bool const has_provides = !object.Provides.empty();
- if (fileset_info_itr == export_info.ObjectToFileSet.end()) {
- // If it provides anything, it should have a `CXX_MODULES` or
- // `CXX_MODULE_INTERNAL_PARTITIONS` type and be present.
- if (has_provides) {
- // Take the first module provided to provide context.
- auto const& provides = object.Provides[0];
- char const* ok_types = "`CXX_MODULES`";
- if (provides.LogicalName.find(':') != std::string::npos) {
- ok_types = "`CXX_MODULES` (or `CXX_MODULE_INTERNAL_PARTITIONS` if "
- "it is not `export`ed)";
- }
- cmSystemTools::Error(
- cmStrCat("Output ", object.PrimaryOutput, " provides the `",
- provides.LogicalName,
- "` module but it is not found in a `FILE_SET` of type ",
- ok_types));
- result = false;
- }
-
- // This object file does not provide anything, so nothing more needs to
- // be done.
- continue;
- }
-
- auto const& file_set = fileset_info_itr->second;
-
- // Verify the fileset type for the object.
- if (file_set.Type == "CXX_MODULES"_s) {
- if (!has_provides) {
- cmSystemTools::Error(cmStrCat(
- "Output ", object.PrimaryOutput,
- " is of type `CXX_MODULES` but does not provide a module"));
- result = false;
- continue;
- }
- } else if (file_set.Type == "CXX_MODULE_INTERNAL_PARTITIONS"_s) {
- if (!has_provides) {
- cmSystemTools::Error(cmStrCat(
- "Source ", file_set.SourcePath,
- " is of type `CXX_MODULE_INTERNAL_PARTITIONS` but does not "
- "provide a module"));
- result = false;
- continue;
- }
- auto const& provides = object.Provides[0];
- if (provides.LogicalName.find(':') == std::string::npos) {
- cmSystemTools::Error(cmStrCat(
- "Source ", file_set.SourcePath,
- " is of type `CXX_MODULE_INTERNAL_PARTITIONS` but does not "
- "provide a module partition"));
- result = false;
- continue;
- }
- } else if (file_set.Type == "CXX_MODULE_HEADERS"_s) {
- // TODO.
- } else {
- if (has_provides) {
- auto const& provides = object.Provides[0];
- char const* ok_types = "`CXX_MODULES`";
- if (provides.LogicalName.find(':') != std::string::npos) {
- ok_types = "`CXX_MODULES` (or `CXX_MODULE_INTERNAL_PARTITIONS` if "
- "it is not `export`ed)";
- }
- cmSystemTools::Error(cmStrCat(
- "Source ", file_set.SourcePath, " provides the `",
- provides.LogicalName, "` C++ module but is of type `",
- file_set.Type, "` module but must be of type ", ok_types));
- result = false;
- }
-
- // Not a C++ module; ignore.
- continue;
- }
-
- if (!cmFileSetVisibilityIsForInterface(file_set.Visibility)) {
- // Nothing needs to be conveyed about non-`PUBLIC` modules.
- for (auto const& p : object.Provides) {
- private_modules.insert(p.LogicalName);
- }
- continue;
- }
-
- // The module is public. Record what it directly requires.
- {
- auto& reqs = public_source_requires[file_set.SourcePath];
- for (auto const& r : object.Requires) {
- reqs.insert(r.LogicalName);
- }
- }
-
- // Write out properties and install rules for any exports.
- for (auto const& p : object.Provides) {
- bool bmi_dest_is_abs = false;
- std::string bmi_destination;
- if (export_info.BmiInstallation) {
- auto dest =
- install_destination(export_info.BmiInstallation->Destination);
- bmi_dest_is_abs = dest.first;
- bmi_destination = cmStrCat(dest.second, '/');
- }
-
- std::string install_bmi_path;
- std::string build_bmi_path;
- auto m = mod_files.find(p.LogicalName);
- if (m != mod_files.end()) {
- install_bmi_path =
- cmStrCat(bmi_destination,
- cmEscape(cmSystemTools::GetFilenameName(m->second)));
- build_bmi_path = cmEscape(m->second);
- }
-
- for (auto const& exp : exports) {
- std::string iface_source;
- if (exp.second->Install && file_set.Destination) {
- auto dest = install_destination(*file_set.Destination);
- iface_source = cmStrCat(
- dest.second, '/', cmEscape(file_set.RelativeDirectory),
- cmEscape(cmSystemTools::GetFilenameName(file_set.SourcePath)));
- } else {
- iface_source = cmEscape(file_set.SourcePath);
- }
-
- std::string bmi_path;
- if (exp.second->Install && export_info.BmiInstallation) {
- bmi_path = install_bmi_path;
- } else if (!exp.second->Install) {
- bmi_path = build_bmi_path;
- }
-
- if (iface_source.empty()) {
- // No destination for the C++ module source; ignore this property
- // value.
- continue;
- }
-
- *exp.first << " \"" << cmEscape(p.LogicalName) << '='
- << iface_source;
- if (!bmi_path.empty()) {
- *exp.first << ',' << bmi_path;
- }
- *exp.first << "\"\n";
- }
-
- if (bmi_install_script) {
- auto const& bmi_install = *export_info.BmiInstallation;
-
- *bmi_install_script << "if (CMAKE_INSTALL_COMPONENT STREQUAL \""
- << cmEscape(bmi_install.Component) << '\"';
- if (!bmi_install.ExcludeFromAll) {
- *bmi_install_script << " OR NOT CMAKE_INSTALL_COMPONENT";
- }
- *bmi_install_script << ")\n";
- *bmi_install_script << " file(INSTALL\n"
- " DESTINATION \"";
- if (!bmi_dest_is_abs) {
- *bmi_install_script << "${CMAKE_INSTALL_PREFIX}/";
- }
- *bmi_install_script << cmEscape(bmi_install.Destination)
- << "\"\n"
- " TYPE FILE\n";
- if (bmi_install.Optional) {
- *bmi_install_script << " OPTIONAL\n";
- }
- if (!bmi_install.MessageLevel.empty()) {
- *bmi_install_script << " " << bmi_install.MessageLevel << "\n";
- }
- if (!bmi_install.Permissions.empty()) {
- *bmi_install_script << " PERMISSIONS" << bmi_install.Permissions
- << "\n";
- }
- *bmi_install_script << " FILES \"" << m->second << "\")\n";
- if (bmi_dest_is_abs) {
- *bmi_install_script
- << " list(APPEND CMAKE_ABSOLUTE_DESTINATION_FILES\n"
- " \""
- << cmEscape(cmSystemTools::GetFilenameName(m->second))
- << "\")\n"
- " if (CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)\n"
- " message(WARNING\n"
- " \"ABSOLUTE path INSTALL DESTINATION : "
- "${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"
- " endif ()\n"
- " if (CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n"
- " message(FATAL_ERROR\n"
- " \"ABSOLUTE path INSTALL DESTINATION forbidden (by "
- "caller): ${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"
- " endif ()\n";
- }
- *bmi_install_script << "endif ()\n";
- }
- }
- }
-
- // Add trailing parenthesis for the `set_property` call.
- for (auto const& exp : exports) {
- *exp.first << ")\n";
- }
-
- // Check that public sources only require public modules.
- for (auto const& pub_reqs : public_source_requires) {
- for (auto const& req : pub_reqs.second) {
- if (private_modules.count(req)) {
- cmSystemTools::Error(cmStrCat(
- "Public C++ module source `", pub_reqs.first, "` requires the `",
- req, "` C++ module which is provided by a private source"));
- result = false;
- }
- }
- }
- }
-
- return result;
+ return cmDyndepCollation::WriteDyndepMetadata(arg_lang, objects, export_info,
+ cb);
}
int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
@@ -3099,58 +2802,7 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
}
}
- cmGlobalNinjaGenerator::CxxModuleExportInfo export_info;
- export_info.Config = tdi["config"].asString();
- if (export_info.Config.empty()) {
- export_info.Config = "noconfig";
- }
- Json::Value const& tdi_exports = tdi["exports"];
- if (tdi_exports.isArray()) {
- for (auto const& tdi_export : tdi_exports) {
- CxxModuleExport exp;
- exp.Install = tdi_export["install"].asBool();
- exp.Name = tdi_export["export-name"].asString();
- exp.Destination = tdi_export["destination"].asString();
- exp.Prefix = tdi_export["export-prefix"].asString();
- exp.CxxModuleInfoDir = tdi_export["cxx-module-info-dir"].asString();
- exp.Namespace = tdi_export["namespace"].asString();
-
- export_info.Exports.push_back(exp);
- }
- }
- auto const& bmi_installation = tdi["bmi-installation"];
- if (bmi_installation.isObject()) {
- CxxModuleBmiInstall bmi_install;
-
- bmi_install.Component = bmi_installation["component"].asString();
- bmi_install.Destination = bmi_installation["destination"].asString();
- bmi_install.ExcludeFromAll = bmi_installation["exclude-from-all"].asBool();
- bmi_install.Optional = bmi_installation["optional"].asBool();
- bmi_install.Permissions = bmi_installation["permissions"].asString();
- bmi_install.MessageLevel = bmi_installation["message-level"].asString();
- bmi_install.ScriptLocation =
- bmi_installation["script-location"].asString();
-
- export_info.BmiInstallation = bmi_install;
- }
- Json::Value const& tdi_cxx_modules = tdi["cxx-modules"];
- if (tdi_cxx_modules.isObject()) {
- for (auto i = tdi_cxx_modules.begin(); i != tdi_cxx_modules.end(); ++i) {
- CxxModuleFileSet& fsi = export_info.ObjectToFileSet[i.key().asString()];
- auto const& tdi_cxx_module_info = *i;
- fsi.Name = tdi_cxx_module_info["name"].asString();
- fsi.RelativeDirectory =
- tdi_cxx_module_info["relative-directory"].asString();
- fsi.SourcePath = tdi_cxx_module_info["source"].asString();
- fsi.Type = tdi_cxx_module_info["type"].asString();
- fsi.Visibility = cmFileSetVisibilityFromName(
- tdi_cxx_module_info["visibility"].asString(), nullptr);
- auto const& tdi_fs_dest = tdi_cxx_module_info["destination"];
- if (tdi_fs_dest.isString()) {
- fsi.Destination = tdi_fs_dest.asString();
- }
- }
- }
+ auto export_info = cmDyndepCollation::ParseExportInfo(tdi);
cmake cm(cmake::RoleInternal, cmState::Unknown);
cm.SetHomeDirectory(dir_top_src);
@@ -3160,7 +2812,7 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
!cm::static_reference_cast<cmGlobalNinjaGenerator>(ggd).WriteDyndepFile(
dir_top_src, dir_top_bld, dir_cur_src, dir_cur_bld, arg_dd, arg_ddis,
module_dir, linked_target_dirs, arg_lang, arg_modmapfmt,
- export_info)) {
+ *export_info)) {
return 1;
}
return 0;
@@ -3208,10 +2860,10 @@ cmGlobalNinjaMultiGenerator::cmGlobalNinjaMultiGenerator(cmake* cm)
cm->GetState()->SetNinjaMulti(true);
}
-void cmGlobalNinjaMultiGenerator::GetDocumentation(cmDocumentationEntry& entry)
+cmDocumentationEntry cmGlobalNinjaMultiGenerator::GetDocumentation()
{
- entry.Name = cmGlobalNinjaMultiGenerator::GetActualName();
- entry.Brief = "Generates build-<Config>.ninja files.";
+ return { cmGlobalNinjaMultiGenerator::GetActualName(),
+ "Generates build-<Config>.ninja files." };
}
std::string cmGlobalNinjaMultiGenerator::ExpandCFGIntDir(
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index defa264..775e792 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -35,7 +35,7 @@ class cmMakefile;
class cmOutputConverter;
class cmStateDirectory;
class cmake;
-struct cmDocumentationEntry;
+struct cmCxxModuleExportInfo;
/**
* \class cmGlobalNinjaGenerator
@@ -193,7 +193,7 @@ public:
/** Get encoding used by generator for ninja files */
codecvt::Encoding GetMakefileEncoding() const override;
- static void GetDocumentation(cmDocumentationEntry& entry);
+ static cmDocumentationEntry GetDocumentation();
void EnableLanguage(std::vector<std::string> const& languages,
cmMakefile* mf, bool optional) override;
@@ -292,7 +292,8 @@ public:
}
void AddCXXCompileCommand(const std::string& commandLine,
- const std::string& sourceFile);
+ const std::string& sourceFile,
+ const std::string& objPath);
/**
* Add a rule to the generated build system.
@@ -417,7 +418,6 @@ public:
bool HasOutputPathPrefix() const { return !this->OutputPathPrefix.empty(); }
void StripNinjaOutputPathPrefixAsSuffix(std::string& path);
- struct CxxModuleExportInfo;
bool WriteDyndepFile(
std::string const& dir_top_src, std::string const& dir_top_bld,
std::string const& dir_cur_src, std::string const& dir_cur_bld,
@@ -425,7 +425,7 @@ public:
std::string const& module_dir,
std::vector<std::string> const& linked_target_dirs,
std::string const& arg_lang, std::string const& arg_modmapfmt,
- CxxModuleExportInfo const& export_info);
+ cmCxxModuleExportInfo const& export_info);
virtual std::string BuildAlias(const std::string& alias,
const std::string& /*config*/) const
@@ -469,7 +469,7 @@ public:
bool IsSingleConfigUtility(cmGeneratorTarget const* target) const;
- bool CheckCxxModuleSupport();
+ bool CheckCxxModuleSupport() override;
protected:
void Generate() override;
@@ -592,7 +592,7 @@ private:
codecvt::Encoding NinjaExpectedEncoding = codecvt::None;
- bool DiagnosedCxxModuleSupport = false;
+ bool DiagnosedCxxModuleNinjaSupport = false;
void InitOutputPathPrefix();
@@ -655,7 +655,7 @@ public:
new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaMultiGenerator>());
}
- static void GetDocumentation(cmDocumentationEntry& entry);
+ static cmDocumentationEntry GetDocumentation();
std::string GetName() const override
{
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 21aa89c..30206b5 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -11,7 +11,6 @@
#include <cmext/algorithm>
#include <cmext/memory>
-#include "cmDocumentationEntry.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -71,11 +70,10 @@ cmGlobalUnixMakefileGenerator3::CreateLocalGenerator(cmMakefile* mf)
cm::make_unique<cmLocalUnixMakefileGenerator3>(this, mf));
}
-void cmGlobalUnixMakefileGenerator3::GetDocumentation(
- cmDocumentationEntry& entry)
+cmDocumentationEntry cmGlobalUnixMakefileGenerator3::GetDocumentation()
{
- entry.Name = cmGlobalUnixMakefileGenerator3::GetActualName();
- entry.Brief = "Generates standard UNIX makefiles.";
+ return { cmGlobalUnixMakefileGenerator3::GetActualName(),
+ "Generates standard UNIX makefiles." };
}
void cmGlobalUnixMakefileGenerator3::ComputeTargetObjectDirectory(
@@ -104,6 +102,9 @@ void cmGlobalUnixMakefileGenerator3::Configure()
void cmGlobalUnixMakefileGenerator3::Generate()
{
+ this->ClangTidyExportFixesDirs.clear();
+ this->ClangTidyExportFixesFiles.clear();
+
// first do superclass method
this->cmGlobalGenerator::Generate();
@@ -139,11 +140,13 @@ void cmGlobalUnixMakefileGenerator3::Generate()
*this->CommandDatabase << "\n]";
this->CommandDatabase.reset();
}
+
+ this->RemoveUnknownClangTidyExportFixesFiles();
}
void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand(
const std::string& sourceFile, const std::string& workingDirectory,
- const std::string& compileCommand)
+ const std::string& compileCommand, const std::string& objPath)
{
if (!this->CommandDatabase) {
std::string commandDatabaseName =
@@ -164,7 +167,9 @@ void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand(
<< "\",\n"
<< R"( "file": ")"
<< cmGlobalGenerator::EscapeJSON(sourceFile)
- << "\"\n}";
+ << "\",\n"
+ << R"( "output": ")"
+ << cmGlobalGenerator::EscapeJSON(objPath) << "\"\n}";
}
void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index b9d333e..214ba2a 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -24,7 +24,6 @@ class cmLocalUnixMakefileGenerator3;
class cmMakefile;
class cmMakefileTargetGenerator;
class cmake;
-struct cmDocumentationEntry;
/** \class cmGlobalUnixMakefileGenerator3
* \brief Write a Unix makefiles.
@@ -101,7 +100,7 @@ public:
bool SupportsCustomCommandDepfile() const override { return true; }
/** Get the documentation entry for this generator. */
- static void GetDocumentation(cmDocumentationEntry& entry);
+ static cmDocumentationEntry GetDocumentation();
std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
cmMakefile* mf) override;
@@ -174,7 +173,8 @@ public:
void AddCXXCompileCommand(const std::string& sourceFile,
const std::string& workingDirectory,
- const std::string& compileCommand);
+ const std::string& compileCommand,
+ const std::string& objPath);
/** Does the make tool tolerate .NOTPARALLEL? */
virtual bool AllowNotParallel() const { return true; }
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index bea2ae7..192663d 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -56,6 +56,7 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator(
{
this->DefaultCudaFlagTableName = "v10";
this->DefaultCudaHostFlagTableName = "v10";
+ this->DefaultMarmasmFlagTableName = "v10";
this->DefaultNasmFlagTableName = "v10";
}
@@ -301,7 +302,7 @@ bool cmGlobalVisualStudio10Generator::ParseGeneratorToolset(
std::string const& ts, cmMakefile* mf)
{
std::vector<std::string> const fields = cmTokenize(ts, ",");
- std::vector<std::string>::const_iterator fi = fields.begin();
+ auto fi = fields.begin();
if (fi == fields.end()) {
return true;
}
@@ -500,7 +501,8 @@ bool cmGlobalVisualStudio10Generator::InitializeWindowsStore(cmMakefile* mf)
bool cmGlobalVisualStudio10Generator::InitializeTegraAndroid(cmMakefile* mf)
{
- std::string v = this->GetInstalledNsightTegraVersion();
+ std::string v =
+ cmGlobalVisualStudio10Generator::GetInstalledNsightTegraVersion();
if (v.empty()) {
mf->IssueMessage(MessageType::FATAL_ERROR,
"CMAKE_SYSTEM_NAME is 'Android' but "
@@ -772,9 +774,9 @@ std::string cmGlobalVisualStudio10Generator::FindMSBuildCommand()
// Search in standard location.
mskey = cmStrCat(
- "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\",
+ R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\)",
this->GetToolsVersion(), ";MSBuildToolsPath");
- if (cmSystemTools::ReadRegistryValue(mskey.c_str(), msbuild,
+ if (cmSystemTools::ReadRegistryValue(mskey, msbuild,
cmSystemTools::KeyWOW64_32)) {
cmSystemTools::ConvertToUnixSlashes(msbuild);
msbuild += "/MSBuild.exe";
@@ -797,6 +799,7 @@ std::string cmGlobalVisualStudio10Generator::FindDevEnvCommand()
}
// Skip over the cmGlobalVisualStudio8Generator implementation because
// we expect a real devenv and do not want to look for VCExpress.
+ // NOLINTNEXTLINE(bugprone-parent-virtual-call)
return this->cmGlobalVisualStudio71Generator::FindDevEnvCommand();
}
@@ -1107,8 +1110,9 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
// Decide if a restore is performed, based on a cache variable.
if (cmValue cached =
this->CMakeInstance->GetState()->GetCacheEntryValue(
- "CMAKE_VS_NUGET_PACKAGE_RESTORE"))
+ "CMAKE_VS_NUGET_PACKAGE_RESTORE")) {
restorePackages = cached.IsOn();
+ }
}
if (restorePackages) {
@@ -1136,7 +1140,7 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
std::string extension =
cmSystemTools::GetFilenameLastExtension(proj->GetRelativePath());
extension = cmSystemTools::LowerCase(extension);
- if (extension.compare(".csproj") == 0) {
+ if (extension == ".csproj") {
// Use correct platform name
platform =
slnData.GetConfigurationTarget(tname, plainConfig, platform);
@@ -1154,8 +1158,6 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
} else {
makeCommand.Add(cmStrCat("/m:", std::to_string(jobs)));
}
- // Having msbuild.exe and cl.exe using multiple jobs is discouraged
- makeCommand.Add("/p:CL_MPCount=1");
}
// Respect the verbosity: 'n' normal will show build commands
@@ -1466,6 +1468,13 @@ cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetCudaHostFlagTable()
"CudaHost");
}
+cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetMarmasmFlagTable()
+ const
+{
+ return LoadFlagTable(std::string(), this->DefaultMarmasmFlagTableName,
+ "MARMASM");
+}
+
cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetMasmFlagTable() const
{
return LoadFlagTable(this->GetMasmFlagTableName(),
@@ -1496,19 +1505,23 @@ std::string cmGlobalVisualStudio10Generator::GetClFlagTableName() const
if (toolset == "v142") {
return "v142";
- } else if (toolset == "v141") {
+ }
+ if (toolset == "v141") {
return "v141";
- } else if (useToolset == "v140") {
+ }
+ if (useToolset == "v140") {
return "v140";
- } else if (useToolset == "v120") {
+ }
+ if (useToolset == "v120") {
return "v12";
- } else if (useToolset == "v110") {
+ }
+ if (useToolset == "v110") {
return "v11";
- } else if (useToolset == "v100") {
+ }
+ if (useToolset == "v100") {
return "v10";
- } else {
- return "";
}
+ return "";
}
std::string cmGlobalVisualStudio10Generator::GetCSharpFlagTableName() const
@@ -1518,19 +1531,23 @@ std::string cmGlobalVisualStudio10Generator::GetCSharpFlagTableName() const
if (useToolset == "v142") {
return "v142";
- } else if (useToolset == "v141") {
+ }
+ if (useToolset == "v141") {
return "v141";
- } else if (useToolset == "v140") {
+ }
+ if (useToolset == "v140") {
return "v140";
- } else if (useToolset == "v120") {
+ }
+ if (useToolset == "v120") {
return "v12";
- } else if (useToolset == "v110") {
+ }
+ if (useToolset == "v110") {
return "v11";
- } else if (useToolset == "v100") {
+ }
+ if (useToolset == "v100") {
return "v10";
- } else {
- return "";
}
+ return "";
}
std::string cmGlobalVisualStudio10Generator::GetRcFlagTableName() const
@@ -1541,15 +1558,17 @@ std::string cmGlobalVisualStudio10Generator::GetRcFlagTableName() const
if ((useToolset == "v140") || (useToolset == "v141") ||
(useToolset == "v142")) {
return "v14";
- } else if (useToolset == "v120") {
+ }
+ if (useToolset == "v120") {
return "v12";
- } else if (useToolset == "v110") {
+ }
+ if (useToolset == "v110") {
return "v11";
- } else if (useToolset == "v100") {
+ }
+ if (useToolset == "v100") {
return "v10";
- } else {
- return "";
}
+ return "";
}
std::string cmGlobalVisualStudio10Generator::GetLibFlagTableName() const
@@ -1560,15 +1579,17 @@ std::string cmGlobalVisualStudio10Generator::GetLibFlagTableName() const
if ((useToolset == "v140") || (useToolset == "v141") ||
(useToolset == "v142")) {
return "v14";
- } else if (useToolset == "v120") {
+ }
+ if (useToolset == "v120") {
return "v12";
- } else if (useToolset == "v110") {
+ }
+ if (useToolset == "v110") {
return "v11";
- } else if (useToolset == "v100") {
+ }
+ if (useToolset == "v100") {
return "v10";
- } else {
- return "";
}
+ return "";
}
std::string cmGlobalVisualStudio10Generator::GetLinkFlagTableName() const
@@ -1578,19 +1599,23 @@ std::string cmGlobalVisualStudio10Generator::GetLinkFlagTableName() const
if (useToolset == "v142") {
return "v142";
- } else if (useToolset == "v141") {
+ }
+ if (useToolset == "v141") {
return "v141";
- } else if (useToolset == "v140") {
+ }
+ if (useToolset == "v140") {
return "v140";
- } else if (useToolset == "v120") {
+ }
+ if (useToolset == "v120") {
return "v12";
- } else if (useToolset == "v110") {
+ }
+ if (useToolset == "v110") {
return "v11";
- } else if (useToolset == "v100") {
+ }
+ if (useToolset == "v100") {
return "v10";
- } else {
- return "";
}
+ return "";
}
std::string cmGlobalVisualStudio10Generator::GetMasmFlagTableName() const
@@ -1601,15 +1626,17 @@ std::string cmGlobalVisualStudio10Generator::GetMasmFlagTableName() const
if ((useToolset == "v140") || (useToolset == "v141") ||
(useToolset == "v142")) {
return "v14";
- } else if (useToolset == "v120") {
+ }
+ if (useToolset == "v120") {
return "v12";
- } else if (useToolset == "v110") {
+ }
+ if (useToolset == "v110") {
return "v11";
- } else if (useToolset == "v100") {
+ }
+ if (useToolset == "v100") {
return "v10";
- } else {
- return "";
}
+ return "";
}
std::string cmGlobalVisualStudio10Generator::CanonicalToolsetName(
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index b32c0a7..63c21c5 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -163,6 +163,7 @@ public:
cmIDEFlagTable const* GetLinkFlagTable() const;
cmIDEFlagTable const* GetCudaFlagTable() const;
cmIDEFlagTable const* GetCudaHostFlagTable() const;
+ cmIDEFlagTable const* GetMarmasmFlagTable() const;
cmIDEFlagTable const* GetMasmFlagTable() const;
cmIDEFlagTable const* GetNasmFlagTable() const;
@@ -226,6 +227,7 @@ protected:
std::string DefaultLinkFlagTableName;
std::string DefaultCudaFlagTableName;
std::string DefaultCudaHostFlagTableName;
+ std::string DefaultMarmasmFlagTableName;
std::string DefaultMasmFlagTableName;
std::string DefaultNasmFlagTableName;
std::string DefaultRCFlagTableName;
@@ -239,15 +241,10 @@ protected:
private:
struct LongestSourcePath
{
- LongestSourcePath()
- : Length(0)
- , Target(0)
- , SourceFile(0)
- {
- }
- size_t Length;
- cmGeneratorTarget* Target;
- cmSourceFile const* SourceFile;
+ LongestSourcePath() = default;
+ size_t Length = 0;
+ cmGeneratorTarget* Target = nullptr;
+ cmSourceFile const* SourceFile = nullptr;
std::string SourceRel;
};
LongestSourcePath LongestSource;
diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx
index 086d3af..3ad10eb 100644
--- a/Source/cmGlobalVisualStudio11Generator.cxx
+++ b/Source/cmGlobalVisualStudio11Generator.cxx
@@ -7,7 +7,6 @@
#include <utility>
#include <vector>
-#include "cmDocumentationEntry.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalGeneratorFactory.h"
#include "cmGlobalVisualStudioGenerator.h"
@@ -23,7 +22,7 @@ static const char* cmVS11GenName(const std::string& name, std::string& genName)
{
if (strncmp(name.c_str(), vs11generatorName,
sizeof(vs11generatorName) - 6) != 0) {
- return 0;
+ return nullptr;
}
const char* p = name.c_str() + sizeof(vs11generatorName) - 6;
if (cmHasLiteralPrefix(p, " 2012")) {
@@ -74,11 +73,11 @@ public:
return std::unique_ptr<cmGlobalGenerator>(std::move(ret));
}
- void GetDocumentation(cmDocumentationEntry& entry) const override
+ cmDocumentationEntry GetDocumentation() const override
{
- entry.Name = std::string(vs11generatorName) + " [arch]";
- entry.Brief = "Deprecated. Generates Visual Studio 2012 project files. "
- "Optional [arch] can be \"Win64\" or \"ARM\".";
+ return { std::string(vs11generatorName) + " [arch]",
+ "Deprecated. Generates Visual Studio 2012 project files. "
+ "Optional [arch] can be \"Win64\" or \"ARM\"." };
}
std::vector<std::string> GetGeneratorNames() const override
@@ -161,6 +160,18 @@ bool cmGlobalVisualStudio11Generator::MatchesGeneratorName(
return false;
}
+void cmGlobalVisualStudio11Generator::EnableLanguage(
+ std::vector<std::string> const& lang, cmMakefile* mf, bool optional)
+{
+ for (std::string const& it : lang) {
+ if (it == "ASM_MARMASM") {
+ this->MarmasmEnabled = true;
+ }
+ }
+ this->AddPlatformDefinitions(mf);
+ cmGlobalVisualStudio10Generator::EnableLanguage(lang, mf, optional);
+}
+
bool cmGlobalVisualStudio11Generator::InitializeWindowsPhone(cmMakefile* mf)
{
if (!this->SelectWindowsPhoneToolset(this->DefaultPlatformToolset)) {
@@ -205,9 +216,8 @@ bool cmGlobalVisualStudio11Generator::SelectWindowsPhoneToolset(
this->IsWindowsDesktopToolsetInstalled()) {
toolset = "v110_wp80";
return true;
- } else {
- return false;
}
+ return false;
}
return this->cmGlobalVisualStudio10Generator::SelectWindowsPhoneToolset(
toolset);
@@ -221,9 +231,8 @@ bool cmGlobalVisualStudio11Generator::SelectWindowsStoreToolset(
this->IsWindowsDesktopToolsetInstalled()) {
toolset = "v110";
return true;
- } else {
- return false;
}
+ return false;
}
return this->cmGlobalVisualStudio10Generator::SelectWindowsStoreToolset(
toolset);
@@ -234,6 +243,7 @@ bool cmGlobalVisualStudio11Generator::UseFolderProperty() const
// Intentionally skip up to the top-level class implementation.
// Folders are not supported by the Express editions in VS10 and earlier,
// but they are in VS11 Express and above.
+ // NOLINTNEXTLINE(bugprone-parent-virtual-call)
return cmGlobalGenerator::UseFolderProperty();
}
diff --git a/Source/cmGlobalVisualStudio11Generator.h b/Source/cmGlobalVisualStudio11Generator.h
index 2f8a7f6..fd25984 100644
--- a/Source/cmGlobalVisualStudio11Generator.h
+++ b/Source/cmGlobalVisualStudio11Generator.h
@@ -25,6 +25,9 @@ public:
bool MatchesGeneratorName(const std::string& name) const override;
+ void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
+ bool optional) override;
+
bool SupportsCustomCommandDepfile() const override { return true; }
cm::optional<cmDepfileFormat> DepfileFormat() const override
diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx
index 600ee0a..d417f9e 100644
--- a/Source/cmGlobalVisualStudio12Generator.cxx
+++ b/Source/cmGlobalVisualStudio12Generator.cxx
@@ -6,7 +6,6 @@
#include <sstream>
#include <vector>
-#include "cmDocumentationEntry.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalGeneratorFactory.h"
#include "cmGlobalVisualStudioGenerator.h"
@@ -22,7 +21,7 @@ static const char* cmVS12GenName(const std::string& name, std::string& genName)
{
if (strncmp(name.c_str(), vs12generatorName,
sizeof(vs12generatorName) - 6) != 0) {
- return 0;
+ return nullptr;
}
const char* p = name.c_str() + sizeof(vs12generatorName) - 6;
if (cmHasLiteralPrefix(p, " 2013")) {
@@ -62,11 +61,11 @@ public:
return std::unique_ptr<cmGlobalGenerator>();
}
- void GetDocumentation(cmDocumentationEntry& entry) const override
+ cmDocumentationEntry GetDocumentation() const override
{
- entry.Name = std::string(vs12generatorName) + " [arch]";
- entry.Brief = "Generates Visual Studio 2013 project files. "
- "Optional [arch] can be \"Win64\" or \"ARM\".";
+ return { std::string(vs12generatorName) + " [arch]",
+ "Generates Visual Studio 2013 project files. "
+ "Optional [arch] can be \"Win64\" or \"ARM\"." };
}
std::vector<std::string> GetGeneratorNames() const override
@@ -195,9 +194,8 @@ bool cmGlobalVisualStudio12Generator::SelectWindowsPhoneToolset(
this->IsWindowsDesktopToolsetInstalled()) {
toolset = "v120_wp81";
return true;
- } else {
- return false;
}
+ return false;
}
return this->cmGlobalVisualStudio11Generator::SelectWindowsPhoneToolset(
toolset);
@@ -211,9 +209,8 @@ bool cmGlobalVisualStudio12Generator::SelectWindowsStoreToolset(
this->IsWindowsDesktopToolsetInstalled()) {
toolset = "v120";
return true;
- } else {
- return false;
}
+ return false;
}
return this->cmGlobalVisualStudio11Generator::SelectWindowsStoreToolset(
toolset);
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index 9f94cca..7424ca3 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -7,7 +7,6 @@
#include <cm/vector>
-#include "cmDocumentationEntry.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalGeneratorFactory.h"
#include "cmGlobalVisualStudioGenerator.h"
@@ -24,7 +23,7 @@ static const char* cmVS14GenName(const std::string& name, std::string& genName)
{
if (strncmp(name.c_str(), vs14generatorName,
sizeof(vs14generatorName) - 6) != 0) {
- return 0;
+ return nullptr;
}
const char* p = name.c_str() + sizeof(vs14generatorName) - 6;
if (cmHasLiteralPrefix(p, " 2015")) {
@@ -64,11 +63,11 @@ public:
return std::unique_ptr<cmGlobalGenerator>();
}
- void GetDocumentation(cmDocumentationEntry& entry) const override
+ cmDocumentationEntry GetDocumentation() const override
{
- entry.Name = std::string(vs14generatorName) + " [arch]";
- entry.Brief = "Generates Visual Studio 2015 project files. "
- "Optional [arch] can be \"Win64\" or \"ARM\".";
+ return { std::string(vs14generatorName) + " [arch]",
+ "Generates Visual Studio 2015 project files. "
+ "Optional [arch] can be \"Win64\" or \"ARM\"." };
}
std::vector<std::string> GetGeneratorNames() const override
@@ -214,9 +213,8 @@ bool cmGlobalVisualStudio14Generator::SelectWindowsStoreToolset(
this->IsWindowsDesktopToolsetInstalled()) {
toolset = "v140";
return true;
- } else {
- return false;
}
+ return false;
}
return this->cmGlobalVisualStudio12Generator::SelectWindowsStoreToolset(
toolset);
@@ -256,7 +254,7 @@ std::string cmGlobalVisualStudio14Generator::GetWindows10SDKMaxVersion(
return std::string();
}
// If the value is something else, trust that it is a valid SDK value.
- else if (value) {
+ if (value) {
return *value;
}
// If value is an invalid pointer, leave result unchanged.
@@ -374,6 +372,7 @@ std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion(
return sdks.at(0);
}
#endif
+ (void)mf;
// Return an empty string
return std::string();
}
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index 758ce83..06fd61c 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -101,14 +101,14 @@ void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
// check to see if this is a fortran build
std::string ext = ".vcproj";
const char* project =
- "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"";
+ R"(Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = ")";
if (this->TargetIsFortranOnly(t)) {
ext = ".vfproj";
- project = "Project(\"{6989167D-11E4-40FE-8C1A-2192A86A7E90}\") = \"";
+ project = R"(Project("{6989167D-11E4-40FE-8C1A-2192A86A7E90}") = ")";
}
if (t->IsCSharpOnly()) {
ext = ".csproj";
- project = "Project(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"";
+ project = R"(Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = ")";
}
cmValue targetExt = t->GetProperty("GENERATOR_FILE_NAME_EXT");
if (targetExt) {
@@ -125,11 +125,11 @@ void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
fout << "EndProject\n";
- UtilityDependsMap::iterator ui = this->UtilityDepends.find(t);
+ auto ui = this->UtilityDepends.find(t);
if (ui != this->UtilityDepends.end()) {
const char* uname = ui->second.c_str();
/* clang-format off */
- fout << "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \""
+ fout << R"(Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = ")"
<< uname << "\", \""
<< this->ConvertToSolutionPath(dir) << (dir[0]? "\\":"")
<< uname << ".vcproj" << "\", \"{"
@@ -169,7 +169,9 @@ void cmGlobalVisualStudio71Generator::WriteExternalProject(
{
fout << "Project(\"{"
<< (typeGuid ? typeGuid
- : std::string(this->ExternalProjectType(location)))
+ : std::string(
+ cmGlobalVisualStudio71Generator::ExternalProjectType(
+ location)))
<< "}\") = \"" << name << "\", \""
<< this->ConvertToSolutionPath(location) << "\", \"{"
<< this->GetGUID(name) << "}\"\n";
@@ -216,8 +218,7 @@ void cmGlobalVisualStudio71Generator::WriteProjectConfigurations(
}
fout << "\t\t{" << guid << "}." << i << ".ActiveCfg = " << dstConfig << "|"
<< platformName << std::endl;
- std::set<std::string>::const_iterator ci =
- configsPartOfDefaultBuild.find(i);
+ auto ci = configsPartOfDefaultBuild.find(i);
if (!(ci == configsPartOfDefaultBuild.end())) {
fout << "\t\t{" << guid << "}." << i << ".Build.0 = " << dstConfig << "|"
<< platformName << std::endl;
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index ff76762..c375d60 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -70,14 +70,13 @@ cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator(
: cmGlobalVisualStudioGenerator(cm, platformInGeneratorName)
{
this->DevEnvCommandInitialized = false;
+ this->MarmasmEnabled = false;
this->MasmEnabled = false;
this->NasmEnabled = false;
this->ExtraFlagTable = cmVS7ExtraFlagTable;
}
-cmGlobalVisualStudio7Generator::~cmGlobalVisualStudio7Generator()
-{
-}
+cmGlobalVisualStudio7Generator::~cmGlobalVisualStudio7Generator() = default;
// Package GUID of Intel Visual Fortran plugin to VS IDE
#define CM_INTEL_PLUGIN_GUID "{B68A201D-CB9B-47AF-A52F-7EEC72E217E4}"
@@ -159,7 +158,7 @@ std::string cmGlobalVisualStudio7Generator::FindDevEnvCommand()
// Search in standard location.
vskey = this->GetRegistryBase() + ";InstallDir";
- if (cmSystemTools::ReadRegistryValue(vskey.c_str(), vscmd,
+ if (cmSystemTools::ReadRegistryValue(vskey, vscmd,
cmSystemTools::KeyWOW64_32)) {
cmSystemTools::ConvertToUnixSlashes(vscmd);
vscmd += "/devenv.com";
@@ -170,9 +169,9 @@ std::string cmGlobalVisualStudio7Generator::FindDevEnvCommand()
// Search where VS15Preview places it.
vskey = cmStrCat(
- "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7;",
+ R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\SxS\VS7;)",
this->GetIDEVersion());
- if (cmSystemTools::ReadRegistryValue(vskey.c_str(), vscmd,
+ if (cmSystemTools::ReadRegistryValue(vskey, vscmd,
cmSystemTools::KeyWOW64_32)) {
cmSystemTools::ConvertToUnixSlashes(vscmd);
vscmd += "/Common7/IDE/devenv.com";
@@ -191,17 +190,23 @@ const char* cmGlobalVisualStudio7Generator::ExternalProjectType(
std::string extension = cmSystemTools::GetFilenameLastExtension(location);
if (extension == ".vbproj") {
return "F184B08F-C81C-45F6-A57F-5ABD9991F28F";
- } else if (extension == ".csproj") {
+ }
+ if (extension == ".csproj") {
return "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC";
- } else if (extension == ".fsproj") {
+ }
+ if (extension == ".fsproj") {
return "F2A71F9B-5D33-465A-A702-920D77279786";
- } else if (extension == ".vdproj") {
+ }
+ if (extension == ".vdproj") {
return "54435603-DBB4-11D2-8724-00A0C9A8B90C";
- } else if (extension == ".dbproj") {
+ }
+ if (extension == ".dbproj") {
return "C8D11400-126E-41CD-887F-60BD40844F9E";
- } else if (extension == ".wixproj") {
+ }
+ if (extension == ".wixproj") {
return "930C7802-8A8C-48F9-8165-68863BCCD9DD";
- } else if (extension == ".pyproj") {
+ }
+ if (extension == ".pyproj") {
return "888888A0-9F3D-457C-B088-3A5042F75D52";
}
return "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942";
@@ -333,7 +338,7 @@ void cmGlobalVisualStudio7Generator::OutputSLNFile(
}
this->CurrentProject = root->GetProjectName();
std::string fname = GetSLNFile(root);
- cmGeneratedFileStream fout(fname.c_str());
+ cmGeneratedFileStream fout(fname);
fout.SetCopyIfDifferent(true);
if (!fout) {
return;
@@ -379,7 +384,8 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
// On VS 19 and above, always map .NET SDK projects to "Any CPU".
if (target->IsDotNetSdkTarget() &&
this->GetVersion() >= VSVersion::VS16 &&
- !this->IsReservedTarget(target->GetName())) {
+ !cmGlobalVisualStudio7Generator::IsReservedTarget(
+ target->GetName())) {
mapping = "Any CPU";
}
this->WriteProjectConfigurations(fout, *vcprojName, *target, configs,
@@ -420,7 +426,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
cmValue expath = target->GetProperty("EXTERNAL_MSPROJECT");
if (expath) {
std::string project = target->GetName();
- std::string location = *expath;
+ std::string const& location = *expath;
this->WriteExternalProject(fout, project, location,
target->GetProperty("VS_PROJECT_TYPE"),
@@ -451,7 +457,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
std::string cumulativePath;
for (std::string const& iter : tokens) {
- if (!iter.size()) {
+ if (iter.empty()) {
continue;
}
@@ -500,7 +506,7 @@ void cmGlobalVisualStudio7Generator::WriteFoldersContent(std::ostream& fout)
std::string guidParent(this->GetGUID(key));
for (std::string const& it : iter.second) {
- std::string value(it);
+ std::string const& value(it);
std::string guid(this->GetGUID(value));
fout << "\t\t{" << guid << "} = {" << guidParent << "}\n";
@@ -516,7 +522,7 @@ std::string cmGlobalVisualStudio7Generator::ConvertToSolutionPath(
// use windows slashes.
std::string d = path;
std::string::size_type pos = 0;
- while ((pos = d.find('/', pos)) != d.npos) {
+ while ((pos = d.find('/', pos)) != std::string::npos) {
d[pos++] = '\\';
}
return d;
@@ -540,8 +546,9 @@ void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections(
} else if (cmHasLiteralPrefix(name, "POST_")) {
name = name.substr(5);
sectionType = "postSolution";
- } else
+ } else {
continue;
+ }
if (!name.empty()) {
bool addGuid = false;
if (name == "ExtensibilityGlobals" && sectionType == "postSolution") {
@@ -579,9 +586,10 @@ void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections(
<< "\t\tSolutionGuid = {" << guid << "}\n"
<< "\tEndGlobalSection\n";
}
- if (!extensibilityAddInsOverridden)
+ if (!extensibilityAddInsOverridden) {
fout << "\tGlobalSection(ExtensibilityAddIns) = postSolution\n"
<< "\tEndGlobalSection\n";
+ }
}
// Standard end of dsw file
@@ -600,13 +608,13 @@ std::string cmGlobalVisualStudio7Generator::WriteUtilityDepend(
std::string fname =
cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
pname, ".vcproj");
- cmGeneratedFileStream fout(fname.c_str());
+ cmGeneratedFileStream fout(fname);
fout.SetCopyIfDifferent(true);
- std::string guid = this->GetGUID(pname.c_str());
+ std::string guid = this->GetGUID(pname);
/* clang-format off */
fout <<
- "<?xml version=\"1.0\" encoding = \""
+ R"(<?xml version="1.0" encoding = ")"
<< this->Encoding() << "\"?>\n"
"<VisualStudioProject\n"
"\tProjectType=\"Visual C++\"\n"
@@ -729,13 +737,12 @@ std::set<std::string> cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(
bool cmGlobalVisualStudio7Generator::IsDependedOn(
OrderedTargetDependSet const& projectTargets, cmGeneratorTarget const* gtIn)
{
- for (cmTargetDepend const& l : projectTargets) {
- TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(l);
- if (tgtdeps.count(gtIn)) {
- return true;
- }
- }
- return false;
+ return std::any_of(projectTargets.begin(), projectTargets.end(),
+ [this, gtIn](cmTargetDepend const& l) {
+ TargetDependSet const& tgtdeps =
+ this->GetTargetDirectDepends(l);
+ return tgtdeps.count(gtIn);
+ });
}
std::string cmGlobalVisualStudio7Generator::Encoding()
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index 288069c..6f6109e 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -31,7 +31,7 @@ class BT;
class cmGlobalVisualStudio7Generator : public cmGlobalVisualStudioGenerator
{
public:
- ~cmGlobalVisualStudio7Generator();
+ ~cmGlobalVisualStudio7Generator() override;
//! Create a local generator appropriate to this Global Generator
std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
@@ -106,6 +106,7 @@ public:
bool FindMakeProgram(cmMakefile* mf) override;
/** Is the Microsoft Assembler enabled? */
+ bool IsMarmasmEnabled() const { return this->MarmasmEnabled; }
bool IsMasmEnabled() const { return this->MasmEnabled; }
bool IsNasmEnabled() const { return this->NasmEnabled; }
@@ -114,6 +115,8 @@ public:
cmIDEFlagTable const* ExtraFlagTable;
+ virtual bool SupportsCxxModuleDyndep() const { return false; }
+
protected:
cmGlobalVisualStudio7Generator(cmake* cm,
std::string const& platformInGeneratorName);
@@ -157,8 +160,6 @@ protected:
cmValue typeGuid,
const std::set<BT<std::pair<std::string, bool>>>& dependencies) = 0;
- virtual bool SupportsCxxModuleDyndep() const { return false; }
-
std::string ConvertToSolutionPath(const std::string& path);
std::set<std::string> IsPartOfDefaultBuild(
@@ -176,6 +177,7 @@ protected:
// Set during OutputSLNFile with the name of the current project.
// There is one SLN file per project.
std::string CurrentProject;
+ bool MarmasmEnabled;
bool MasmEnabled;
bool NasmEnabled;
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 323ee67..647fc2d 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -44,7 +44,8 @@ cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator(
{
this->ProjectConfigurationSectionName = "ProjectConfigurationPlatforms";
this->Name = name;
- this->ExtraFlagTable = this->GetExtraFlagTableVS8();
+ this->ExtraFlagTable =
+ cmGlobalVisualStudio8Generator::GetExtraFlagTableVS8();
}
std::string cmGlobalVisualStudio8Generator::FindDevEnvCommand()
@@ -52,9 +53,9 @@ std::string cmGlobalVisualStudio8Generator::FindDevEnvCommand()
// First look for VCExpress.
std::string vsxcmd;
std::string vsxkey =
- cmStrCat("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\",
+ cmStrCat(R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VCExpress\)",
this->GetIDEVersion(), ";InstallDir");
- if (cmSystemTools::ReadRegistryValue(vsxkey.c_str(), vsxcmd,
+ if (cmSystemTools::ReadRegistryValue(vsxkey, vsxcmd,
cmSystemTools::KeyWOW64_32)) {
cmSystemTools::ConvertToUnixSlashes(vsxcmd);
vsxcmd += "/VCExpress.exe";
@@ -149,6 +150,7 @@ void cmGlobalVisualStudio8Generator::Configure()
bool cmGlobalVisualStudio8Generator::UseFolderProperty() const
{
+ // NOLINTNEXTLINE(bugprone-parent-virtual-call)
return IsExpressEdition() ? false : cmGlobalGenerator::UseFolderProperty();
}
@@ -172,7 +174,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
std::move(cc));
auto ptr = cm::make_unique<cmGeneratorTarget>(tgt, &lg);
- auto gt = ptr.get();
+ auto* gt = ptr.get();
lg.AddGeneratorTarget(std::move(ptr));
// Organize in the "predefined targets" folder:
@@ -190,7 +192,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
cmStrCat(generators[0]->GetMakefile()->GetCurrentBinaryDirectory(), '/',
stampList);
std::string stampFile;
- cmGeneratedFileStream fout(stampListFile.c_str());
+ cmGeneratedFileStream fout(stampListFile);
for (const auto& gi : generators) {
stampFile = cmStrCat(gi->GetMakefile()->GetCurrentBinaryDirectory(),
"/CMakeFiles/generate.stamp");
@@ -237,8 +239,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
// Sort the list of input files and remove duplicates.
std::sort(listFiles.begin(), listFiles.end(), std::less<std::string>());
- std::vector<std::string>::iterator new_end =
- std::unique(listFiles.begin(), listFiles.end());
+ auto new_end = std::unique(listFiles.begin(), listFiles.end());
listFiles.erase(new_end, listFiles.end());
// Create a rule to re-run CMake.
@@ -277,8 +278,8 @@ void cmGlobalVisualStudio8Generator::AddExtraIDETargets()
{
cmGlobalVisualStudio7Generator::AddExtraIDETargets();
if (this->AddCheckTarget()) {
- for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) {
- const auto& tgts = this->LocalGenerators[i]->GetGeneratorTargets();
+ for (auto& LocalGenerator : this->LocalGenerators) {
+ const auto& tgts = LocalGenerator->GetGeneratorTargets();
// All targets depend on the build-system check target.
for (const auto& ti : tgts) {
if (ti->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
@@ -324,8 +325,7 @@ void cmGlobalVisualStudio8Generator::WriteProjectConfigurations(
<< (!platformMapping.empty() ? platformMapping
: this->GetPlatformName())
<< "\n";
- std::set<std::string>::const_iterator ci =
- configsPartOfDefaultBuild.find(i);
+ auto ci = configsPartOfDefaultBuild.find(i);
if (!(ci == configsPartOfDefaultBuild.end())) {
fout << "\t\t{" << guid << "}." << i << "|" << this->GetPlatformName()
<< ".Build.0 = " << dstConfig << "|"
@@ -382,6 +382,7 @@ bool cmGlobalVisualStudio8Generator::ComputeTargetDepends()
{
// Skip over the cmGlobalVisualStudioGenerator implementation!
// We do not need the support that VS <= 7.1 needs.
+ // NOLINTNEXTLINE(bugprone-parent-virtual-call)
return this->cmGlobalGenerator::ComputeTargetDepends();
}
@@ -404,20 +405,23 @@ bool cmGlobalVisualStudio8Generator::NeedLinkLibraryDependencies(
cmGeneratorTarget* target)
{
// Look for utility dependencies that magically link.
- for (BT<std::pair<std::string, bool>> const& ui : target->GetUtilities()) {
- if (cmGeneratorTarget* depTarget =
- target->GetLocalGenerator()->FindGeneratorTargetToUse(
- ui.Value.first)) {
- if (depTarget->IsInBuildSystem() &&
- depTarget->GetProperty("EXTERNAL_MSPROJECT")) {
- // This utility dependency names an external .vcproj target.
- // We use LinkLibraryDependencies="true" to link to it without
- // predicting the .lib file location or name.
- return true;
+ auto const& utilities = target->GetUtilities();
+ return std::any_of(
+ utilities.begin(), utilities.end(),
+ [target](BT<std::pair<std::string, bool>> const& ui) {
+ if (cmGeneratorTarget* depTarget =
+ target->GetLocalGenerator()->FindGeneratorTargetToUse(
+ ui.Value.first)) {
+ if (depTarget->IsInBuildSystem() &&
+ depTarget->GetProperty("EXTERNAL_MSPROJECT")) {
+ // This utility dependency names an external .vcproj target.
+ // We use LinkLibraryDependencies="true" to link to it without
+ // predicting the .lib file location or name.
+ return true;
+ }
}
- }
- }
- return false;
+ return false;
+ });
}
static cmVS7FlagTable cmVS8ExtraFlagTable[] = {
diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx
index e03e665..9f6550b 100644
--- a/Source/cmGlobalVisualStudio9Generator.cxx
+++ b/Source/cmGlobalVisualStudio9Generator.cxx
@@ -6,7 +6,6 @@
#include <utility>
#include <vector>
-#include "cmDocumentationEntry.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalGeneratorFactory.h"
#include "cmGlobalVisualStudioGenerator.h"
@@ -62,11 +61,11 @@ public:
return std::unique_ptr<cmGlobalGenerator>(std::move(ret));
}
- void GetDocumentation(cmDocumentationEntry& entry) const override
+ cmDocumentationEntry GetDocumentation() const override
{
- entry.Name = std::string(vs9generatorName) + " [arch]";
- entry.Brief = "Generates Visual Studio 2008 project files. "
- "Optional [arch] can be \"Win64\" or \"IA64\".";
+ return { std::string(vs9generatorName) + " [arch]",
+ "Generates Visual Studio 2008 project files. "
+ "Optional [arch] can be \"Win64\" or \"IA64\"." };
}
std::vector<std::string> GetGeneratorNames() const override
@@ -159,5 +158,5 @@ std::string cmGlobalVisualStudio9Generator::GetUserMacrosDirectory()
std::string cmGlobalVisualStudio9Generator::GetUserMacrosRegKeyBase()
{
- return "Software\\Microsoft\\VisualStudio\\9.0\\vsmacros";
+ return R"(Software\Microsoft\VisualStudio\9.0\vsmacros)";
}
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 9d168d0..31f6f77 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -51,9 +51,7 @@ cmGlobalVisualStudioGenerator::cmGlobalVisualStudioGenerator(
}
}
-cmGlobalVisualStudioGenerator::~cmGlobalVisualStudioGenerator()
-{
-}
+cmGlobalVisualStudioGenerator::~cmGlobalVisualStudioGenerator() = default;
cmGlobalVisualStudioGenerator::VSVersion
cmGlobalVisualStudioGenerator::GetVersion() const
@@ -188,7 +186,7 @@ std::string cmGlobalVisualStudioGenerator::GetRegistryBase()
std::string cmGlobalVisualStudioGenerator::GetRegistryBase(const char* version)
{
- std::string key = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\";
+ std::string key = R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\)";
return key + version;
}
@@ -520,13 +518,12 @@ std::string cmGlobalVisualStudioGenerator::GetStartupProjectName(
std::string startup = *n;
if (this->FindTarget(startup)) {
return startup;
- } else {
- root->GetMakefile()->IssueMessage(
- MessageType::AUTHOR_WARNING,
- "Directory property VS_STARTUP_PROJECT specifies target "
- "'" +
- startup + "' that does not exist. Ignoring.");
}
+ root->GetMakefile()->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ "Directory property VS_STARTUP_PROJECT specifies target "
+ "'" +
+ startup + "' that does not exist. Ignoring.");
}
// default, if not specified
@@ -961,7 +958,7 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
commands.push_back(std::move(command));
}
-static bool OpenSolution(std::string sln)
+static bool OpenSolution(std::string const& sln)
{
HRESULT comInitialized =
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index 576e4f2..3e20ada 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -44,7 +44,7 @@ public:
VS17 = 170
};
- virtual ~cmGlobalVisualStudioGenerator();
+ ~cmGlobalVisualStudioGenerator() override;
VSVersion GetVersion() const;
void SetVersion(VSVersion v);
@@ -133,8 +133,8 @@ public:
std::string First;
public:
- TargetCompare(std::string const& first)
- : First(first)
+ TargetCompare(std::string first)
+ : First(std::move(first))
{
}
bool operator()(cmGeneratorTarget const* l,
@@ -193,7 +193,6 @@ protected:
using UtilityDependsMap = std::map<cmGeneratorTarget const*, std::string>;
UtilityDependsMap UtilityDepends;
-protected:
VSVersion Version;
bool ExpressEdition;
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index be318c1..415eb7c 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -14,7 +14,6 @@
#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cmDocumentationEntry.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalGeneratorFactory.h"
#include "cmMakefile.h"
@@ -54,7 +53,8 @@ static bool VSIsArm64Host()
# undef CM_VS_GCC_DIAGNOSTIC_PUSHED
#endif
- USHORT processMachine, nativeMachine;
+ USHORT processMachine;
+ USHORT nativeMachine;
return s_IsWow64Process2Impl != nullptr &&
s_IsWow64Process2Impl(GetCurrentProcess(), &processMachine,
@@ -66,7 +66,7 @@ static bool VSHasDotNETFrameworkArm64()
{
std::string dotNetArm64;
return cmSystemTools::ReadRegistryValue(
- "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\.NETFramework;InstallRootArm64",
+ R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework;InstallRootArm64)",
dotNetArm64, cmSystemTools::KeyWOW64_64);
}
@@ -86,19 +86,19 @@ static std::string VSHostPlatformName()
{
if (VSIsArm64Host()) {
return "ARM64";
- } else if (VSIsWow64()) {
+ }
+ if (VSIsWow64()) {
return "x64";
- } else {
+ }
#if defined(_M_ARM)
- return "ARM";
+ return "ARM";
#elif defined(_M_IA64)
- return "Itanium";
+ return "Itanium";
#elif defined(_WIN64)
- return "x64";
+ return "x64";
#else
- return "Win32";
+ return "Win32";
#endif
- }
}
static std::string VSHostArchitecture(
@@ -106,19 +106,19 @@ static std::string VSHostArchitecture(
{
if (VSIsArm64Host()) {
return v >= cmGlobalVisualStudioGenerator::VSVersion::VS17 ? "ARM64" : "";
- } else if (VSIsWow64()) {
+ }
+ if (VSIsWow64()) {
return "x64";
- } else {
+ }
#if defined(_M_ARM)
- return "";
+ return "";
#elif defined(_M_IA64)
- return "";
+ return "";
#elif defined(_WIN64)
- return "x64";
+ return "x64";
#else
- return "x86";
+ return "x86";
#endif
- }
}
static unsigned int VSVersionToMajor(
@@ -212,7 +212,7 @@ static const char* cmVS15GenName(const std::string& name, std::string& genName)
{
if (strncmp(name.c_str(), vs15generatorName,
sizeof(vs15generatorName) - 6) != 0) {
- return 0;
+ return nullptr;
}
const char* p = name.c_str() + sizeof(vs15generatorName) - 6;
if (cmHasLiteralPrefix(p, " 2017")) {
@@ -255,11 +255,11 @@ public:
return std::unique_ptr<cmGlobalGenerator>();
}
- void GetDocumentation(cmDocumentationEntry& entry) const override
+ cmDocumentationEntry GetDocumentation() const override
{
- entry.Name = std::string(vs15generatorName) + " [arch]";
- entry.Brief = "Generates Visual Studio 2017 project files. "
- "Optional [arch] can be \"Win64\" or \"ARM\".";
+ return { std::string(vs15generatorName) + " [arch]",
+ "Generates Visual Studio 2017 project files. "
+ "Optional [arch] can be \"Win64\" or \"ARM\"." };
}
std::vector<std::string> GetGeneratorNames() const override
@@ -307,7 +307,7 @@ static const char* cmVS16GenName(const std::string& name, std::string& genName)
{
if (strncmp(name.c_str(), vs16generatorName,
sizeof(vs16generatorName) - 6) != 0) {
- return 0;
+ return nullptr;
}
const char* p = name.c_str() + sizeof(vs16generatorName) - 6;
if (cmHasLiteralPrefix(p, " 2019")) {
@@ -321,7 +321,7 @@ static const char* cmVS17GenName(const std::string& name, std::string& genName)
{
if (strncmp(name.c_str(), vs17generatorName,
sizeof(vs17generatorName) - 6) != 0) {
- return 0;
+ return nullptr;
}
const char* p = name.c_str() + sizeof(vs17generatorName) - 6;
if (cmHasLiteralPrefix(p, " 2022")) {
@@ -351,11 +351,11 @@ public:
return std::unique_ptr<cmGlobalGenerator>();
}
- void GetDocumentation(cmDocumentationEntry& entry) const override
+ cmDocumentationEntry GetDocumentation() const override
{
- entry.Name = std::string(vs16generatorName);
- entry.Brief = "Generates Visual Studio 2019 project files. "
- "Use -A option to specify architecture.";
+ return { std::string(vs16generatorName),
+ "Generates Visual Studio 2019 project files. "
+ "Use -A option to specify architecture." };
}
std::vector<std::string> GetGeneratorNames() const override
@@ -416,11 +416,11 @@ public:
return std::unique_ptr<cmGlobalGenerator>();
}
- void GetDocumentation(cmDocumentationEntry& entry) const override
+ cmDocumentationEntry GetDocumentation() const override
{
- entry.Name = std::string(vs17generatorName);
- entry.Brief = "Generates Visual Studio 2022 project files. "
- "Use -A option to specify architecture.";
+ return { std::string(vs17generatorName),
+ "Generates Visual Studio 2022 project files. "
+ "Use -A option to specify architecture." };
}
std::vector<std::string> GetGeneratorNames() const override
@@ -521,6 +521,7 @@ bool cmGlobalVisualStudioVersionedGenerator::SetGeneratorInstance(
{
if (this->LastGeneratorInstanceString &&
i == *(this->LastGeneratorInstanceString)) {
+ this->SetVSVersionVar(mf);
return true;
}
@@ -531,7 +532,7 @@ bool cmGlobalVisualStudioVersionedGenerator::SetGeneratorInstance(
if (!this->GeneratorInstanceVersion.empty()) {
std::string const majorStr = VSVersionToMajorString(this->Version);
cmsys::RegularExpression versionRegex(
- cmStrCat("^", majorStr, "\\.[0-9]+\\.[0-9]+\\.[0-9]+$"));
+ cmStrCat("^", majorStr, R"(\.[0-9]+\.[0-9]+\.[0-9]+$)"));
if (!versionRegex.find(this->GeneratorInstanceVersion)) {
std::ostringstream e;
/* clang-format off */
@@ -592,6 +593,8 @@ bool cmGlobalVisualStudioVersionedGenerator::SetGeneratorInstance(
cmStateEnums::INTERNAL);
}
+ this->SetVSVersionVar(mf);
+
// The selected instance may have a different MSBuild than previously found.
this->MSBuildCommandInitialized = false;
@@ -607,7 +610,7 @@ bool cmGlobalVisualStudioVersionedGenerator::ParseGeneratorInstance(
this->GeneratorInstanceVersion.clear();
std::vector<std::string> const fields = cmTokenize(is, ",");
- std::vector<std::string>::const_iterator fi = fields.begin();
+ auto fi = fields.begin();
if (fi == fields.end()) {
return true;
}
@@ -672,6 +675,13 @@ bool cmGlobalVisualStudioVersionedGenerator::ParseGeneratorInstance(
return true;
}
+void cmGlobalVisualStudioVersionedGenerator::SetVSVersionVar(cmMakefile* mf)
+{
+ if (cm::optional<std::string> vsVer = this->GetVSInstanceVersion()) {
+ mf->AddDefinition("CMAKE_VS_VERSION_BUILD_NUMBER", *vsVer);
+ }
+}
+
bool cmGlobalVisualStudioVersionedGenerator::ProcessGeneratorInstanceField(
std::string const& key, std::string const& value)
{
@@ -901,9 +911,8 @@ bool cmGlobalVisualStudioVersionedGenerator::SelectWindowsStoreToolset(
this->IsWindowsDesktopToolsetInstalled()) {
toolset = VSVersionToToolset(this->Version);
return true;
- } else {
- return false;
}
+ return false;
}
return this->cmGlobalVisualStudio14Generator::SelectWindowsStoreToolset(
toolset);
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.h b/Source/cmGlobalVisualStudioVersionedGenerator.h
index 2e573ec..45aca74 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.h
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.h
@@ -46,6 +46,16 @@ public:
const char* GetAndroidApplicationTypeRevision() const override;
+ bool CheckCxxModuleSupport() override
+ {
+ this->CxxModuleSupportCheck();
+ return this->SupportsCxxModuleDyndep();
+ }
+ bool SupportsCxxModuleDyndep() const override
+ {
+ return this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS17;
+ }
+
protected:
cmGlobalVisualStudioVersionedGenerator(
VSVersion version, cmake* cm, const std::string& name,
@@ -83,6 +93,7 @@ private:
mutable cmVSSetupAPIHelper vsSetupAPIHelper;
bool ParseGeneratorInstance(std::string const& is, cmMakefile* mf);
+ void SetVSVersionVar(cmMakefile* mf);
std::string GeneratorInstance;
std::string GeneratorInstanceVersion;
diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx
index fb2a8b6..ed44e6b 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.cxx
+++ b/Source/cmGlobalWatcomWMakeGenerator.cxx
@@ -4,7 +4,6 @@
#include <ostream>
-#include "cmDocumentationEntry.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
@@ -54,11 +53,10 @@ bool cmGlobalWatcomWMakeGenerator::SetSystemName(std::string const& s,
return this->cmGlobalUnixMakefileGenerator3::SetSystemName(s, mf);
}
-void cmGlobalWatcomWMakeGenerator::GetDocumentation(
- cmDocumentationEntry& entry)
+cmDocumentationEntry cmGlobalWatcomWMakeGenerator::GetDocumentation()
{
- entry.Name = cmGlobalWatcomWMakeGenerator::GetActualName();
- entry.Brief = "Generates Watcom WMake makefiles.";
+ return { cmGlobalWatcomWMakeGenerator::GetActualName(),
+ "Generates Watcom WMake makefiles." };
}
std::vector<cmGlobalGenerator::GeneratedMakeCommand>
diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h
index eb93934..5579120 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.h
+++ b/Source/cmGlobalWatcomWMakeGenerator.h
@@ -15,7 +15,6 @@
class cmMakefile;
class cmake;
-struct cmDocumentationEntry;
/** \class cmGlobalWatcomWMakeGenerator
* \brief Write a NMake makefiles.
@@ -39,7 +38,7 @@ public:
static std::string GetActualName() { return "Watcom WMake"; }
/** Get the documentation entry for this generator. */
- static void GetDocumentation(cmDocumentationEntry& entry);
+ static cmDocumentationEntry GetDocumentation();
/** Tell the generator about the target system. */
bool SetSystemName(std::string const& s, cmMakefile* mf) override;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 116e510..f19dfd5 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -13,6 +13,7 @@
#include <utility>
#include <cm/memory>
+#include <cm/optional>
#include <cmext/algorithm>
#include <cmext/string_view>
@@ -24,7 +25,6 @@
#include "cmCustomCommandGenerator.h"
#include "cmCustomCommandLines.h"
#include "cmCustomCommandTypes.h"
-#include "cmDocumentationEntry.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -149,9 +149,9 @@ public:
std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
const std::string& name, bool allowArch, cmake* cm) const override;
- void GetDocumentation(cmDocumentationEntry& entry) const override
+ cmDocumentationEntry GetDocumentation() const override
{
- cmGlobalXCodeGenerator::GetDocumentation(entry);
+ return cmGlobalXCodeGenerator::GetDocumentation();
}
std::vector<std::string> GetGeneratorNames() const override
@@ -2281,11 +2281,11 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile(
}
makefileStream << "\n";
- if (const char* comment = ccg.GetComment()) {
+ if (cm::optional<std::string> comment = ccg.GetComment()) {
std::string echo_cmd =
cmStrCat("echo ",
(this->CurrentLocalGenerator->EscapeForShell(
- comment, ccg.GetCC().GetEscapeAllowMakeVars())));
+ *comment, ccg.GetCC().GetEscapeAllowMakeVars())));
makefileStream << "\t" << echo_cmd << "\n";
}
@@ -3623,7 +3623,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
}
// Add a pair of config and item to target-item map
auto& itemVector = targetItemMap[libName];
- itemVector.emplace_back(ConfigItemPair(configName, &libItem));
+ itemVector.emplace_back(configName, &libItem);
// Add product file-name to a lib-product map
auto productName =
cmSystemTools::GetFilenameName(libItem.Value.Value);
@@ -3962,7 +3962,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
void cmGlobalXCodeGenerator::AddEmbeddedObjects(
cmXCodeObject* target, const std::string& copyFilesBuildPhaseName,
const std::string& embedPropertyName, const std::string& dstSubfolderSpec,
- int actionsOnByDefault)
+ int actionsOnByDefault, const std::string& defaultDstPath)
{
cmGeneratorTarget* gt = target->GetTarget();
if (!gt) {
@@ -3998,7 +3998,8 @@ void cmGlobalXCodeGenerator::AddEmbeddedObjects(
copyFilesBuildPhase->AddAttribute("dstPath",
this->CreateString(*fwEmbedPath));
} else {
- copyFilesBuildPhase->AddAttribute("dstPath", this->CreateString(""));
+ copyFilesBuildPhase->AddAttribute("dstPath",
+ this->CreateString(defaultDstPath));
}
copyFilesBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
this->CreateString("0"));
@@ -4124,6 +4125,17 @@ void cmGlobalXCodeGenerator::AddEmbeddedAppExtensions(cmXCodeObject* target)
RemoveHeadersOnCopyByDefault);
}
+void cmGlobalXCodeGenerator::AddEmbeddedExtensionKitExtensions(
+ cmXCodeObject* target)
+{
+ static const auto dstSubfolderSpec = "16";
+
+ this->AddEmbeddedObjects(target, "Embed App Extensions",
+ "XCODE_EMBED_EXTENSIONKIT_EXTENSIONS",
+ dstSubfolderSpec, RemoveHeadersOnCopyByDefault,
+ "$(EXTENSIONS_FOLDER_PATH)");
+}
+
bool cmGlobalXCodeGenerator::CreateGroups(
std::vector<cmLocalGenerator*>& generators)
{
@@ -4369,7 +4381,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
cmXCodeObject* config =
this->CreateObject(cmXCodeObject::XCBuildConfiguration);
config->AddAttribute("name", this->CreateString(name));
- configs.push_back(std::make_pair(name, config));
+ configs.emplace_back(name, config);
}
if (defaultConfigName.empty()) {
defaultConfigName = "Debug";
@@ -4444,12 +4456,20 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
buildSettings->AddAttribute("CODE_SIGNING_ALLOWED",
this->CreateString("NO"));
}
+ auto debugConfigs = this->GetCMakeInstance()->GetDebugConfigs();
+ std::set<std::string> debugConfigSet(debugConfigs.begin(),
+ debugConfigs.end());
for (auto& config : configs) {
CreateGlobalXCConfigSettings(root, config.second, config.first);
cmXCodeObject* buildSettingsForCfg = this->CreateFlatClone(buildSettings);
+ if (debugConfigSet.count(cmSystemTools::UpperCase(config.first)) == 0) {
+ buildSettingsForCfg->AddAttribute("SWIFT_COMPILATION_MODE",
+ this->CreateString("wholemodule"));
+ }
+
// Put this last so it can override existing settings
// Convert "CMAKE_XCODE_ATTRIBUTE_*" variables directly.
for (const auto& var : this->CurrentMakefile->GetDefinitions()) {
@@ -4507,6 +4527,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
this->AddEmbeddedFrameworks(t);
this->AddEmbeddedPlugIns(t);
this->AddEmbeddedAppExtensions(t);
+ this->AddEmbeddedExtensionKitExtensions(t);
// Inherit project-wide values for any target-specific search paths.
this->InheritBuildSettingAttribute(t, "HEADER_SEARCH_PATHS");
this->InheritBuildSettingAttribute(t, "SYSTEM_HEADER_SEARCH_PATHS");
@@ -4888,10 +4909,10 @@ std::string cmGlobalXCodeGenerator::ExpandCFGIntDir(
return tmp;
}
-void cmGlobalXCodeGenerator::GetDocumentation(cmDocumentationEntry& entry)
+cmDocumentationEntry cmGlobalXCodeGenerator::GetDocumentation()
{
- entry.Name = cmGlobalXCodeGenerator::GetActualName();
- entry.Brief = "Generate Xcode project files.";
+ return { cmGlobalXCodeGenerator::GetActualName(),
+ "Generate Xcode project files." };
}
std::string cmGlobalXCodeGenerator::ConvertToRelativeForMake(
@@ -4974,7 +4995,13 @@ void cmGlobalXCodeGenerator::AppendDefines(
std::string def;
for (auto const& define : defines) {
// Start with -D if requested.
- def = cmStrCat(dflag ? "-D" : "", define);
+ if (dflag && !cmHasLiteralPrefix(define, "-D")) {
+ def = cmStrCat("-D", define);
+ } else if (!dflag && cmHasLiteralPrefix(define, "-D")) {
+ def = define.substr(2);
+ } else {
+ def = define;
+ }
// Append the flag with needed escapes.
std::string tmp;
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 9ae75fb..1fdd189 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -14,6 +14,7 @@
#include <cm/optional>
#include <cm/string_view>
+#include "cmDocumentationEntry.h"
#include "cmGlobalGenerator.h"
#include "cmTransformDepfile.h"
#include "cmValue.h"
@@ -28,7 +29,6 @@ class cmMakefile;
class cmSourceFile;
class cmSourceGroup;
class cmake;
-struct cmDocumentationEntry;
/** \class cmGlobalXCodeGenerator
* \brief Write a Unix makefiles.
@@ -54,7 +54,7 @@ public:
static std::string GetActualName() { return "Xcode"; }
/** Get the documentation entry for this generator. */
- static void GetDocumentation(cmDocumentationEntry& entry);
+ static cmDocumentationEntry GetDocumentation();
//! Create a local generator appropriate to this Global Generator
std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
@@ -218,10 +218,12 @@ private:
const std::string& copyFilesBuildPhaseName,
const std::string& embedPropertyName,
const std::string& dstSubfolderSpec,
- int actionsOnByDefault);
+ int actionsOnByDefault,
+ const std::string& defaultDstPath = "");
void AddEmbeddedFrameworks(cmXCodeObject* target);
void AddEmbeddedPlugIns(cmXCodeObject* target);
void AddEmbeddedAppExtensions(cmXCodeObject* target);
+ void AddEmbeddedExtensionKitExtensions(cmXCodeObject* target);
void AddPositionIndependentLinkAttribute(cmGeneratorTarget* target,
cmXCodeObject* buildSettings,
const std::string& configName);
diff --git a/Source/cmIDEOptions.cxx b/Source/cmIDEOptions.cxx
index c09aa46..9468d4a 100644
--- a/Source/cmIDEOptions.cxx
+++ b/Source/cmIDEOptions.cxx
@@ -20,15 +20,13 @@ cmIDEOptions::cmIDEOptions()
this->AllowDefine = true;
this->DoingInclude = false;
this->AllowSlash = false;
- this->DoingFollowing = 0;
- for (int i = 0; i < FlagTableCount; ++i) {
- this->FlagTable[i] = 0;
+ this->DoingFollowing = nullptr;
+ for (auto& flag : this->FlagTable) {
+ flag = nullptr;
}
}
-cmIDEOptions::~cmIDEOptions()
-{
-}
+cmIDEOptions::~cmIDEOptions() = default;
void cmIDEOptions::HandleFlag(std::string const& flag)
{
@@ -49,7 +47,7 @@ void cmIDEOptions::HandleFlag(std::string const& flag)
// If the last option expected a following value, this is it.
if (this->DoingFollowing) {
this->FlagMapUpdate(this->DoingFollowing, flag);
- this->DoingFollowing = 0;
+ this->DoingFollowing = nullptr;
return;
}
@@ -248,8 +246,7 @@ bool cmIDEOptions::HasFlag(std::string const& flag) const
const char* cmIDEOptions::GetFlag(std::string const& flag) const
{
// This method works only for single-valued flags!
- std::map<std::string, FlagValue>::const_iterator i =
- this->FlagMap.find(flag);
+ auto i = this->FlagMap.find(flag);
if (i != this->FlagMap.cend() && i->second.size() == 1) {
return i->second[0].c_str();
}
diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx
index 0974eea..5bf8320 100644
--- a/Source/cmInstalledFile.cxx
+++ b/Source/cmInstalledFile.cxx
@@ -21,7 +21,7 @@ cmInstalledFile::Property::~Property() = default;
void cmInstalledFile::SetName(cmMakefile* mf, const std::string& name)
{
cmListFileBacktrace backtrace = mf->GetBacktrace();
- cmGeneratorExpression ge(backtrace);
+ cmGeneratorExpression ge(*mf->GetCMakeInstance(), backtrace);
this->Name = name;
this->NameExpression = ge.Parse(name);
@@ -56,7 +56,7 @@ void cmInstalledFile::AppendProperty(cmMakefile const* mf,
bool /*asString*/)
{
cmListFileBacktrace backtrace = mf->GetBacktrace();
- cmGeneratorExpression ge(backtrace);
+ cmGeneratorExpression ge(*mf->GetCMakeInstance(), backtrace);
Property& property = this->Properties[prop];
property.ValueExpressions.push_back(ge.Parse(value));
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index b2b724a..cedb367 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1021,12 +1021,6 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
}
}
- std::string compReqFlag;
- this->AddCompilerRequirementFlag(compReqFlag, target, lang, config);
- if (!compReqFlag.empty()) {
- flags.emplace_back(std::move(compReqFlag));
- }
-
// Add Warning as errors flags
if (!this->GetCMakeInstance()->GetIgnoreWarningAsError()) {
const cmValue wError = target->GetProperty("COMPILE_WARNING_AS_ERROR");
@@ -1932,6 +1926,30 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
this->AddConfigVariableFlags(flags, cmStrCat("CMAKE_", lang, "_FLAGS"),
config);
+ // Add the language standard flag for compiling, and sometimes linking.
+ if (compileOrLink == cmBuildStep::Compile ||
+ (compileOrLink == cmBuildStep::Link &&
+ // Some toolchains require use of the language standard flag
+ // when linking in order to use the matching standard library.
+ // FIXME: If CMake gains an abstraction for standard library
+ // selection, this will have to be reconciled with it.
+ this->Makefile->IsOn(
+ cmStrCat("CMAKE_", lang, "_LINK_WITH_STANDARD_COMPILE_OPTION")))) {
+ cmStandardLevelResolver standardResolver(this->Makefile);
+ std::string const& optionFlagDef =
+ standardResolver.GetCompileOptionDef(target, lang, config);
+ if (!optionFlagDef.empty()) {
+ cmValue opt =
+ target->Target->GetMakefile()->GetDefinition(optionFlagDef);
+ if (opt) {
+ std::vector<std::string> optVec = cmExpandedList(*opt);
+ for (std::string const& i : optVec) {
+ this->AppendFlagEscape(flags, i);
+ }
+ }
+ }
+ }
+
std::string compiler = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", lang, "_COMPILER_ID"));
@@ -2076,15 +2094,6 @@ void cmLocalGenerator::AddLanguageFlagsForLinking(
std::string& flags, cmGeneratorTarget const* target, const std::string& lang,
const std::string& config)
{
- if (this->Makefile->IsOn("CMAKE_" + lang +
- "_LINK_WITH_STANDARD_COMPILE_OPTION")) {
- // This toolchain requires use of the language standard flag
- // when linking in order to use the matching standard library.
- // FIXME: If CMake gains an abstraction for standard library
- // selection, this will have to be reconciled with it.
- this->AddCompilerRequirementFlag(flags, target, lang, config);
- }
-
this->AddLanguageFlags(flags, target, cmBuildStep::Link, lang, config);
if (target->IsIPOEnabled(lang, config)) {
@@ -2224,25 +2233,6 @@ void cmLocalGenerator::AddSharedFlags(std::string& flags,
}
}
-void cmLocalGenerator::AddCompilerRequirementFlag(
- std::string& flags, cmGeneratorTarget const* target, const std::string& lang,
- const std::string& config)
-{
- cmStandardLevelResolver standardResolver(this->Makefile);
-
- std::string const& optionFlagDef =
- standardResolver.GetCompileOptionDef(target, lang, config);
- if (!optionFlagDef.empty()) {
- cmValue opt = target->Target->GetMakefile()->GetDefinition(optionFlagDef);
- if (opt) {
- std::vector<std::string> optVec = cmExpandedList(*opt);
- for (std::string const& i : optVec) {
- this->AppendFlagEscape(flags, i);
- }
- }
- }
-}
-
static void AddVisibilityCompileOption(std::string& flags,
cmGeneratorTarget const* target,
cmLocalGenerator* lg,
@@ -3387,7 +3377,12 @@ void cmLocalGenerator::AppendDefines(
if (!this->CheckDefinition(d.Value)) {
continue;
}
- defines.insert(d);
+ // remove any leading -D
+ if (cmHasLiteralPrefix(d.Value, "-D")) {
+ defines.emplace(d.Value.substr(2), d.Backtrace);
+ } else {
+ defines.insert(d);
+ }
}
}
@@ -3484,8 +3479,8 @@ std::string cmLocalGenerator::ConstructComment(
cmCustomCommandGenerator const& ccg, const char* default_comment) const
{
// Check for a comment provided with the command.
- if (ccg.GetComment()) {
- return ccg.GetComment();
+ if (cm::optional<std::string> comment = ccg.GetComment()) {
+ return *comment;
}
// Construct a reasonable default comment if possible.
@@ -4505,7 +4500,7 @@ std::vector<std::string> cmLocalGenerator::ExpandCustomCommandOutputGenex(
std::string const& o, cmListFileBacktrace const& bt)
{
std::vector<std::string> allConfigOutputs;
- cmGeneratorExpression ge(bt);
+ cmGeneratorExpression ge(*this->GetCMakeInstance(), bt);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(o);
std::vector<std::string> configs =
this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 765441c..20f23de 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -164,10 +164,6 @@ public:
const std::string& lang);
void AddConfigVariableFlags(std::string& flags, const std::string& var,
const std::string& config);
- void AddCompilerRequirementFlag(std::string& flags,
- cmGeneratorTarget const* target,
- const std::string& lang,
- const std::string& config);
void AddColorDiagnosticsFlags(std::string& flags, const std::string& lang);
//! Append flags to a string.
virtual void AppendFlags(std::string& flags,
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index c11f5b4..1e2ea2a 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -701,7 +701,7 @@ bool cmLocalNinjaGenerator::HasUniqueByproducts(
{
std::vector<std::string> configs =
this->GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
- cmGeneratorExpression ge(bt);
+ cmGeneratorExpression ge(*this->GetCMakeInstance(), bt);
for (std::string const& p : byproducts) {
if (cmGeneratorExpression::Find(p) == std::string::npos) {
return false;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index de1d3cd..7172d34 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -10,6 +10,7 @@
#include <utility>
#include <cm/memory>
+#include <cm/optional>
#include <cm/string_view>
#include <cm/vector>
#include <cmext/algorithm>
@@ -945,9 +946,8 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
// post-build command comments. Custom build step commands have
// their comments generated elsewhere.
if (echo_comment) {
- const char* comment = ccg.GetComment();
- if (comment && *comment) {
- this->AppendEcho(commands, comment,
+ if (cm::optional<std::string> comment = ccg.GetComment()) {
+ this->AppendEcho(commands, *comment,
cmLocalUnixMakefileGenerator3::EchoGenerate);
}
}
diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx
index 4c0d2eea..8fe6677 100644
--- a/Source/cmLocalVisualStudio10Generator.cxx
+++ b/Source/cmLocalVisualStudio10Generator.cxx
@@ -18,8 +18,8 @@ class cmGeneratorTarget;
class cmVS10XMLParser : public cmXMLParser
{
public:
- virtual void EndElement(const std::string& /* name */) {}
- virtual void CharacterDataHandler(const char* data, int length)
+ void EndElement(const std::string& /* name */) override {}
+ void CharacterDataHandler(const char* data, int length) override
{
if (this->DoGUID) {
if (data[0] == '{') {
@@ -31,7 +31,7 @@ public:
this->DoGUID = false;
}
}
- virtual void StartElement(const std::string& name, const char**)
+ void StartElement(const std::string& name, const char**) override
{
// once the GUID is found do nothing
if (!this->GUID.empty()) {
@@ -41,7 +41,7 @@ public:
this->DoGUID = true;
}
}
- int InitializeParser()
+ int InitializeParser() override
{
this->DoGUID = false;
int ret = cmXMLParser::InitializeParser();
@@ -63,9 +63,7 @@ cmLocalVisualStudio10Generator::cmLocalVisualStudio10Generator(
{
}
-cmLocalVisualStudio10Generator::~cmLocalVisualStudio10Generator()
-{
-}
+cmLocalVisualStudio10Generator::~cmLocalVisualStudio10Generator() = default;
void cmLocalVisualStudio10Generator::GenerateTarget(cmGeneratorTarget* target)
{
diff --git a/Source/cmLocalVisualStudio10Generator.h b/Source/cmLocalVisualStudio10Generator.h
index 7bfe3b7..fe44bb5 100644
--- a/Source/cmLocalVisualStudio10Generator.h
+++ b/Source/cmLocalVisualStudio10Generator.h
@@ -24,7 +24,7 @@ public:
//! Set cache only and recurse to false by default.
cmLocalVisualStudio10Generator(cmGlobalGenerator* gg, cmMakefile* mf);
- virtual ~cmLocalVisualStudio10Generator();
+ ~cmLocalVisualStudio10Generator() override;
void ReadAndStoreExternalGUID(const std::string& name,
const char* path) override;
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index af2d31d..ded1647 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -10,6 +10,7 @@
#include <utility>
#include <cm/memory>
+#include <cm/optional>
#include <cmext/algorithm>
#include <windows.h>
@@ -56,7 +57,7 @@ public:
using ItemVector = cmComputeLinkInformation::ItemVector;
void OutputLibraries(std::ostream& fout, ItemVector const& libs);
void OutputObjects(std::ostream& fout, cmGeneratorTarget* t,
- std::string const& config, const char* isep = 0);
+ std::string const& config, const char* isep = nullptr);
private:
cmLocalVisualStudio7Generator* LocalGenerator;
@@ -107,8 +108,8 @@ void cmLocalVisualStudio7Generator::Generate()
}
auto& gtVisited = this->GetSourcesVisited(gt);
- auto& deps = this->GlobalGenerator->GetTargetDirectDepends(gt);
- for (auto& d : deps) {
+ auto const& deps = this->GlobalGenerator->GetTargetDirectDepends(gt);
+ for (auto const& d : deps) {
// Take the union of visited source files of custom commands
auto depVisited = this->GetSourcesVisited(d);
gtVisited.insert(depVisited.begin(), depVisited.end());
@@ -126,7 +127,7 @@ void cmLocalVisualStudio7Generator::FixGlobalTargets()
// commands for targets in which no sources are built. Add dummy
// rules to force these targets to build.
const auto& tgts = this->GetGeneratorTargets();
- for (auto& l : tgts) {
+ for (auto const& l : tgts) {
if (l->GetType() == cmStateEnums::GLOBAL_TARGET) {
cmCustomCommandLines force_commands =
cmMakeSingleCommandLine({ "cd", "." });
@@ -178,8 +179,7 @@ void cmLocalVisualStudio7Generator::WriteStampFiles()
// Sort the list of input files and remove duplicates.
std::sort(listFiles.begin(), listFiles.end(), std::less<std::string>());
- std::vector<std::string>::iterator new_end =
- std::unique(listFiles.begin(), listFiles.end());
+ auto new_end = std::unique(listFiles.begin(), listFiles.end());
listFiles.erase(new_end, listFiles.end());
for (const std::string& lf : listFiles) {
@@ -216,7 +216,7 @@ void cmLocalVisualStudio7Generator::GenerateTarget(cmGeneratorTarget* target)
// Generate the project file and replace it atomically with
// copy-if-different. We use a separate timestamp so that the IDE
// does not reload project files unnecessarily.
- cmGeneratedFileStream fout(fname.c_str());
+ cmGeneratedFileStream fout(fname);
fout.SetCopyIfDifferent(true);
this->WriteVCProjFile(fout, lname, target);
if (fout.Close()) {
@@ -252,8 +252,7 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
// Sort the list of input files and remove duplicates.
std::sort(listFiles.begin(), listFiles.end(), std::less<std::string>());
- std::vector<std::string>::iterator new_end =
- std::unique(listFiles.begin(), listFiles.end());
+ auto new_end = std::unique(listFiles.begin(), listFiles.end());
listFiles.erase(new_end, listFiles.end());
std::string argS = cmStrCat("-S", this->GetSourceDirectory());
@@ -279,10 +278,9 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
// the generator validated all project-named sources.
file->ResolveFullPath();
return file;
- } else {
- cmSystemTools::Error("Error adding rule for " + makefileIn);
- return nullptr;
}
+ cmSystemTools::Error("Error adding rule for " + makefileIn);
+ return nullptr;
}
void cmLocalVisualStudio7Generator::WriteConfigurations(
@@ -558,12 +556,11 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranLinkFlagTable[] = {
class cmLocalVisualStudio7Generator::EventWriter
{
public:
- EventWriter(cmLocalVisualStudio7Generator* lg, const std::string& config,
+ EventWriter(cmLocalVisualStudio7Generator* lg, std::string config,
std::ostream& os)
: LG(lg)
- , Config(config)
+ , Config(std::move(config))
, Stream(os)
- , First(true)
{
}
void Start(const char* tool)
@@ -592,9 +589,8 @@ public:
{
cmCustomCommandGenerator ccg(cc, this->Config, this->LG);
if (this->First) {
- const char* comment = ccg.GetComment();
- if (comment && *comment) {
- this->Stream << "\nDescription=\"" << this->LG->EscapeForXML(comment)
+ if (cm::optional<std::string> comment = ccg.GetComment()) {
+ this->Stream << "\nDescription=\"" << this->LG->EscapeForXML(*comment)
<< "\"";
}
this->Stream << "\nCommandLine=\"";
@@ -610,7 +606,7 @@ private:
cmLocalVisualStudio7Generator* LG;
std::string Config;
std::ostream& Stream;
- bool First;
+ bool First = true;
};
void cmLocalVisualStudio7Generator::WriteConfiguration(
@@ -634,7 +630,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
// 1 == executable
// 10 == utility
const char* configType = "10";
- const char* projectType = 0;
+ const char* projectType = nullptr;
bool targetBuilds = true;
switch (target->GetType()) {
@@ -842,8 +838,26 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
}
}
fout << "/>\n"; // end of <Tool Name=VCCLCompilerTool
+ if (gg->IsMarmasmEnabled() && !this->FortranProject) {
+ Options marmasmOptions(this, Options::MarmasmCompiler, nullptr, nullptr);
+ /* clang-format off */
+ fout <<
+ "\t\t\t<Tool\n"
+ "\t\t\t\tName=\"MARMASM\"\n"
+ ;
+ /* clang-format on */
+ targetOptions.OutputAdditionalIncludeDirectories(fout, 4, "ASM_MARMASM");
+ // Use same preprocessor definitions as VCCLCompilerTool.
+ targetOptions.OutputPreprocessorDefinitions(fout, 4, "ASM_MARMASM");
+ marmasmOptions.OutputFlagMap(fout, 4);
+ /* clang-format off */
+ fout <<
+ "\t\t\t\tObjectFile=\"$(IntDir)\\\"\n"
+ "\t\t\t/>\n";
+ /* clang-format on */
+ }
if (gg->IsMasmEnabled() && !this->FortranProject) {
- Options masmOptions(this, Options::MasmCompiler, 0, 0);
+ Options masmOptions(this, Options::MasmCompiler, nullptr, nullptr);
/* clang-format off */
fout <<
"\t\t\t<Tool\n"
@@ -939,7 +953,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
}
std::string cmLocalVisualStudio7Generator::GetBuildTypeLinkerFlags(
- std::string rootLinkerFlags, const std::string& configName)
+ std::string const& rootLinkerFlags, const std::string& configName)
{
std::string configTypeUpper = cmSystemTools::UpperCase(configName);
std::string extraLinkOptionsBuildTypeDef =
@@ -1421,8 +1435,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
fout << "\t<Files>\n";
// Loop through every source group.
- for (unsigned int i = 0; i < sourceGroups.size(); ++i) {
- cmSourceGroup sg = sourceGroups[i];
+ for (auto const& sg : sourceGroups) {
this->WriteGroup(&sg, target, fout, libName, configs, sources);
}
@@ -1616,10 +1629,9 @@ std::string cmLocalVisualStudio7Generator::ComputeLongestObjectDirectory(
// Compute the maximum length configuration name.
std::string config_max;
- for (std::vector<std::string>::iterator i = configs.begin();
- i != configs.end(); ++i) {
- if (i->size() > config_max.size()) {
- config_max = *i;
+ for (auto& config : configs) {
+ if (config.size() > config_max.size()) {
+ config_max = config;
}
}
@@ -1645,9 +1657,8 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
// Write the children to temporary output.
bool hasChildrenWithSources = false;
std::ostringstream tmpOut;
- for (unsigned int i = 0; i < children.size(); ++i) {
- if (this->WriteGroup(&children[i], target, tmpOut, libName, configs,
- sources)) {
+ for (const auto& child : children) {
+ if (this->WriteGroup(&child, target, tmpOut, libName, configs, sources)) {
hasChildrenWithSources = true;
}
}
@@ -1673,8 +1684,7 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
target->GetType() == cmStateEnums::GLOBAL_TARGET ||
target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
// Look up the source kind and configs.
- std::map<cmSourceFile const*, size_t>::const_iterator map_it =
- sources.Index.find(sf);
+ auto map_it = sources.Index.find(sf);
// The map entry must exist because we populated it earlier.
assert(map_it != sources.Index.end());
cmGeneratorTarget::AllConfigSource const& acs =
@@ -1720,6 +1730,10 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
aCompilerTool = "VFCustomBuildTool";
}
}
+ if (gg->IsMarmasmEnabled() && !this->FortranProject &&
+ lang == "ASM_MARMASM") {
+ aCompilerTool = "MARMASM";
+ }
if (gg->IsMasmEnabled() && !this->FortranProject &&
lang == "ASM_MASM") {
aCompilerTool = "MASM";
@@ -1921,7 +1935,7 @@ void cmLocalVisualStudio7Generator::OutputTargetRules(
}
std::unique_ptr<cmCustomCommand> pcc(
this->MaybeCreateImplibDir(target, configName, this->FortranProject));
- if (pcc.get()) {
+ if (pcc) {
event.Write(*pcc);
}
event.Finish();
@@ -1964,7 +1978,7 @@ void cmLocalVisualStudio7Generator::WriteProjectStartFortran(
cmGlobalVisualStudio7Generator* gg =
static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);
/* clang-format off */
- fout << "<?xml version=\"1.0\" encoding = \""
+ fout << R"(<?xml version="1.0" encoding = ")"
<< gg->Encoding() << "\"?>\n"
<< "<VisualStudioProject\n"
<< "\tProjectCreator=\"Intel Fortran\"\n"
@@ -1972,7 +1986,7 @@ void cmLocalVisualStudio7Generator::WriteProjectStartFortran(
/* clang-format on */
cmValue p = target->GetProperty("VS_KEYWORD");
const char* keyword = p ? p->c_str() : "Console Application";
- const char* projectType = 0;
+ const char* projectType = nullptr;
switch (target->GetType()) {
case cmStateEnums::OBJECT_LIBRARY:
case cmStateEnums::STATIC_LIBRARY:
@@ -1992,7 +2006,7 @@ void cmLocalVisualStudio7Generator::WriteProjectStartFortran(
if (!keyword) {
keyword = "Console Application";
}
- projectType = 0;
+ projectType = nullptr;
break;
case cmStateEnums::UTILITY:
case cmStateEnums::GLOBAL_TARGET:
@@ -2026,7 +2040,7 @@ void cmLocalVisualStudio7Generator::WriteProjectStart(
static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);
/* clang-format off */
- fout << "<?xml version=\"1.0\" encoding = \""
+ fout << R"(<?xml version="1.0" encoding = ")"
<< gg->Encoding() << "\"?>\n"
<< "<VisualStudioProject\n"
<< "\tProjectType=\"Visual C++\"\n";
@@ -2050,6 +2064,17 @@ void cmLocalVisualStudio7Generator::WriteProjectStart(
<< "\t\t<Platform\n\t\t\tName=\"" << gg->GetPlatformName() << "\"/>\n"
<< "\t</Platforms>\n";
/* clang-format on */
+ if (gg->IsMarmasmEnabled()) {
+ /* clang-format off */
+ fout <<
+ "\t<ToolFiles>\n"
+ "\t\t<DefaultToolFile\n"
+ "\t\t\tFileName=\"marmasm.rules\"\n"
+ "\t\t/>\n"
+ "\t</ToolFiles>\n"
+ ;
+ /* clang-format on */
+ }
if (gg->IsMasmEnabled()) {
/* clang-format off */
fout <<
@@ -2133,8 +2158,8 @@ void cmVS7GeneratorOptions::OutputFlag(std::ostream& fout, int indent,
class cmVS7XMLParser : public cmXMLParser
{
public:
- virtual void EndElement(const std::string& /* name */) {}
- virtual void StartElement(const std::string& name, const char** atts)
+ void EndElement(const std::string& /* name */) override {}
+ void StartElement(const std::string& name, const char** atts) override
{
// once the GUID is found do nothing
if (!this->GUID.empty()) {
@@ -2159,7 +2184,7 @@ public:
}
}
}
- int InitializeParser()
+ int InitializeParser() override
{
int ret = cmXMLParser::InitializeParser();
if (ret == 0) {
@@ -2202,7 +2227,7 @@ static bool cmLVS7G_IsFAT(const char* dir)
volRoot[0] = dir[0];
char fsName[16];
if (GetVolumeInformationA(volRoot, 0, 0, 0, 0, 0, fsName, 16) &&
- strstr(fsName, "FAT") != 0) {
+ strstr(fsName, "FAT") != nullptr) {
return true;
}
}
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index d95ebc2..ce1156f 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -48,7 +48,7 @@ public:
//! Set cache only and recurse to false by default.
cmLocalVisualStudio7Generator(cmGlobalGenerator* gg, cmMakefile* mf);
- virtual ~cmLocalVisualStudio7Generator();
+ ~cmLocalVisualStudio7Generator() override;
cmLocalVisualStudio7Generator(const cmLocalVisualStudio7Generator&) = delete;
const cmLocalVisualStudio7Generator& operator=(
@@ -97,7 +97,7 @@ protected:
private:
using Options = cmVS7GeneratorOptions;
using FCInfo = cmLocalVisualStudio7GeneratorFCInfo;
- std::string GetBuildTypeLinkerFlags(std::string rootLinkerFlags,
+ std::string GetBuildTypeLinkerFlags(std::string const& rootLinkerFlags,
const std::string& configName);
void FixGlobalTargets();
void WriteVCProjHeader(std::ostream& fout, const std::string& libName,
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
index 2703c7b..58d46f1 100644
--- a/Source/cmLocalVisualStudioGenerator.cxx
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -4,6 +4,8 @@
#include <utility>
+#include <cm/memory>
+
#include "windows.h"
#include "cmCustomCommand.h"
@@ -24,9 +26,7 @@ cmLocalVisualStudioGenerator::cmLocalVisualStudioGenerator(
{
}
-cmLocalVisualStudioGenerator::~cmLocalVisualStudioGenerator()
-{
-}
+cmLocalVisualStudioGenerator::~cmLocalVisualStudioGenerator() = default;
cmGlobalVisualStudioGenerator::VSVersion
cmLocalVisualStudioGenerator::GetVersion() const
@@ -107,7 +107,7 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmGeneratorTarget* target,
// Add a pre-build event to create the directory.
cmCustomCommandLines commands = cmMakeSingleCommandLine(
{ cmSystemTools::GetCMakeCommand(), "-E", "make_directory", impDir });
- pcc.reset(new cmCustomCommand());
+ pcc = cm::make_unique<cmCustomCommand>();
pcc->SetCommandLines(commands);
pcc->SetStdPipesUTF8(true);
pcc->SetEscapeOldStyle(false);
diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h
index cf4f4d9..8fed1bd 100644
--- a/Source/cmLocalVisualStudioGenerator.h
+++ b/Source/cmLocalVisualStudioGenerator.h
@@ -29,7 +29,7 @@ class cmLocalVisualStudioGenerator : public cmLocalGenerator
{
public:
cmLocalVisualStudioGenerator(cmGlobalGenerator* gg, cmMakefile* mf);
- virtual ~cmLocalVisualStudioGenerator();
+ ~cmLocalVisualStudioGenerator() override;
std::string ConstructScript(cmCustomCommandGenerator const& ccg,
const std::string& newline = "\n");
@@ -47,7 +47,7 @@ public:
void ComputeObjectFilenames(
std::map<cmSourceFile const*, std::string>& mapping,
- cmGeneratorTarget const* = 0) override;
+ cmGeneratorTarget const* = nullptr) override;
protected:
virtual const char* ReportErrorLabel() const;
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 6e0d704..db8f785 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -375,19 +375,28 @@ public:
++this->Makefile->RecursionDepth;
this->Makefile->ExecutionStatusStack.push_back(&status);
#if !defined(CMAKE_BOOTSTRAP)
- if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) {
- this->Makefile->GetCMakeInstance()->GetProfilingOutput().StartEntry(lff,
- lfc);
- }
+ this->ProfilingDataRAII =
+ this->Makefile->GetCMakeInstance()->CreateProfilingEntry(
+ "script", lff.LowerCaseName(), [&lff, &lfc]() -> Json::Value {
+ Json::Value argsValue = Json::objectValue;
+ if (!lff.Arguments().empty()) {
+ std::string args;
+ for (auto const& a : lff.Arguments()) {
+ args = cmStrCat(args, args.empty() ? "" : " ", a.Value);
+ }
+ argsValue["functionArgs"] = args;
+ }
+ argsValue["location"] =
+ cmStrCat(lfc.FilePath, ':', std::to_string(lfc.Line));
+ return argsValue;
+ });
#endif
}
~cmMakefileCall()
{
#if !defined(CMAKE_BOOTSTRAP)
- if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) {
- this->Makefile->GetCMakeInstance()->GetProfilingOutput().StopEntry();
- }
+ this->ProfilingDataRAII.reset();
#endif
this->Makefile->ExecutionStatusStack.pop_back();
--this->Makefile->RecursionDepth;
@@ -399,6 +408,9 @@ public:
private:
cmMakefile* Makefile;
+#if !defined(CMAKE_BOOTSTRAP)
+ cm::optional<cmMakefileProfilingData::RAII> ProfilingDataRAII;
+#endif
};
void cmMakefile::OnExecuteCommand(std::function<void()> callback)
@@ -3584,6 +3596,9 @@ int cmMakefile::TryCompile(const std::string& srcdir,
gg->RecursionDepth = this->RecursionDepth;
cm.SetGlobalGenerator(std::move(gg));
+ // copy trace state
+ cm.SetTraceRedirect(this->GetCMakeInstance());
+
// do a configure
cm.SetHomeDirectory(srcdir);
cm.SetHomeOutputDirectory(bindir);
@@ -4470,12 +4485,12 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
}
// Deprecate old policies.
- if (status == cmPolicies::OLD && id <= cmPolicies::CMP0102 &&
+ if (status == cmPolicies::OLD && id <= cmPolicies::CMP0108 &&
!(this->GetCMakeInstance()->GetIsInTryCompile() &&
(
// Policies set by cmCoreTryCompile::TryCompileCode.
id == cmPolicies::CMP0065 || id == cmPolicies::CMP0083 ||
- id == cmPolicies::CMP0091)) &&
+ id == cmPolicies::CMP0091 || id == cmPolicies::CMP0104)) &&
(!this->IsSet("CMAKE_WARN_DEPRECATED") ||
this->IsOn("CMAKE_WARN_DEPRECATED"))) {
this->IssueMessage(MessageType::DEPRECATION_WARNING,
diff --git a/Source/cmMakefileProfilingData.cxx b/Source/cmMakefileProfilingData.cxx
index 1cd97c9..e903ae1 100644
--- a/Source/cmMakefileProfilingData.cxx
+++ b/Source/cmMakefileProfilingData.cxx
@@ -4,7 +4,8 @@
#include <chrono>
#include <stdexcept>
-#include <vector>
+#include <type_traits>
+#include <utility>
#include <cm3p/json/value.h>
#include <cm3p/json/writer.h>
@@ -12,7 +13,6 @@
#include "cmsys/FStream.hxx"
#include "cmsys/SystemInformation.hxx"
-#include "cmListFileCache.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -43,8 +43,9 @@ cmMakefileProfilingData::~cmMakefileProfilingData() noexcept
}
}
-void cmMakefileProfilingData::StartEntry(const cmListFileFunction& lff,
- cmListFileContext const& lfc)
+void cmMakefileProfilingData::StartEntry(const std::string& category,
+ const std::string& name,
+ cm::optional<Json::Value> args)
{
/* Do not try again if we previously failed to write to output. */
if (!this->ProfileStream.good()) {
@@ -58,24 +59,17 @@ void cmMakefileProfilingData::StartEntry(const cmListFileFunction& lff,
cmsys::SystemInformation info;
Json::Value v;
v["ph"] = "B";
- v["name"] = lff.LowerCaseName();
- v["cat"] = "cmake";
+ v["name"] = name;
+ v["cat"] = category;
v["ts"] = static_cast<Json::Value::UInt64>(
std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now().time_since_epoch())
.count());
v["pid"] = static_cast<int>(info.GetProcessId());
v["tid"] = 0;
- Json::Value argsValue;
- if (!lff.Arguments().empty()) {
- std::string args;
- for (auto const& a : lff.Arguments()) {
- args += (args.empty() ? "" : " ") + a.Value;
- }
- argsValue["functionArgs"] = args;
+ if (args) {
+ v["args"] = *std::move(args);
}
- argsValue["location"] = lfc.FilePath + ":" + std::to_string(lfc.Line);
- v["args"] = argsValue;
this->JsonWriter->write(v, &this->ProfileStream);
} catch (std::ios_base::failure& fail) {
@@ -112,3 +106,36 @@ void cmMakefileProfilingData::StopEntry()
cmSystemTools::Error("Error writing profiling output!");
}
}
+
+cmMakefileProfilingData::RAII::RAII(cmMakefileProfilingData& data,
+ const std::string& category,
+ const std::string& name,
+ cm::optional<Json::Value> args)
+ : Data(&data)
+{
+ this->Data->StartEntry(category, name, std::move(args));
+}
+
+cmMakefileProfilingData::RAII::RAII(RAII&& other) noexcept
+ : Data(other.Data)
+{
+ other.Data = nullptr;
+}
+
+cmMakefileProfilingData::RAII::~RAII()
+{
+ if (this->Data) {
+ this->Data->StopEntry();
+ }
+}
+
+cmMakefileProfilingData::RAII& cmMakefileProfilingData::RAII::operator=(
+ RAII&& other) noexcept
+{
+ if (this->Data) {
+ this->Data->StopEntry();
+ }
+ this->Data = other.Data;
+ other.Data = nullptr;
+ return *this;
+}
diff --git a/Source/cmMakefileProfilingData.h b/Source/cmMakefileProfilingData.h
index a86764a..4cf0bfa 100644
--- a/Source/cmMakefileProfilingData.h
+++ b/Source/cmMakefileProfilingData.h
@@ -4,23 +4,45 @@
#include <memory>
#include <string>
+#include <cm/optional>
+
+#include <cm3p/json/value.h> // IWYU pragma: keep
+
#include "cmsys/FStream.hxx"
namespace Json {
class StreamWriter;
}
-class cmListFileContext;
-class cmListFileFunction;
-
class cmMakefileProfilingData
{
public:
cmMakefileProfilingData(const std::string&);
~cmMakefileProfilingData() noexcept;
- void StartEntry(const cmListFileFunction& lff, cmListFileContext const& lfc);
+ void StartEntry(const std::string& category, const std::string& name,
+ cm::optional<Json::Value> args = cm::nullopt);
void StopEntry();
+ class RAII
+ {
+ public:
+ RAII() = delete;
+ RAII(const RAII&) = delete;
+ RAII(RAII&&) noexcept;
+
+ RAII(cmMakefileProfilingData& data, const std::string& category,
+ const std::string& name,
+ cm::optional<Json::Value> args = cm::nullopt);
+
+ ~RAII();
+
+ RAII& operator=(const RAII&) = delete;
+ RAII& operator=(RAII&&) noexcept;
+
+ private:
+ cmMakefileProfilingData* Data = nullptr;
+ };
+
private:
cmsys::ofstream ProfileStream;
std::unique_ptr<Json::StreamWriter> JsonWriter;
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index d19bbb9..20cc2c3 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -25,6 +25,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
+#include "cmGlobalCommonGenerator.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLinkLineComputer.h" // IWYU pragma: keep
#include "cmLocalCommonGenerator.h"
@@ -1031,7 +1032,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
}
this->GlobalGenerator->AddCXXCompileCommand(
- source.GetFullPath(), workingDirectory, compileCommand);
+ source.GetFullPath(), workingDirectory, compileCommand, relativeObj);
}
// See if we need to use a compiler launcher like ccache or distcc
@@ -1107,8 +1108,29 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
} else {
driverMode = lang == "C" ? "gcc" : "g++";
}
+ std::string d =
+ this->GeneratorTarget->GetClangTidyExportFixesDirectory(lang);
+ std::string exportFixes;
+ if (!d.empty()) {
+ this->GlobalCommonGenerator->AddClangTidyExportFixesDir(d);
+ std::string fixesFile = cmSystemTools::CollapseFullPath(cmStrCat(
+ d, '/',
+ this->LocalGenerator->MaybeRelativeToTopBinDir(cmStrCat(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
+ this->LocalGenerator->GetTargetDirectory(
+ this->GeneratorTarget),
+ '/', objectName, ".yaml"))));
+ this->GlobalCommonGenerator->AddClangTidyExportFixesFile(
+ fixesFile);
+ cmSystemTools::MakeDirectory(
+ cmSystemTools::GetFilenamePath(fixesFile));
+ fixesFile =
+ this->LocalGenerator->MaybeRelativeToCurBinDir(fixesFile);
+ exportFixes = cmStrCat(";--export-fixes=", fixesFile);
+ }
run_iwyu += this->LocalGenerator->EscapeForShell(
- cmStrCat(*tidy, ";--extra-arg-before=--driver-mode=", driverMode));
+ cmStrCat(*tidy, ";--extra-arg-before=--driver-mode=", driverMode,
+ exportFixes));
}
if (cmNonempty(cpplint)) {
run_iwyu += " --cpplint=";
@@ -2249,6 +2271,7 @@ void cmMakefileTargetGenerator::CreateObjectLists(
std::string responseFileName =
(responseMode == Link) ? "objects" : "deviceObjects";
responseFileName += std::to_string(i + 1);
+ responseFileName += ".rsp";
// Create this response file.
std::string objects_rsp = this->CreateResponseFile(
diff --git a/Source/cmMessenger.cxx b/Source/cmMessenger.cxx
index 333003b..ff513be 100644
--- a/Source/cmMessenger.cxx
+++ b/Source/cmMessenger.cxx
@@ -107,8 +107,8 @@ static void printMessageText(std::ostream& msg, std::string const& text)
{
msg << ":\n";
cmDocumentationFormatter formatter;
- formatter.SetIndent(" ");
- formatter.PrintFormatted(msg, text.c_str());
+ formatter.SetIndent(2u);
+ formatter.PrintFormatted(msg, text);
}
static void displayMessage(MessageType t, std::ostringstream& msg)
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index bda8a5f..6ec1781 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -64,9 +64,9 @@ void cmNinjaNormalTargetGenerator::Generate(const std::string& config)
{
std::string lang = this->GeneratorTarget->GetLinkerLanguage(config);
if (this->TargetLinkLanguage(config).empty()) {
- cmSystemTools::Error("CMake can not determine linker language for "
- "target: " +
- this->GetGeneratorTarget()->GetName());
+ cmSystemTools::Error(
+ cmStrCat("CMake can not determine linker language for target: ",
+ this->GetGeneratorTarget()->GetName()));
return;
}
@@ -117,7 +117,7 @@ void cmNinjaNormalTargetGenerator::WriteLanguagesRules(
#ifdef NINJA_GEN_VERBOSE_FILES
cmGlobalNinjaGenerator::WriteDivider(this->GetRulesFileStream());
this->GetRulesFileStream()
- << "# Rules for each languages for "
+ << "# Rules for each language for "
<< cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType())
<< " target " << this->GetTargetName() << "\n\n";
#endif
@@ -372,7 +372,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
vars.SwiftLibraryName = "$SWIFT_LIBRARY_NAME";
vars.SwiftModule = "$SWIFT_MODULE";
vars.SwiftModuleName = "$SWIFT_MODULE_NAME";
- vars.SwiftOutputFileMap = "$SWIFT_OUTPUT_FILE_MAP";
vars.SwiftSources = "$SWIFT_SOURCES";
vars.Defines = "$DEFINES";
@@ -1072,12 +1071,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
cmOutputConverter::SHELL);
}(vars["SWIFT_MODULE_NAME"]);
- const std::string map = cmStrCat(gt->GetSupportDirectory(), '/', config,
- '/', "output-file-map.json");
- vars["SWIFT_OUTPUT_FILE_MAP"] =
- this->GetLocalGenerator()->ConvertToOutputFormat(
- this->ConvertToNinjaPath(map), cmOutputConverter::SHELL);
-
vars["SWIFT_SOURCES"] = [this, config]() -> std::string {
std::vector<cmSourceFile const*> sources;
std::stringstream oss;
@@ -1101,6 +1094,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
vars["DEFINES"] = this->GetDefines("Swift", config);
vars["FLAGS"] = this->GetFlags("Swift", config);
vars["INCLUDES"] = this->GetIncludes("Swift", config);
+ this->GenerateSwiftOutputFileMap(config, vars["FLAGS"]);
}
// Compute specific libraries to link with.
@@ -1118,7 +1112,9 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
this->GetObjectFilePath(source, config));
}
}
- linkBuild.Outputs.push_back(vars["SWIFT_MODULE"]);
+ if (targetType != cmStateEnums::EXECUTABLE) {
+ linkBuild.Outputs.push_back(vars["SWIFT_MODULE"]);
+ }
} else {
linkBuild.ExplicitDeps = this->GetObjects(config);
}
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index e4427f5..6887376 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -4,6 +4,7 @@
#include <algorithm>
#include <cassert>
+#include <functional>
#include <iterator>
#include <map>
#include <ostream>
@@ -21,17 +22,13 @@
#include "cmComputeLinkInformation.h"
#include "cmCustomCommandGenerator.h"
-#include "cmExportBuildFileGenerator.h"
-#include "cmExportSet.h"
+#include "cmDyndepCollation.h"
#include "cmFileSet.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
+#include "cmGlobalCommonGenerator.h"
#include "cmGlobalNinjaGenerator.h"
-#include "cmInstallCxxModuleBmiGenerator.h"
-#include "cmInstallExportGenerator.h"
-#include "cmInstallFileSetGenerator.h"
-#include "cmInstallGenerator.h"
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
#include "cmMakefile.h"
@@ -47,7 +44,6 @@
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
-#include "cmTargetExport.h"
#include "cmValue.h"
#include "cmake.h"
@@ -109,12 +105,13 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const
}
std::string cmNinjaTargetGenerator::LanguageCompilerRule(
- const std::string& lang, const std::string& config) const
+ const std::string& lang, const std::string& config,
+ WithScanning withScanning) const
{
return cmStrCat(
lang, "_COMPILER__",
cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
- '_', config);
+ withScanning == WithScanning::Yes ? "_scanned_" : "_unscanned_", config);
}
std::string cmNinjaTargetGenerator::LanguagePreprocessAndScanRule(
@@ -156,23 +153,6 @@ std::string cmNinjaTargetGenerator::LanguageDyndepRule(
'_', config);
}
-bool cmNinjaTargetGenerator::NeedCxxModuleSupport(
- std::string const& lang, std::string const& config) const
-{
- if (lang != "CXX"_s) {
- return false;
- }
- return this->GetGeneratorTarget()->HaveCxxModuleSupport(config) ==
- cmGeneratorTarget::Cxx20SupportLevel::Supported &&
- this->GetGlobalGenerator()->CheckCxxModuleSupport();
-}
-
-bool cmNinjaTargetGenerator::NeedDyndep(std::string const& lang,
- std::string const& config) const
-{
- return lang == "Fortran" || this->NeedCxxModuleSupport(lang, config);
-}
-
std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget(
const std::string& config)
{
@@ -256,54 +236,17 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
flags, genexInterpreter.Evaluate(pchOptions, COMPILE_OPTIONS));
}
- auto const& path = source->GetFullPath();
- auto const* tgt = this->GeneratorTarget->Target;
-
- std::string file_set_type;
-
- for (auto const& name : tgt->GetAllFileSetNames()) {
- auto const* file_set = tgt->GetFileSet(name);
- if (!file_set) {
+ auto const* fs = this->GeneratorTarget->GetFileSetForSource(config, source);
+ if (fs &&
+ (fs->GetType() == "CXX_MODULES"_s ||
+ fs->GetType() == "CXX_MODULE_HEADER_UNITS"_s)) {
+ if (source->GetLanguage() != "CXX"_s) {
this->GetMakefile()->IssueMessage(
- MessageType::INTERNAL_ERROR,
- cmStrCat("Target \"", tgt->GetName(),
- "\" is tracked to have file set \"", name,
- "\", but it was not found."));
- continue;
- }
-
- auto fileEntries = file_set->CompileFileEntries();
- auto directoryEntries = file_set->CompileDirectoryEntries();
- auto directories = file_set->EvaluateDirectoryEntries(
- directoryEntries, this->LocalGenerator, config, this->GeneratorTarget);
-
- std::map<std::string, std::vector<std::string>> files;
- for (auto const& entry : fileEntries) {
- file_set->EvaluateFileEntry(directories, files, entry,
- this->LocalGenerator, config,
- this->GeneratorTarget);
- }
-
- for (auto const& it : files) {
- for (auto const& filename : it.second) {
- if (filename == path) {
- file_set_type = file_set->GetType();
- break;
- }
- }
- }
-
- if (file_set_type == "CXX_MODULES"_s ||
- file_set_type == "CXX_MODULE_HEADER_UNITS"_s) {
- if (source->GetLanguage() != "CXX"_s) {
- this->GetMakefile()->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat(
- "Target \"", tgt->GetName(), "\" contains the source\n ", path,
- "\nin a file set of type \"", file_set_type,
- R"(" but the source is not classified as a "CXX" source.)"));
- continue;
- }
+ MessageType::FATAL_ERROR,
+ cmStrCat("Target \"", this->GeneratorTarget->Target->GetName(),
+ "\" contains the source\n ", source->GetFullPath(),
+ "\nin a file set of type \"", fs->GetType(),
+ R"(" but the source is not classified as a "CXX" source.)"));
}
}
@@ -452,6 +395,24 @@ std::string cmNinjaTargetGenerator::GetObjectFilePath(
return path;
}
+std::string cmNinjaTargetGenerator::GetClangTidyReplacementsFilePath(
+ const std::string& directory, cmSourceFile const* source,
+ const std::string& config) const
+{
+ std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
+ if (!path.empty()) {
+ path += '/';
+ }
+ path = cmStrCat(directory, '/', path);
+ std::string const& objectName = this->GeneratorTarget->GetObjectName(source);
+ path =
+ cmStrCat(std::move(path),
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
+ this->GetGlobalGenerator()->ConfigDirectory(config), '/',
+ objectName, ".yaml");
+ return path;
+}
+
std::string cmNinjaTargetGenerator::GetPreprocessedFilePath(
cmSourceFile const* source, const std::string& config) const
{
@@ -600,9 +561,9 @@ cmNinjaRule GetScanRule(
// Scanning always uses a depfile for preprocessor dependencies.
if (deptype == "msvc"_s) {
rule.DepType = deptype;
- rule.DepFile = "";
+ rule.DepFile.clear();
} else {
- rule.DepType = ""; // no deps= for multiple outputs
+ rule.DepType.clear(); // no deps= for multiple outputs
rule.DepFile = "$DEP_FILE";
}
@@ -650,6 +611,19 @@ cmNinjaRule GetScanRule(
void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
const std::string& config)
{
+ // For some cases we scan to dynamically discover dependencies.
+ bool const needDyndep = this->GetGeneratorTarget()->NeedDyndep(lang, config);
+
+ if (needDyndep) {
+ this->WriteCompileRule(lang, config, WithScanning::Yes);
+ }
+ this->WriteCompileRule(lang, config, WithScanning::No);
+}
+
+void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
+ const std::string& config,
+ WithScanning withScanning)
+{
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
vars.CMTargetType =
@@ -669,7 +643,6 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
cmMakefile* mf = this->GetMakefile();
// For some cases we scan to dynamically discover dependencies.
- bool const needDyndep = this->NeedDyndep(lang, config);
bool const compilationPreprocesses = !this->NeedExplicitPreprocessing(lang);
std::string flags = "$FLAGS";
@@ -707,7 +680,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
this->GetLocalGenerator()->ConvertToOutputFormat(
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
- if (needDyndep) {
+ if (withScanning == WithScanning::Yes) {
const auto& scanDepType = this->GetMakefile()->GetSafeDefinition(
cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_DEPFILE_FORMAT"));
@@ -813,7 +786,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
this->GetGlobalGenerator()->AddRule(rule);
}
- cmNinjaRule rule(this->LanguageCompilerRule(lang, config));
+ cmNinjaRule rule(this->LanguageCompilerRule(lang, config, withScanning));
// If using a response file, move defines, includes, and flags into it.
if (!responseFlag.empty()) {
rule.RspFile = "$RSP_FILE";
@@ -867,7 +840,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
}
}
- if (needDyndep && !modmapFormat.empty()) {
+ if (withScanning == WithScanning::Yes && !modmapFormat.empty()) {
std::string modmapFlags = mf->GetRequiredDefinition(
cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_MODULE_MAP_FLAG"));
cmSystemTools::ReplaceString(modmapFlags, "<MODULE_MAP_FILE>",
@@ -978,8 +951,24 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
} else {
driverMode = lang == "C" ? "gcc" : "g++";
}
+ const bool haveClangTidyExportFixesDir =
+ !this->GeneratorTarget->GetClangTidyExportFixesDirectory(lang)
+ .empty();
+ std::string exportFixes;
+ if (haveClangTidyExportFixesDir) {
+ exportFixes = ";--export-fixes=$CLANG_TIDY_EXPORT_FIXES";
+ }
run_iwyu += this->GetLocalGenerator()->EscapeForShell(
- cmStrCat(*tidy, ";--extra-arg-before=--driver-mode=", driverMode));
+ cmStrCat(*tidy, ";--extra-arg-before=--driver-mode=", driverMode,
+ exportFixes));
+ if (haveClangTidyExportFixesDir) {
+ std::string search = cmStrCat(
+ this->GetLocalGenerator()->GetState()->UseWindowsShell() ? ""
+ : "\\",
+ "$$CLANG_TIDY_EXPORT_FIXES");
+ auto loc = run_iwyu.rfind(search);
+ run_iwyu.replace(loc, search.length(), "$CLANG_TIDY_EXPORT_FIXES");
+ }
}
if (cmNonempty(cpplint)) {
run_iwyu += cmStrCat(
@@ -1177,30 +1166,42 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
}
this->GetImplFileStream(fileConfig) << "\n";
+}
- if (!this->Configs[config].SwiftOutputMap.empty()) {
- std::string const mapFilePath =
- cmStrCat(this->GeneratorTarget->GetSupportDirectory(), '/', config, '/',
- "output-file-map.json");
- std::string const targetSwiftDepsPath = [this, config]() -> std::string {
- cmGeneratorTarget const* target = this->GeneratorTarget;
- if (cmValue name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
- return *name;
- }
- return this->ConvertToNinjaPath(
- cmStrCat(target->GetSupportDirectory(), '/', config, '/',
- target->GetName(), ".swiftdeps"));
- }();
+void cmNinjaTargetGenerator::GenerateSwiftOutputFileMap(
+ const std::string& config, std::string& flags)
+{
+ if (this->Configs[config].SwiftOutputMap.empty()) {
+ return;
+ }
+
+ std::string const targetSwiftDepsPath = [this, config]() -> std::string {
+ cmGeneratorTarget const* target = this->GeneratorTarget;
+ if (cmValue name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
+ return *name;
+ }
+ return this->ConvertToNinjaPath(cmStrCat(target->GetSupportDirectory(),
+ '/', config, '/',
+ target->GetName(), ".swiftdeps"));
+ }();
- // build the global target dependencies
- // https://github.com/apple/swift/blob/master/docs/Driver.md#output-file-maps
- Json::Value deps(Json::objectValue);
- deps["swift-dependencies"] = targetSwiftDepsPath;
- this->Configs[config].SwiftOutputMap[""] = deps;
+ std::string mapFilePath =
+ cmStrCat(this->GeneratorTarget->GetSupportDirectory(), '/', config, '/',
+ "output-file-map.json");
- cmGeneratedFileStream output(mapFilePath);
- output << this->Configs[config].SwiftOutputMap;
- }
+ // build the global target dependencies
+ // https://github.com/apple/swift/blob/master/docs/Driver.md#output-file-maps
+ Json::Value deps(Json::objectValue);
+ deps["swift-dependencies"] = targetSwiftDepsPath;
+ this->Configs[config].SwiftOutputMap[""] = deps;
+
+ cmGeneratedFileStream output(mapFilePath);
+ output << this->Configs[config].SwiftOutputMap;
+
+ // Add flag
+ this->LocalGenerator->AppendFlags(flags, "-output-file-map");
+ this->LocalGenerator->AppendFlagEscape(flags,
+ ConvertToNinjaPath(mapFilePath));
}
namespace {
@@ -1315,8 +1316,11 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
!(language == "RC" || (language == "CUDA" && !flag));
int const commandLineLengthLimit =
((lang_supports_response && this->ForceResponseFile())) ? -1 : 0;
+ bool const needDyndep =
+ this->GeneratorTarget->NeedDyndepForSource(language, config, source);
- cmNinjaBuild objBuild(this->LanguageCompilerRule(language, config));
+ cmNinjaBuild objBuild(this->LanguageCompilerRule(
+ language, config, needDyndep ? WithScanning::Yes : WithScanning::No));
cmNinjaVars& vars = objBuild.Variables;
vars["FLAGS"] = this->ComputeFlagsForObject(source, language, config);
vars["DEFINES"] = this->ComputeDefines(source, language, config);
@@ -1345,6 +1349,18 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
}
}
+ std::string d =
+ this->GeneratorTarget->GetClangTidyExportFixesDirectory(language);
+ if (!d.empty()) {
+ this->GlobalCommonGenerator->AddClangTidyExportFixesDir(d);
+ std::string fixesFile =
+ this->GetClangTidyReplacementsFilePath(d, source, config);
+ this->GlobalCommonGenerator->AddClangTidyExportFixesFile(fixesFile);
+ cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(fixesFile));
+ fixesFile = this->ConvertToNinjaPath(fixesFile);
+ vars["CLANG_TIDY_EXPORT_FIXES"] = fixesFile;
+ }
+
if (firstForConfig) {
this->ExportObjectCompileCommand(
language, sourceFilePath, objectDir, objectFileName, objectFileDir,
@@ -1425,7 +1441,6 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
}
// For some cases we scan to dynamically discover dependencies.
- bool const needDyndep = this->NeedDyndep(language, config);
bool const compilationPreprocesses =
!this->NeedExplicitPreprocessing(language);
@@ -1664,214 +1679,15 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang,
tdi_linked_target_dirs.append(l);
}
- cmTarget* tgt = this->GeneratorTarget->Target;
- auto all_file_sets = tgt->GetAllFileSetNames();
- Json::Value& tdi_cxx_module_info = tdi["cxx-modules"] = Json::objectValue;
- for (auto const& file_set_name : all_file_sets) {
- auto* file_set = tgt->GetFileSet(file_set_name);
- if (!file_set) {
- this->GetMakefile()->IssueMessage(
- MessageType::INTERNAL_ERROR,
- cmStrCat("Target \"", tgt->GetName(),
- "\" is tracked to have file set \"", file_set_name,
- "\", but it was not found."));
- continue;
- }
- auto fs_type = file_set->GetType();
- // We only care about C++ module sources here.
- if (fs_type != "CXX_MODULES"_s) {
- continue;
- }
-
- auto fileEntries = file_set->CompileFileEntries();
- auto directoryEntries = file_set->CompileDirectoryEntries();
-
- auto directories = file_set->EvaluateDirectoryEntries(
- directoryEntries, this->GeneratorTarget->LocalGenerator, config,
- this->GeneratorTarget);
- std::map<std::string, std::vector<std::string>> files_per_dirs;
- for (auto const& entry : fileEntries) {
- file_set->EvaluateFileEntry(directories, files_per_dirs, entry,
- this->GeneratorTarget->LocalGenerator,
- config, this->GeneratorTarget);
- }
-
- std::map<std::string, cmSourceFile const*> sf_map;
- {
- std::vector<cmSourceFile const*> objectSources;
- this->GeneratorTarget->GetObjectSources(objectSources, config);
- for (auto const* sf : objectSources) {
- auto full_path = sf->GetFullPath();
- if (full_path.empty()) {
- this->GetMakefile()->IssueMessage(
- MessageType::INTERNAL_ERROR,
- cmStrCat("Target \"", tgt->GetName(),
- "\" has a full path-less source file."));
- continue;
- }
- sf_map[full_path] = sf;
- }
- }
-
- Json::Value fs_dest = Json::nullValue;
- for (auto const& ig : this->GetMakefile()->GetInstallGenerators()) {
- if (auto const* fsg =
- dynamic_cast<cmInstallFileSetGenerator const*>(ig.get())) {
- if (fsg->GetTarget() == this->GeneratorTarget &&
- fsg->GetFileSet() == file_set) {
- fs_dest = fsg->GetDestination(config);
- continue;
- }
- }
- }
-
- for (auto const& files_per_dir : files_per_dirs) {
- for (auto const& file : files_per_dir.second) {
- auto lookup = sf_map.find(file);
- if (lookup == sf_map.end()) {
- this->GetMakefile()->IssueMessage(
- MessageType::INTERNAL_ERROR,
- cmStrCat("Target \"", tgt->GetName(), "\" has source file \"",
- file,
- R"(" which is not in any of its "FILE_SET BASE_DIRS".)"));
- continue;
- }
-
- auto const* sf = lookup->second;
-
- if (!sf) {
- this->GetMakefile()->IssueMessage(
- MessageType::INTERNAL_ERROR,
- cmStrCat("Target \"", tgt->GetName(), "\" has source file \"",
- file, "\" which has not been tracked properly."));
- continue;
- }
-
- auto obj_path = this->GetObjectFilePath(sf, config);
- Json::Value& tdi_module_info = tdi_cxx_module_info[obj_path] =
- Json::objectValue;
-
- tdi_module_info["source"] = file;
- tdi_module_info["relative-directory"] = files_per_dir.first;
- tdi_module_info["name"] = file_set->GetName();
- tdi_module_info["type"] = file_set->GetType();
- tdi_module_info["visibility"] =
- std::string(cmFileSetVisibilityToName(file_set->GetVisibility()));
- tdi_module_info["destination"] = fs_dest;
- }
- }
- }
-
- tdi["config"] = config;
-
- // Add information about the export sets that this target is a member of.
- Json::Value& tdi_exports = tdi["exports"] = Json::arrayValue;
- std::string export_name = this->GeneratorTarget->GetExportName();
-
- cmInstallCxxModuleBmiGenerator const* bmi_gen = nullptr;
- for (auto const& ig : this->GetMakefile()->GetInstallGenerators()) {
- if (auto const* bmig =
- dynamic_cast<cmInstallCxxModuleBmiGenerator const*>(ig.get())) {
- if (bmig->GetTarget() == this->GeneratorTarget) {
- bmi_gen = bmig;
- continue;
- }
- }
- }
- if (bmi_gen) {
- Json::Value tdi_bmi_info = Json::objectValue;
-
- tdi_bmi_info["permissions"] = bmi_gen->GetFilePermissions();
- tdi_bmi_info["destination"] = bmi_gen->GetDestination(config);
- const char* msg_level = "";
- switch (bmi_gen->GetMessageLevel()) {
- case cmInstallGenerator::MessageDefault:
- break;
- case cmInstallGenerator::MessageAlways:
- msg_level = "MESSAGE_ALWAYS";
- break;
- case cmInstallGenerator::MessageLazy:
- msg_level = "MESSAGE_LAZY";
- break;
- case cmInstallGenerator::MessageNever:
- msg_level = "MESSAGE_NEVER";
- break;
- }
- tdi_bmi_info["message-level"] = msg_level;
- tdi_bmi_info["script-location"] = bmi_gen->GetScriptLocation(config);
-
- tdi["bmi-installation"] = tdi_bmi_info;
- } else {
- tdi["bmi-installation"] = Json::nullValue;
- }
-
- auto const& all_install_exports =
- this->GetGlobalGenerator()->GetExportSets();
- for (auto const& exp : all_install_exports) {
- // Ignore exports sets which are not for this target.
- auto const& targets = exp.second.GetTargetExports();
- auto tgt_export =
- std::find_if(targets.begin(), targets.end(),
- [this](std::unique_ptr<cmTargetExport> const& te) {
- return te->Target == this->GeneratorTarget;
- });
- if (tgt_export == targets.end()) {
- continue;
- }
-
- auto const* installs = exp.second.GetInstallations();
- for (auto const* install : *installs) {
- Json::Value tdi_export_info = Json::objectValue;
-
- auto const& ns = install->GetNamespace();
- auto const& dest = install->GetDestination();
- auto const& cxxm_dir = install->GetCxxModuleDirectory();
- auto const& export_prefix = install->GetTempDir();
-
- tdi_export_info["namespace"] = ns;
- tdi_export_info["export-name"] = export_name;
- tdi_export_info["destination"] = dest;
- tdi_export_info["cxx-module-info-dir"] = cxxm_dir;
- tdi_export_info["export-prefix"] = export_prefix;
- tdi_export_info["install"] = true;
-
- tdi_exports.append(tdi_export_info);
- }
- }
-
- auto const& all_build_exports =
- this->GetMakefile()->GetExportBuildFileGenerators();
- for (auto const& exp : all_build_exports) {
- std::vector<std::string> targets;
- exp->GetTargets(targets);
+ cmDyndepGeneratorCallbacks cb;
+ cb.ObjectFilePath = [this](cmSourceFile const* sf, std::string const& cnf) {
+ return this->GetObjectFilePath(sf, cnf);
+ };
- // Ignore exports sets which are not for this target.
- auto const& name = this->GeneratorTarget->GetName();
- bool has_current_target =
- std::any_of(targets.begin(), targets.end(),
- [name](std::string const& tname) { return tname == name; });
- if (!has_current_target) {
- continue;
- }
-
- Json::Value tdi_export_info = Json::objectValue;
-
- auto const& ns = exp->GetNamespace();
- auto const& main_fn = exp->GetMainExportFileName();
- auto const& cxxm_dir = exp->GetCxxModuleDirectory();
- auto dest = cmsys::SystemTools::GetParentDirectory(main_fn);
- auto const& export_prefix =
- cmSystemTools::GetFilenamePath(exp->GetMainExportFileName());
-
- tdi_export_info["namespace"] = ns;
- tdi_export_info["export-name"] = export_name;
- tdi_export_info["destination"] = dest;
- tdi_export_info["cxx-module-info-dir"] = cxxm_dir;
- tdi_export_info["export-prefix"] = export_prefix;
- tdi_export_info["install"] = false;
-
- tdi_exports.append(tdi_export_info);
- }
+#if !defined(CMAKE_BOOTSTRAP)
+ cmDyndepCollation::AddCollationInformation(tdi, this->GeneratorTarget,
+ config, cb);
+#endif
std::string const tdin = this->GetTargetDependInfoPath(lang, config);
cmGeneratedFileStream tdif(tdin);
@@ -1998,7 +1814,8 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
std::string cmdLine = this->GetLocalGenerator()->BuildCommandLine(
compileCmds, outputConfig, outputConfig);
- this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine, sourceFileName);
+ this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine, sourceFileName,
+ objectFileName);
}
void cmNinjaTargetGenerator::AdditionalCleanFiles(const std::string& config)
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 4b4cf8d..8bf7986 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -63,19 +63,22 @@ protected:
cmMakefile* GetMakefile() const { return this->Makefile; }
+ enum class WithScanning
+ {
+ No,
+ Yes,
+ };
std::string LanguageCompilerRule(const std::string& lang,
- const std::string& config) const;
+ const std::string& config,
+ WithScanning withScanning) const;
std::string LanguagePreprocessAndScanRule(std::string const& lang,
const std::string& config) const;
std::string LanguageScanRule(std::string const& lang,
const std::string& config) const;
std::string LanguageDyndepRule(std::string const& lang,
const std::string& config) const;
- bool NeedDyndep(std::string const& lang, std::string const& config) const;
bool NeedExplicitPreprocessing(std::string const& lang) const;
bool CompileWithDefines(std::string const& lang) const;
- bool NeedCxxModuleSupport(std::string const& lang,
- std::string const& config) const;
std::string OrderDependsTargetForTarget(const std::string& config);
@@ -131,6 +134,11 @@ protected:
std::string GetPreprocessedFilePath(cmSourceFile const* source,
const std::string& config) const;
+ /// @return the clang-tidy replacements file path for the given @a source.
+ std::string GetClangTidyReplacementsFilePath(
+ const std::string& directory, cmSourceFile const* source,
+ const std::string& config) const;
+
/// @return the dyndep file path for this target.
std::string GetDyndepFilePath(std::string const& lang,
const std::string& config) const;
@@ -150,6 +158,8 @@ protected:
const std::string& config);
void WriteCompileRule(const std::string& language,
const std::string& config);
+ void WriteCompileRule(const std::string& language, const std::string& config,
+ WithScanning withScanning);
void WriteObjectBuildStatements(const std::string& config,
const std::string& fileConfig,
bool firstForConfig);
@@ -163,6 +173,9 @@ protected:
void EmitSwiftDependencyInfo(cmSourceFile const* source,
const std::string& config);
+ void GenerateSwiftOutputFileMap(const std::string& config,
+ std::string& flags);
+
void ExportObjectCompileCommand(
std::string const& language, std::string const& sourceFileName,
std::string const& objectDir, std::string const& objectFileName,
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 4643868..fa24f57 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -431,7 +431,10 @@ class cmMakefile;
SELECT(POLICY, CMP0142, \
"The Xcode generator does not append per-config suffixes to " \
"library search paths.", \
- 3, 25, 0, cmPolicies::WARN)
+ 3, 25, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0143, \
+ "Global property USE_FOLDERS treated as ON by default", 3, 26, 0, \
+ cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 249fe2d..4d1ccfe 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -34,6 +34,15 @@ bool cmProjectCommand(std::vector<std::string> const& args,
}
cmMakefile& mf = status.GetMakefile();
+ if (mf.IsRootMakefile() &&
+ !mf.GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION")) {
+ mf.IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ "cmake_minimum_required() should be called prior to this top-level "
+ "project() call. Please see the cmake-commands(7) manual for usage "
+ "documentation of both commands.");
+ }
+
if (!IncludeByVariable(status, "CMAKE_PROJECT_INCLUDE_BEFORE")) {
return false;
}
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 96649ab..66e591e 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -970,8 +970,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
uiHeader, uiHeaderGenex, cmStrCat(this->Dir.Build, "/include"_s),
uiHeaderFilePath);
- this->Uic.UiHeaders.emplace_back(
- std::make_pair(uiHeader, uiHeaderGenex));
+ this->Uic.UiHeaders.emplace_back(uiHeader, uiHeaderGenex);
} else {
// Register skipped .ui file
this->Uic.SkipUi.insert(fullPath);
@@ -2095,7 +2094,7 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars,
// Evaluate generator expression
{
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmGeneratorExpression ge(lfbt);
+ cmGeneratorExpression ge(*this->Makefile->GetCMakeInstance(), lfbt);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(val);
genVars.Executable = cge->Evaluate(this->LocalGen, "");
}
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index 4753e61..683c18f 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -1981,6 +1981,9 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
std::string const& sourceFile = this->Mapping->SourceFile->FileName;
std::string const& outputFile = this->Mapping->OutputFile;
+ // Remove output file in case the case of the source file has changed
+ cmSystemTools::RemoveFile(outputFile);
+
// Compose moc command
std::vector<std::string> cmd;
{
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index b63d11c..638bb42 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -119,11 +119,6 @@ std::string cmRulePlaceholderExpander::ExpandVariable(
return this->ReplaceValues->SwiftModuleName;
}
}
- if (this->ReplaceValues->SwiftOutputFileMap) {
- if (variable == "SWIFT_OUTPUT_FILE_MAP") {
- return this->ReplaceValues->SwiftOutputFileMap;
- }
- }
if (this->ReplaceValues->SwiftSources) {
if (variable == "SWIFT_SOURCES") {
return this->ReplaceValues->SwiftSources;
diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h
index 23ec405..5d1f199 100644
--- a/Source/cmRulePlaceholderExpander.h
+++ b/Source/cmRulePlaceholderExpander.h
@@ -64,7 +64,7 @@ public:
const char* SwiftLibraryName = nullptr;
const char* SwiftModule = nullptr;
const char* SwiftModuleName = nullptr;
- const char* SwiftOutputFileMap = nullptr;
+ const char* SwiftOutputFileMapOption = nullptr;
const char* SwiftSources = nullptr;
const char* ISPCHeader = nullptr;
const char* CudaCompileMode = nullptr;
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
index 6c53b85..44f37cb 100644
--- a/Source/cmSearchPath.cxx
+++ b/Source/cmSearchPath.cxx
@@ -179,12 +179,27 @@ void cmSearchPath::AddPrefixPaths(const std::vector<std::string>& paths,
cmValue arch =
this->FC->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE");
if (cmNonempty(arch)) {
+ std::string archNoUnknown = arch;
+ auto unknownAtPos = archNoUnknown.find("-unknown-");
+ bool foundUnknown = unknownAtPos != std::string::npos;
+ if (foundUnknown) {
+ // Replace "-unknown-" with "-".
+ archNoUnknown.replace(unknownAtPos, 9, "-");
+ }
if (this->FC->Makefile->IsDefinitionSet("CMAKE_SYSROOT") &&
this->FC->Makefile->IsDefinitionSet(
"CMAKE_PREFIX_LIBRARY_ARCHITECTURE")) {
+ if (foundUnknown) {
+ this->AddPathInternal(cmStrCat('/', archNoUnknown, dir, subdir),
+ cmStrCat('/', archNoUnknown, prefix), base);
+ }
this->AddPathInternal(cmStrCat('/', *arch, dir, subdir),
cmStrCat('/', *arch, prefix), base);
} else {
+ if (foundUnknown) {
+ this->AddPathInternal(cmStrCat(dir, subdir, '/', archNoUnknown),
+ prefix, base);
+ }
this->AddPathInternal(cmStrCat(dir, subdir, '/', *arch), prefix,
base);
}
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index e54ccfc..f12f91f 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -786,6 +786,8 @@ std::string cmState::ModeToString(cmState::Mode mode)
return "CTEST";
case CPack:
return "CPACK";
+ case Help:
+ return "HELP";
case Unknown:
return "UNKNOWN";
}
diff --git a/Source/cmState.h b/Source/cmState.h
index 2d0c521..9a17b22 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -53,6 +53,7 @@ public:
FindPackage,
CTest,
CPack,
+ Help
};
enum class ProjectKind
diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx
index f73c854..66bf383 100644
--- a/Source/cmStringAlgorithms.cxx
+++ b/Source/cmStringAlgorithms.cxx
@@ -203,17 +203,45 @@ cmAlphaNum::cmAlphaNum(double val)
MakeDigits(this->View_, this->Digits_, "%g", val);
}
-std::string cmCatViews(std::initializer_list<cm::string_view> views)
+std::string cmCatViews(
+ std::initializer_list<std::pair<cm::string_view, std::string*>> views)
{
- std::size_t total_size = 0;
- for (cm::string_view const& view : views) {
- total_size += view.size();
+ std::size_t totalSize = 0;
+ std::string* rvalueString = nullptr;
+ std::size_t rvalueStringLength = 0;
+ std::size_t rvalueStringOffset = 0;
+ for (auto const& view : views) {
+ // Find the rvalue string with the largest capacity.
+ if (view.second &&
+ (!rvalueString ||
+ view.second->capacity() > rvalueString->capacity())) {
+ rvalueString = view.second;
+ rvalueStringLength = rvalueString->length();
+ rvalueStringOffset = totalSize;
+ }
+ totalSize += view.first.size();
}
- std::string result(total_size, '\0');
- std::string::iterator sit = result.begin();
- for (cm::string_view const& view : views) {
- sit = std::copy_n(view.data(), view.size(), sit);
+ std::string result;
+ std::string::size_type initialLen = 0;
+ if (rvalueString && rvalueString->capacity() >= totalSize) {
+ result = std::move(*rvalueString);
+ } else {
+ rvalueString = nullptr;
+ }
+ result.resize(totalSize);
+ if (rvalueString && rvalueStringOffset > 0) {
+ std::copy_backward(result.begin(), result.begin() + rvalueStringLength,
+ result.begin() + rvalueStringOffset +
+ rvalueStringLength);
+ }
+ std::string::iterator sit = result.begin() + initialLen;
+ for (auto const& view : views) {
+ if (rvalueString && view.second == rvalueString) {
+ sit += rvalueStringLength;
+ } else {
+ sit = std::copy_n(view.first.data(), view.first.size(), sit);
+ }
}
return result;
}
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h
index 83938bc..9ea7491 100644
--- a/Source/cmStringAlgorithms.h
+++ b/Source/cmStringAlgorithms.h
@@ -146,7 +146,8 @@ std::vector<std::string> cmExpandedLists(InputIt first, InputIt last)
}
/** Concatenate string pieces into a single string. */
-std::string cmCatViews(std::initializer_list<cm::string_view> views);
+std::string cmCatViews(
+ std::initializer_list<std::pair<cm::string_view, std::string*>> views);
/** Utility class for cmStrCat. */
class cmAlphaNum
@@ -160,6 +161,10 @@ public:
: View_(str)
{
}
+ cmAlphaNum(std::string&& str)
+ : RValueString_(&str)
+ {
+ }
cmAlphaNum(const char* str)
: View_(str)
{
@@ -182,20 +187,34 @@ public:
{
}
- cm::string_view View() const { return this->View_; }
+ cm::string_view View() const
+ {
+ if (this->RValueString_) {
+ return *this->RValueString_;
+ }
+ return this->View_;
+ }
+
+ std::string* RValueString() const { return this->RValueString_; }
private:
+ std::string* RValueString_ = nullptr;
cm::string_view View_;
char Digits_[32];
};
/** Concatenate string pieces and numbers into a single string. */
-template <typename... AV>
-inline std::string cmStrCat(cmAlphaNum const& a, cmAlphaNum const& b,
- AV const&... args)
+template <typename A, typename B, typename... AV>
+inline std::string cmStrCat(A&& a, B&& b, AV&&... args)
{
- return cmCatViews(
- { a.View(), b.View(), static_cast<cmAlphaNum const&>(args).View()... });
+ static auto const makePair =
+ [](const cmAlphaNum& arg) -> std::pair<cm::string_view, std::string*> {
+ return { arg.View(), arg.RValueString() };
+ };
+
+ return cmCatViews({ makePair(std::forward<A>(a)),
+ makePair(std::forward<B>(b)),
+ makePair(std::forward<AV>(args))... });
}
/** Joins wrapped elements of a range with separator into a single string. */
@@ -206,8 +225,13 @@ std::string cmWrap(cm::string_view prefix, Range const& rng,
if (rng.empty()) {
return std::string();
}
- return cmCatViews(
- { prefix, cmJoin(rng, cmCatViews({ suffix, sep, prefix })), suffix });
+ return cmCatViews({ { prefix, nullptr },
+ { cmJoin(rng,
+ cmCatViews({ { suffix, nullptr },
+ { sep, nullptr },
+ { prefix, nullptr } })),
+ nullptr },
+ { suffix, nullptr } });
}
/** Joins wrapped elements of a range with separator into a single string. */
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index c12d1fe..5a64588 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -9,7 +9,6 @@
#include <cctype>
#include <cstdio>
#include <cstdlib>
-#include <initializer_list>
#include <limits>
#include <memory>
#include <stdexcept>
@@ -950,9 +949,9 @@ struct Args : cmRange<typename std::vector<std::string>::const_iterator>
class json_error : public std::runtime_error
{
public:
- json_error(std::initializer_list<cm::string_view> message,
+ json_error(const std::string& message,
cm::optional<Args> errorPath = cm::nullopt)
- : std::runtime_error(cmCatViews(message))
+ : std::runtime_error(message)
, ErrorPath{
std::move(errorPath) // NOLINT(performance-move-const-arg)
}
@@ -964,7 +963,7 @@ public:
const std::string& Args::PopFront(cm::string_view error)
{
if (this->empty()) {
- throw json_error({ error });
+ throw json_error(std::string(error));
}
const std::string& res = *this->begin();
this->advance(1);
@@ -974,7 +973,7 @@ const std::string& Args::PopFront(cm::string_view error)
const std::string& Args::PopBack(cm::string_view error)
{
if (this->empty()) {
- throw json_error({ error });
+ throw json_error(std::string(error));
}
const std::string& res = *(this->end() - 1);
this->retreat(1);
@@ -999,7 +998,7 @@ cm::string_view JsonTypeToString(Json::ValueType type)
case Json::ValueType::objectValue:
return "OBJECT"_s;
}
- throw json_error({ "invalid JSON type found"_s });
+ throw json_error("invalid JSON type found");
}
int ParseIndex(
@@ -1008,14 +1007,14 @@ int ParseIndex(
{
unsigned long lindex;
if (!cmStrToULong(str, &lindex)) {
- throw json_error({ "expected an array index, got: '"_s, str, "'"_s },
+ throw json_error(cmStrCat("expected an array index, got: '"_s, str, "'"_s),
progress);
}
Json::ArrayIndex index = static_cast<Json::ArrayIndex>(lindex);
if (index >= max) {
cmAlphaNum sizeStr{ max };
- throw json_error({ "expected an index less than "_s, sizeStr.View(),
- " got '"_s, str, "'"_s },
+ throw json_error(cmStrCat("expected an index less than "_s, sizeStr.View(),
+ " got '"_s, str, "'"_s),
progress);
}
return index;
@@ -1036,16 +1035,16 @@ Json::Value& ResolvePath(Json::Value& json, Args path)
} else if (search->isObject()) {
if (!search->isMember(field)) {
const auto progressStr = cmJoin(progress, " "_s);
- throw json_error({ "member '"_s, progressStr, "' not found"_s },
+ throw json_error(cmStrCat("member '"_s, progressStr, "' not found"_s),
progress);
}
search = &(*search)[field];
} else {
const auto progressStr = cmJoin(progress, " "_s);
throw json_error(
- { "invalid path '"_s, progressStr,
- "', need element of OBJECT or ARRAY type to lookup '"_s, field,
- "' got "_s, JsonTypeToString(search->type()) },
+ cmStrCat("invalid path '"_s, progressStr,
+ "', need element of OBJECT or ARRAY type to lookup '"_s,
+ field, "' got "_s, JsonTypeToString(search->type())),
progress);
}
}
@@ -1061,7 +1060,7 @@ Json::Value ReadJson(const std::string& jsonstr)
std::string error;
if (!jsonReader->parse(jsonstr.data(), jsonstr.data() + jsonstr.size(),
&json, &error)) {
- throw json_error({ "failed parsing json string: "_s, error });
+ throw json_error(cmStrCat("failed parsing json string: "_s, error));
}
return json;
}
@@ -1101,9 +1100,9 @@ bool HandleJSONCommand(std::vector<std::string> const& arguments,
mode != "LENGTH"_s && mode != "REMOVE"_s && mode != "SET"_s &&
mode != "EQUAL"_s) {
throw json_error(
- { "got an invalid mode '"_s, mode,
- "', expected one of GET, TYPE, MEMBER, LENGTH, REMOVE, SET, "
- " EQUAL"_s });
+ cmStrCat("got an invalid mode '"_s, mode,
+ "', expected one of GET, TYPE, MEMBER, LENGTH, REMOVE, SET, "
+ " EQUAL"_s));
}
const auto& jsonstr = args.PopFront("missing json string argument"_s);
@@ -1127,10 +1126,11 @@ bool HandleJSONCommand(std::vector<std::string> const& arguments,
const auto& indexStr = args.PopBack("missing member index"_s);
const auto& value = ResolvePath(json, args);
if (!value.isObject()) {
- throw json_error({ "MEMBER needs to be called with an element of "
- "type OBJECT, got "_s,
- JsonTypeToString(value.type()) },
- args);
+ throw json_error(
+ cmStrCat("MEMBER needs to be called with an element of "
+ "type OBJECT, got "_s,
+ JsonTypeToString(value.type())),
+ args);
}
const auto index = ParseIndex(
indexStr, Args{ args.begin(), args.end() + 1 }, value.size());
@@ -1140,9 +1140,9 @@ bool HandleJSONCommand(std::vector<std::string> const& arguments,
} else if (mode == "LENGTH"_s) {
const auto& value = ResolvePath(json, args);
if (!value.isArray() && !value.isObject()) {
- throw json_error({ "LENGTH needs to be called with an "
- "element of type ARRAY or OBJECT, got "_s,
- JsonTypeToString(value.type()) },
+ throw json_error(cmStrCat("LENGTH needs to be called with an "
+ "element of type ARRAY or OBJECT, got "_s,
+ JsonTypeToString(value.type())),
args);
}
@@ -1165,9 +1165,9 @@ bool HandleJSONCommand(std::vector<std::string> const& arguments,
value.removeMember(toRemove, &removed);
} else {
- throw json_error({ "REMOVE needs to be called with an "
- "element of type ARRAY or OBJECT, got "_s,
- JsonTypeToString(value.type()) },
+ throw json_error(cmStrCat("REMOVE needs to be called with an "
+ "element of type ARRAY or OBJECT, got "_s,
+ JsonTypeToString(value.type())),
args);
}
makefile.AddDefinition(*outputVariable, WriteJson(json));
@@ -1189,9 +1189,9 @@ bool HandleJSONCommand(std::vector<std::string> const& arguments,
value.append(newValue);
}
} else {
- throw json_error({ "SET needs to be called with an "
- "element of type OBJECT or ARRAY, got "_s,
- JsonTypeToString(value.type()) });
+ throw json_error(cmStrCat("SET needs to be called with an "
+ "element of type OBJECT or ARRAY, got "_s,
+ JsonTypeToString(value.type())));
}
makefile.AddDefinition(*outputVariable, WriteJson(json));
@@ -1207,7 +1207,7 @@ bool HandleJSONCommand(std::vector<std::string> const& arguments,
if (outputVariable && e.ErrorPath) {
const auto errorPath = cmJoin(*e.ErrorPath, "-");
makefile.AddDefinition(*outputVariable,
- cmCatViews({ errorPath, "-NOTFOUND"_s }));
+ cmStrCat(errorPath, "-NOTFOUND"_s));
} else if (outputVariable) {
makefile.AddDefinition(*outputVariable, "NOTFOUND"_s);
}
@@ -1215,7 +1215,7 @@ bool HandleJSONCommand(std::vector<std::string> const& arguments,
if (errorVariable) {
makefile.AddDefinition(*errorVariable, e.what());
} else {
- status.SetError(cmCatViews({ "sub-command JSON "_s, e.what(), "."_s }));
+ status.SetError(cmStrCat("sub-command JSON "_s, e.what(), "."_s));
success = false;
}
}
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index ee74908..f94c4d3 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1111,16 +1111,9 @@ bool cmMoveFile(std::wstring const& oldname, std::wstring const& newname,
}
#endif
-bool cmSystemTools::CopySingleFile(const std::string& oldname,
- const std::string& newname)
-{
- return cmSystemTools::CopySingleFile(oldname, newname, CopyWhen::Always) ==
- CopyResult::Success;
-}
-
cmSystemTools::CopyResult cmSystemTools::CopySingleFile(
std::string const& oldname, std::string const& newname, CopyWhen when,
- std::string* err)
+ CopyInputRecent inputRecent, std::string* err)
{
switch (when) {
case CopyWhen::Always:
@@ -1140,23 +1133,50 @@ cmSystemTools::CopyResult cmSystemTools::CopySingleFile(
return CopyResult::Success;
}
- cmsys::Status status;
+ cmsys::SystemTools::CopyStatus status;
status = cmsys::SystemTools::CloneFileContent(oldname, newname);
if (!status) {
// if cloning did not succeed, fall back to blockwise copy
+#ifdef _WIN32
+ if (inputRecent == CopyInputRecent::Yes) {
+ // Windows sometimes locks a file immediately after creation.
+ // Retry a few times.
+ WindowsFileRetry retry = cmSystemTools::GetWindowsFileRetry();
+ while ((status =
+ cmsys::SystemTools::CopyFileContentBlockwise(oldname, newname),
+ status.Path == cmsys::SystemTools::CopyStatus::SourcePath &&
+ status.GetPOSIX() == EACCES && --retry.Count)) {
+ cmSystemTools::Delay(retry.Delay);
+ }
+ } else {
+ status = cmsys::SystemTools::CopyFileContentBlockwise(oldname, newname);
+ }
+#else
+ static_cast<void>(inputRecent);
status = cmsys::SystemTools::CopyFileContentBlockwise(oldname, newname);
+#endif
}
if (!status) {
if (err) {
*err = status.GetString();
+ switch (status.Path) {
+ case cmsys::SystemTools::CopyStatus::SourcePath:
+ *err = cmStrCat(*err, " (input)");
+ break;
+ case cmsys::SystemTools::CopyStatus::DestPath:
+ *err = cmStrCat(*err, " (output)");
+ break;
+ default:
+ break;
+ }
}
return CopyResult::Failure;
}
if (perms) {
- status = SystemTools::SetPermissions(newname, perm);
- if (!status) {
+ perms = SystemTools::SetPermissions(newname, perm);
+ if (!perms) {
if (err) {
- *err = status.GetString();
+ *err = cmStrCat(perms.GetString(), " (output)");
}
return CopyResult::Failure;
}
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 87b354c..09f2bf0 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -149,6 +149,11 @@ public:
Always,
OnlyIfDifferent,
};
+ enum class CopyInputRecent
+ {
+ No,
+ Yes,
+ };
enum class CopyResult
{
Success,
@@ -177,10 +182,9 @@ public:
const mode_t* mode = nullptr);
/** Copy a file. */
- static bool CopySingleFile(const std::string& oldname,
- const std::string& newname);
static CopyResult CopySingleFile(std::string const& oldname,
std::string const& newname, CopyWhen when,
+ CopyInputRecent inputRecent,
std::string* err = nullptr);
enum class Replace
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 874195b..37f9e98 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -526,6 +526,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("ANDROID_ANT_ADDITIONAL_OPTIONS");
initProp("BUILD_RPATH");
initProp("BUILD_RPATH_USE_ORIGIN");
+ initProp("CXX_SCAN_FOR_MODULES");
initProp("INSTALL_NAME_DIR");
initProp("INSTALL_REMOVE_ENVIRONMENT_RPATH");
initPropValue("INSTALL_RPATH", "");
@@ -572,12 +573,14 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("NO_SYSTEM_FROM_IMPORTED");
initProp("BUILD_WITH_INSTALL_NAME_DIR");
initProp("C_CLANG_TIDY");
+ initProp("C_CLANG_TIDY_EXPORT_FIXES_DIR");
initProp("C_CPPLINT");
initProp("C_CPPCHECK");
initProp("C_INCLUDE_WHAT_YOU_USE");
initProp("C_LINKER_LAUNCHER");
initProp("LINK_WHAT_YOU_USE");
initProp("CXX_CLANG_TIDY");
+ initProp("CXX_CLANG_TIDY_EXPORT_FIXES_DIR");
initProp("CXX_CPPLINT");
initProp("CXX_CPPCHECK");
initProp("CXX_INCLUDE_WHAT_YOU_USE");
@@ -599,8 +602,10 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("LINK_SEARCH_START_STATIC");
initProp("LINK_SEARCH_END_STATIC");
initProp("OBJC_CLANG_TIDY");
+ initProp("OBJC_CLANG_TIDY_EXPORT_FIXES_DIR");
initProp("OBJC_LINKER_LAUNCHER");
initProp("OBJCXX_CLANG_TIDY");
+ initProp("OBJCXX_CLANG_TIDY_EXPORT_FIXES_DIR");
initProp("OBJCXX_LINKER_LAUNCHER");
initProp("Swift_LANGUAGE_VERSION");
initProp("Swift_MODULE_DIRECTORY");
@@ -2657,7 +2662,8 @@ std::pair<cmFileSet*, bool> cmTarget::GetOrCreateFileSet(
const std::string& name, const std::string& type, cmFileSetVisibility vis)
{
auto result = this->impl->FileSets.emplace(
- std::make_pair(name, cmFileSet(name, type, vis)));
+ name,
+ cmFileSet(*this->GetMakefile()->GetCMakeInstance(), name, type, vis));
if (result.second) {
auto bt = this->impl->Makefile->GetBacktrace();
if (type == this->impl->HeadersFileSets.TypeName) {
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index cb83873..7a2dd09 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -100,8 +100,7 @@ bool cmTargetIncludeDirectoriesCommand(std::vector<std::string> const& args,
{
return TargetIncludeDirectoriesImpl(status).HandleArguments(
args, "INCLUDE_DIRECTORIES",
- static_cast<TargetIncludeDirectoriesImpl::ArgumentFlags>(
- TargetIncludeDirectoriesImpl::PROCESS_BEFORE |
+ TargetIncludeDirectoriesImpl::PROCESS_BEFORE |
TargetIncludeDirectoriesImpl::PROCESS_AFTER |
- TargetIncludeDirectoriesImpl::PROCESS_SYSTEM));
+ TargetIncludeDirectoriesImpl::PROCESS_SYSTEM);
}
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index 391b954..8d2ff71 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -23,7 +23,7 @@ void cmTargetPropCommandBase::SetError(std::string const& e)
bool cmTargetPropCommandBase::HandleArguments(
std::vector<std::string> const& args, const std::string& prop,
- ArgumentFlags flags)
+ unsigned int flags)
{
if (args.size() < 2) {
this->SetError("called with incorrect number of arguments");
diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h
index 6bf7c3c..ac50b4d 100644
--- a/Source/cmTargetPropCommandBase.h
+++ b/Source/cmTargetPropCommandBase.h
@@ -24,13 +24,12 @@ public:
NO_FLAGS = 0x0,
PROCESS_BEFORE = 0x1,
PROCESS_AFTER = 0x2,
- PROCESS_SYSTEM = 0x3,
- PROCESS_REUSE_FROM = 0x4
+ PROCESS_SYSTEM = 0x4,
+ PROCESS_REUSE_FROM = 0x8
};
bool HandleArguments(std::vector<std::string> const& args,
- const std::string& prop,
- ArgumentFlags flags = NO_FLAGS);
+ const std::string& prop, unsigned int flags = NO_FLAGS);
protected:
std::string Property;
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index dbb0876..5e325dd 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -127,7 +127,8 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
this->TestGenerated = true;
// Set up generator expression evaluation context.
- cmGeneratorExpression ge(this->Test->GetBacktrace());
+ cmGeneratorExpression ge(*this->Test->GetMakefile()->GetCMakeInstance(),
+ this->Test->GetBacktrace());
// Determine if policy CMP0110 is set to NEW.
const bool quote_test_name =
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index 677fdb6..7e47b4e 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -128,8 +128,8 @@ std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT,
: static_cast<char>(0);
if (c1 == '%' && c2 != 0) {
- result +=
- this->AddTimestampComponent(c2, timeStruct, timeT, microseconds);
+ result += this->AddTimestampComponent(c2, timeStruct, timeT, utcFlag,
+ microseconds);
++i;
} else {
result += c1;
@@ -179,7 +179,7 @@ time_t cmTimestamp::CreateUtcTimeTFromTm(struct tm& tm) const
}
std::string cmTimestamp::AddTimestampComponent(
- char flag, struct tm& timeStruct, const time_t timeT,
+ char flag, struct tm& timeStruct, const time_t timeT, const bool utcFlag,
const uint32_t microseconds) const
{
std::string formatString = cmStrCat('%', flag);
@@ -203,6 +203,63 @@ std::string cmTimestamp::AddTimestampComponent(
case 'Y':
case '%':
break;
+ case 'Z':
+#if defined(__GLIBC__)
+ // 'struct tm' has the time zone, so strftime can honor UTC.
+ static_cast<void>(utcFlag);
+#else
+ // 'struct tm' may not have the time zone, so strftime may
+ // use local time. Hard-code the UTC result.
+ if (utcFlag) {
+ return std::string("GMT");
+ }
+#endif
+ break;
+ case 'z': {
+#if defined(__GLIBC__)
+ // 'struct tm' has the time zone, so strftime can honor UTC.
+ static_cast<void>(utcFlag);
+#else
+ // 'struct tm' may not have the time zone, so strftime may
+ // use local time. Hard-code the UTC result.
+ if (utcFlag) {
+ return std::string("+0000");
+ }
+#endif
+#ifndef _AIX
+ break;
+#else
+ std::string xpg_sus_old;
+ bool const xpg_sus_was_set =
+ cmSystemTools::GetEnv("XPG_SUS_ENV", xpg_sus_old);
+ if (xpg_sus_was_set && xpg_sus_old == "ON") {
+ break;
+ }
+ xpg_sus_old = "XPG_SUS_ENV=" + xpg_sus_old;
+
+ // On AIX systems, %z requires XPG_SUS_ENV=ON to work as desired.
+ cmSystemTools::PutEnv("XPG_SUS_ENV=ON");
+ tzset();
+
+ char buffer[16];
+ size_t size = strftime(buffer, sizeof(buffer), "%z", &timeStruct);
+
+# ifndef CMAKE_BOOTSTRAP
+ if (xpg_sus_was_set) {
+ cmSystemTools::PutEnv(xpg_sus_old);
+ } else {
+ cmSystemTools::UnsetEnv("XPG_SUS_ENV");
+ }
+# else
+ // No UnsetEnv during bootstrap. This is good enough for CMake itself.
+ cmSystemTools::PutEnv(xpg_sus_old);
+ static_cast<void>(xpg_sus_was_set);
+# endif
+ tzset();
+
+ return std::string(buffer, size);
+#endif
+ }
case 's': // Seconds since UNIX epoch (midnight 1-jan-1970)
{
// Build a time_t for UNIX epoch and subtract from the input "timeT":
diff --git a/Source/cmTimestamp.h b/Source/cmTimestamp.h
index ada5006..05c6342 100644
--- a/Source/cmTimestamp.h
+++ b/Source/cmTimestamp.h
@@ -32,6 +32,6 @@ private:
time_t CreateUtcTimeTFromTm(struct tm& timeStruct) const;
std::string AddTimestampComponent(char flag, struct tm& timeStruct,
- time_t timeT,
- uint32_t microseconds = 0) const;
+ time_t timeT, bool utcFlag,
+ uint32_t microseconds) const;
};
diff --git a/Source/cmTryCompileCommand.cxx b/Source/cmTryCompileCommand.cxx
index a2c4ce1..c70c03e 100644
--- a/Source/cmTryCompileCommand.cxx
+++ b/Source/cmTryCompileCommand.cxx
@@ -2,6 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTryCompileCommand.h"
+#include <cm/optional>
+
+#include "cmConfigureLog.h"
#include "cmCoreTryCompile.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
@@ -13,6 +16,24 @@
#include "cmValue.h"
#include "cmake.h"
+namespace {
+#ifndef CMAKE_BOOTSTRAP
+void WriteTryCompileEvent(cmConfigureLog& log, cmMakefile const& mf,
+ cmTryCompileResult const& compileResult)
+{
+ // Keep in sync with cmFileAPIConfigureLog's DumpEventKindNames.
+ static const std::vector<unsigned long> LogVersionsWithTryCompileV1{ 1 };
+
+ if (log.IsAnyLogVersionEnabled(LogVersionsWithTryCompileV1)) {
+ log.BeginEvent("try_compile-v1");
+ log.WriteBacktrace(mf);
+ cmCoreTryCompile::WriteTryCompileEventFields(log, compileResult);
+ log.EndEvent();
+ }
+}
+#endif
+}
+
bool cmTryCompileCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -59,7 +80,15 @@ bool cmTryCompileCommand(std::vector<std::string> const& args,
if (!arguments) {
return true;
}
- tc.TryCompileCode(arguments, targetType);
+
+ if (cm::optional<cmTryCompileResult> compileResult =
+ tc.TryCompileCode(arguments, targetType)) {
+#ifndef CMAKE_BOOTSTRAP
+ if (cmConfigureLog* log = mf.GetCMakeInstance()->GetConfigureLog()) {
+ WriteTryCompileEvent(*log, mf, *compileResult);
+ }
+#endif
+ }
// if They specified clean then we clean up what we can
if (tc.SrcFileSignature) {
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index 8d62cb1..ef59c32 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -3,12 +3,15 @@
#include "cmTryRunCommand.h"
#include <cstdio>
+#include <stdexcept>
#include <cm/optional>
+#include <cmext/string_view>
#include "cmsys/FStream.hxx"
#include "cmArgumentParserTypes.h"
+#include "cmConfigureLog.h"
#include "cmCoreTryCompile.h"
#include "cmDuration.h"
#include "cmExecutionStatus.h"
@@ -23,6 +26,49 @@
#include "cmake.h"
namespace {
+struct cmTryRunResult
+{
+ bool VariableCached = true;
+ std::string Variable;
+ cm::optional<std::string> Stdout;
+ cm::optional<std::string> Stderr;
+ cm::optional<std::string> ExitCode;
+};
+
+#ifndef CMAKE_BOOTSTRAP
+void WriteTryRunEvent(cmConfigureLog& log, cmMakefile const& mf,
+ cmTryCompileResult const& compileResult,
+ cmTryRunResult const& runResult)
+{
+ // Keep in sync with cmFileAPIConfigureLog's DumpEventKindNames.
+ static const std::vector<unsigned long> LogVersionsWithTryRunV1{ 1 };
+
+ if (log.IsAnyLogVersionEnabled(LogVersionsWithTryRunV1)) {
+ log.BeginEvent("try_run-v1");
+ log.WriteBacktrace(mf);
+ cmCoreTryCompile::WriteTryCompileEventFields(log, compileResult);
+
+ log.BeginObject("runResult"_s);
+ log.WriteValue("variable"_s, runResult.Variable);
+ log.WriteValue("cached"_s, runResult.VariableCached);
+ if (runResult.Stdout) {
+ log.WriteLiteralTextBlock("stdout"_s, *runResult.Stdout);
+ }
+ if (runResult.Stderr) {
+ log.WriteLiteralTextBlock("stderr"_s, *runResult.Stderr);
+ }
+ if (runResult.ExitCode) {
+ try {
+ log.WriteValue("exitCode"_s, std::stoi(*runResult.ExitCode));
+ } catch (std::invalid_argument const&) {
+ log.WriteValue("exitCode"_s, *runResult.ExitCode);
+ }
+ }
+ log.EndObject();
+ log.EndEvent();
+ }
+}
+#endif
class TryRunCommandImpl : public cmCoreTryCompile
{
@@ -44,7 +90,8 @@ public:
std::string const& compileResultVariable,
std::string* runOutputContents,
std::string* runOutputStdOutContents,
- std::string* runOutputStdErrContents);
+ std::string* runOutputStdErrContents,
+ bool stdOutErrRequired);
bool NoCache;
std::string RunResultVariable;
@@ -96,23 +143,35 @@ bool TryRunCommandImpl::TryRunCode(std::vector<std::string> const& argv)
}
bool captureRunOutput = false;
- bool captureRunOutputStdOutErr = false;
if (arguments.OutputVariable) {
captureRunOutput = true;
} else if (arguments.CompileOutputVariable) {
arguments.OutputVariable = arguments.CompileOutputVariable;
}
- if (arguments.RunOutputStdOutVariable || arguments.RunOutputStdErrVariable) {
- captureRunOutputStdOutErr = true;
- } else if (arguments.RunOutputVariable) {
- captureRunOutput = true;
+
+ // Capture the split output for the configure log unless the caller
+ // requests combined output to be captured by a variable.
+ bool captureRunOutputStdOutErr = true;
+ if (!arguments.RunOutputStdOutVariable &&
+ !arguments.RunOutputStdErrVariable) {
+ if (arguments.RunOutputVariable) {
+ captureRunOutput = true;
+ captureRunOutputStdOutErr = false;
+ } else if (arguments.OutputVariable) {
+ captureRunOutputStdOutErr = false;
+ }
}
// do the try compile
- bool compiled = this->TryCompileCode(arguments, cmStateEnums::EXECUTABLE);
+ cm::optional<cmTryCompileResult> compileResult =
+ this->TryCompileCode(arguments, cmStateEnums::EXECUTABLE);
+
+ cmTryRunResult runResult;
+ runResult.Variable = this->RunResultVariable;
+ runResult.VariableCached = !arguments.NoCache;
// now try running the command if it compiled
- if (compiled) {
+ if (compileResult && compileResult->ExitCode == 0) {
if (this->OutputFile.empty()) {
cmSystemTools::Error(this->FindErrorMessage);
} else {
@@ -127,26 +186,35 @@ bool TryRunCommandImpl::TryRunCode(std::vector<std::string> const& argv)
std::string runOutputStdErrContents;
if (this->Makefile->IsOn("CMAKE_CROSSCOMPILING") &&
!this->Makefile->IsDefinitionSet("CMAKE_CROSSCOMPILING_EMULATOR")) {
+ // We only require the stdout/stderr cache entries if the project
+ // actually asked for the values, not just for logging.
+ bool const stdOutErrRequired = (arguments.RunOutputStdOutVariable ||
+ arguments.RunOutputStdErrVariable);
this->DoNotRunExecutable(
runArgs, arguments.SourceDirectoryOrFile,
*arguments.CompileResultVariable,
captureRunOutput ? &runOutputContents : nullptr,
- captureRunOutputStdOutErr && arguments.RunOutputStdOutVariable
- ? &runOutputStdOutContents
- : nullptr,
- captureRunOutputStdOutErr && arguments.RunOutputStdErrVariable
- ? &runOutputStdErrContents
- : nullptr);
+ captureRunOutputStdOutErr ? &runOutputStdOutContents : nullptr,
+ captureRunOutputStdOutErr ? &runOutputStdErrContents : nullptr,
+ stdOutErrRequired);
} else {
this->RunExecutable(
runArgs, arguments.RunWorkingDirectory,
captureRunOutput ? &runOutputContents : nullptr,
- captureRunOutputStdOutErr && arguments.RunOutputStdOutVariable
- ? &runOutputStdOutContents
- : nullptr,
- captureRunOutputStdOutErr && arguments.RunOutputStdErrVariable
- ? &runOutputStdErrContents
- : nullptr);
+ captureRunOutputStdOutErr ? &runOutputStdOutContents : nullptr,
+ captureRunOutputStdOutErr ? &runOutputStdErrContents : nullptr);
+ }
+
+ if (captureRunOutputStdOutErr) {
+ runResult.Stdout = runOutputStdOutContents;
+ runResult.Stderr = runOutputStdErrContents;
+ } else {
+ runResult.Stdout = runOutputContents;
+ }
+
+ if (cmValue ec =
+ this->Makefile->GetDefinition(this->RunResultVariable)) {
+ runResult.ExitCode = *ec;
}
// now put the output into the variables
@@ -177,6 +245,15 @@ bool TryRunCommandImpl::TryRunCode(std::vector<std::string> const& argv)
}
}
+#ifndef CMAKE_BOOTSTRAP
+ if (compileResult) {
+ cmMakefile const& mf = *(this->Makefile);
+ if (cmConfigureLog* log = mf.GetCMakeInstance()->GetConfigureLog()) {
+ WriteTryRunEvent(*log, mf, *compileResult, runResult);
+ }
+ }
+#endif
+
// if we created a directory etc, then cleanup after ourselves
if (!this->Makefile->GetCMakeInstance()->GetDebugTryCompile()) {
this->CleanupFiles(this->BinaryDirectory);
@@ -240,7 +317,7 @@ void TryRunCommandImpl::RunExecutable(const std::string& runArgs,
void TryRunCommandImpl::DoNotRunExecutable(
const std::string& runArgs, cm::optional<std::string> const& srcFile,
std::string const& compileResultVariable, std::string* out,
- std::string* stdOut, std::string* stdErr)
+ std::string* stdOut, std::string* stdErr, bool stdOutErrRequired)
{
// copy the executable out of the CMakeFiles/ directory, so it is not
// removed at the end of try_run() and the user can run it manually
@@ -286,7 +363,7 @@ void TryRunCommandImpl::DoNotRunExecutable(
}
// is the output from the executable used ?
- if (stdOut || stdErr) {
+ if (stdOutErrRequired) {
if (!this->Makefile->GetDefinition(internalRunOutputStdOutName)) {
// if the variables doesn't exist, create it with a helpful error text
// and mark it as advanced
diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx
index 6040fd8..3faf2f6 100644
--- a/Source/cmUVProcessChain.cxx
+++ b/Source/cmUVProcessChain.cxx
@@ -241,6 +241,7 @@ bool cmUVProcessChain::InternalData::AddCommand(
options.file = config.Arguments[0].c_str();
std::vector<const char*> arguments;
+ arguments.reserve(config.Arguments.size());
for (auto const& arg : config.Arguments) {
arguments.push_back(arg.c_str());
}
diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx
index 8764f21..6702b7b 100644
--- a/Source/cmVSSetupHelper.cxx
+++ b/Source/cmVSSetupHelper.cxx
@@ -87,12 +87,11 @@ std::string VSInstanceInfo::GetInstallLocation() const
cmVSSetupAPIHelper::cmVSSetupAPIHelper(unsigned int version)
: Version(version)
- , setupConfig(NULL)
- , setupConfig2(NULL)
- , setupHelper(NULL)
- , initializationFailure(false)
+ , setupConfig(nullptr)
+ , setupConfig2(nullptr)
+ , setupHelper(nullptr)
{
- comInitialized = CoInitializeEx(NULL, 0);
+ comInitialized = CoInitializeEx(nullptr, 0);
if (SUCCEEDED(comInitialized)) {
Initialize();
} else {
@@ -102,11 +101,12 @@ cmVSSetupAPIHelper::cmVSSetupAPIHelper(unsigned int version)
cmVSSetupAPIHelper::~cmVSSetupAPIHelper()
{
- setupHelper = NULL;
- setupConfig2 = NULL;
- setupConfig = NULL;
- if (SUCCEEDED(comInitialized))
+ setupHelper = nullptr;
+ setupConfig2 = nullptr;
+ setupConfig = nullptr;
+ if (SUCCEEDED(comInitialized)) {
CoUninitialize();
+ }
}
bool cmVSSetupAPIHelper::SetVSInstance(std::string const& vsInstallLocation,
@@ -159,12 +159,12 @@ bool cmVSSetupAPIHelper::CheckInstalledComponent(
// the
// component name ex: Microsoft.VisualStudio.Component.Windows10SDK.10240
if (id.find(Win10SDKComponent) != std::wstring::npos &&
- type.compare(ComponentType) == 0) {
+ type == ComponentType) {
bWin10SDK = true;
ret = true;
}
- if (id.compare(Win81SDKComponent) == 0 && type.compare(ComponentType) == 0) {
+ if (id == Win81SDKComponent && type == ComponentType) {
bWin81SDK = true;
ret = true;
}
@@ -177,8 +177,9 @@ bool cmVSSetupAPIHelper::CheckInstalledComponent(
bool cmVSSetupAPIHelper::GetVSInstanceInfo(
SmartCOMPtr<ISetupInstance2> pInstance, VSInstanceInfo& vsInstanceInfo)
{
- if (pInstance == NULL)
+ if (pInstance == nullptr) {
return false;
+ }
InstanceState state;
if (FAILED(pInstance->GetState(&state))) {
@@ -188,21 +189,19 @@ bool cmVSSetupAPIHelper::GetVSInstanceInfo(
SmartBSTR bstrVersion;
if (FAILED(pInstance->GetInstallationVersion(&bstrVersion))) {
return false;
- } else {
- vsInstanceInfo.Version =
- cmsys::Encoding::ToNarrow(std::wstring(bstrVersion));
}
+ vsInstanceInfo.Version =
+ cmsys::Encoding::ToNarrow(std::wstring(bstrVersion));
// Reboot may have been required before the installation path was created.
SmartBSTR bstrInstallationPath;
if ((eLocal & state) == eLocal) {
if (FAILED(pInstance->GetInstallationPath(&bstrInstallationPath))) {
return false;
- } else {
- vsInstanceInfo.VSInstallLocation =
- cmsys::Encoding::ToNarrow(std::wstring(bstrInstallationPath));
- cmSystemTools::ConvertToUnixSlashes(vsInstanceInfo.VSInstallLocation);
}
+ vsInstanceInfo.VSInstallLocation =
+ cmsys::Encoding::ToNarrow(std::wstring(bstrInstallationPath));
+ cmSystemTools::ConvertToUnixSlashes(vsInstanceInfo.VSInstallLocation);
}
// Check if a compiler is installed with this instance.
@@ -220,7 +219,7 @@ bool cmVSSetupAPIHelper::GetVSInstanceInfo(
LPSAFEARRAY lpsaPackages;
if (FAILED(pInstance->GetPackages(&lpsaPackages)) ||
- lpsaPackages == NULL) {
+ lpsaPackages == nullptr) {
return false;
}
@@ -229,11 +228,12 @@ bool cmVSSetupAPIHelper::GetVSInstanceInfo(
IUnknown** ppData = (IUnknown**)lpsaPackages->pvData;
for (int i = lower; i < upper; i++) {
- SmartCOMPtr<ISetupPackageReference> package = NULL;
+ SmartCOMPtr<ISetupPackageReference> package = nullptr;
if (FAILED(ppData[i]->QueryInterface(IID_ISetupPackageReference,
(void**)&package)) ||
- package == NULL)
+ package == nullptr) {
continue;
+ }
bool win10SDKInstalled = false;
bool win81SDkInstalled = false;
@@ -289,7 +289,8 @@ bool cmVSSetupAPIHelper::GetVCToolsetVersion(std::string& vsToolsetVersion)
bool cmVSSetupAPIHelper::IsEWDKEnabled()
{
- std::string envEnterpriseWDK, envDisableRegistryUse;
+ std::string envEnterpriseWDK;
+ std::string envDisableRegistryUse;
cmSystemTools::GetEnv("EnterpriseWDK", envEnterpriseWDK);
cmSystemTools::GetEnv("DisableRegistryUse", envDisableRegistryUse);
if (!cmSystemTools::Strucmp(envEnterpriseWDK.c_str(), "True") &&
@@ -370,11 +371,12 @@ bool cmVSSetupAPIHelper::EnumerateVSInstancesWithVswhere(
bool cmVSSetupAPIHelper::EnumerateVSInstancesWithCOM(
std::vector<VSInstanceInfo>& VSInstances)
{
- if (initializationFailure || setupConfig == NULL || setupConfig2 == NULL ||
- setupHelper == NULL)
+ if (initializationFailure || setupConfig == nullptr ||
+ setupConfig2 == nullptr || setupHelper == nullptr) {
return false;
+ }
- SmartCOMPtr<IEnumSetupInstances> enumInstances = NULL;
+ SmartCOMPtr<IEnumSetupInstances> enumInstances = nullptr;
if (FAILED(
setupConfig2->EnumInstances((IEnumSetupInstances**)&enumInstances)) ||
!enumInstances) {
@@ -382,20 +384,21 @@ bool cmVSSetupAPIHelper::EnumerateVSInstancesWithCOM(
}
SmartCOMPtr<ISetupInstance> instance;
- while (SUCCEEDED(enumInstances->Next(1, &instance, NULL)) && instance) {
- SmartCOMPtr<ISetupInstance2> instance2 = NULL;
+ while (SUCCEEDED(enumInstances->Next(1, &instance, nullptr)) && instance) {
+ SmartCOMPtr<ISetupInstance2> instance2 = nullptr;
if (FAILED(
instance->QueryInterface(IID_ISetupInstance2, (void**)&instance2)) ||
!instance2) {
- instance = NULL;
+ instance = nullptr;
continue;
}
VSInstanceInfo instanceInfo;
bool isInstalled = GetVSInstanceInfo(instance2, instanceInfo);
- instance = instance2 = NULL;
- if (isInstalled)
+ instance = instance2 = nullptr;
+ if (isInstalled) {
VSInstances.push_back(instanceInfo);
+ }
}
return true;
}
@@ -403,18 +406,21 @@ bool cmVSSetupAPIHelper::EnumerateVSInstancesWithCOM(
bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
{
bool isVSInstanceExists = false;
- if (chosenInstanceInfo.VSInstallLocation.compare("") != 0) {
+ if (!chosenInstanceInfo.VSInstallLocation.empty()) {
return true;
}
if (this->IsEWDKEnabled()) {
- std::string envWindowsSdkDir81, envVSVersion, envVsInstallDir;
+ std::string envWindowsSdkDir81;
+ std::string envVSVersion;
+ std::string envVsInstallDir;
cmSystemTools::GetEnv("WindowsSdkDir_81", envWindowsSdkDir81);
cmSystemTools::GetEnv("VisualStudioVersion", envVSVersion);
cmSystemTools::GetEnv("VSINSTALLDIR", envVsInstallDir);
- if (envVSVersion.empty() || envVsInstallDir.empty())
+ if (envVSVersion.empty() || envVsInstallDir.empty()) {
return false;
+ }
chosenInstanceInfo.VSInstallLocation = envVsInstallDir;
chosenInstanceInfo.Version = envVSVersion;
@@ -499,7 +505,7 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
return this->LoadSpecifiedVSInstanceFromDisk();
}
- if (vecVSInstances.size() > 0) {
+ if (!vecVSInstances.empty()) {
isVSInstanceExists = true;
int index = ChooseVSInstance(vecVSInstances);
chosenInstanceInfo = vecVSInstances[index];
@@ -511,11 +517,13 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
int cmVSSetupAPIHelper::ChooseVSInstance(
const std::vector<VSInstanceInfo>& vecVSInstances)
{
- if (vecVSInstances.size() == 0)
+ if (vecVSInstances.empty()) {
return -1;
+ }
- if (vecVSInstances.size() == 1)
+ if (vecVSInstances.size() == 1) {
return 0;
+ }
unsigned int chosenIndex = 0;
for (unsigned int i = 1; i < vecVSInstances.size(); i++) {
@@ -589,32 +597,33 @@ bool cmVSSetupAPIHelper::LoadSpecifiedVSInstanceFromDisk()
bool cmVSSetupAPIHelper::Initialize()
{
- if (initializationFailure)
+ if (initializationFailure) {
return false;
+ }
if (FAILED(comInitialized)) {
initializationFailure = true;
return false;
}
- if (FAILED(setupConfig.CoCreateInstance(CLSID_SetupConfiguration, NULL,
+ if (FAILED(setupConfig.CoCreateInstance(CLSID_SetupConfiguration, nullptr,
IID_ISetupConfiguration,
CLSCTX_INPROC_SERVER)) ||
- setupConfig == NULL) {
+ setupConfig == nullptr) {
initializationFailure = true;
return false;
}
if (FAILED(setupConfig.QueryInterface(IID_ISetupConfiguration2,
(void**)&setupConfig2)) ||
- setupConfig2 == NULL) {
+ setupConfig2 == nullptr) {
initializationFailure = true;
return false;
}
if (FAILED(
setupConfig.QueryInterface(IID_ISetupHelper, (void**)&setupHelper)) ||
- setupHelper == NULL) {
+ setupHelper == nullptr) {
initializationFailure = true;
return false;
}
diff --git a/Source/cmVSSetupHelper.h b/Source/cmVSSetupHelper.h
index a16f00b..b8be9b9 100644
--- a/Source/cmVSSetupHelper.h
+++ b/Source/cmVSSetupHelper.h
@@ -17,18 +17,20 @@ template <class T>
class SmartCOMPtr
{
public:
- SmartCOMPtr() { ptr = NULL; }
+ SmartCOMPtr() = default;
SmartCOMPtr(T* p)
{
ptr = p;
- if (ptr != NULL)
+ if (ptr != nullptr) {
ptr->AddRef();
+ }
}
SmartCOMPtr(const SmartCOMPtr<T>& sptr)
{
ptr = sptr.ptr;
- if (ptr != NULL)
+ if (ptr != nullptr) {
ptr->AddRef();
+ }
}
T** operator&() { return &ptr; }
T* operator->() { return ptr; }
@@ -36,8 +38,9 @@ public:
{
if (*this != p) {
ptr = p;
- if (ptr != NULL)
+ if (ptr != nullptr) {
ptr->AddRef();
+ }
}
return *this;
}
@@ -45,11 +48,10 @@ public:
template <class I>
HRESULT QueryInterface(REFCLSID rclsid, I** pp)
{
- if (pp != NULL) {
+ if (pp != nullptr) {
return ptr->QueryInterface(rclsid, (void**)pp);
- } else {
- return E_FAIL;
}
+ return E_FAIL;
}
HRESULT CoCreateInstance(REFCLSID clsid, IUnknown* pUnknown,
REFIID interfaceId, DWORD dwClsContext = CLSCTX_ALL)
@@ -60,18 +62,19 @@ public:
}
~SmartCOMPtr()
{
- if (ptr != NULL)
+ if (ptr != nullptr) {
ptr->Release();
+ }
}
private:
- T* ptr;
+ T* ptr = nullptr;
};
class SmartBSTR
{
public:
- SmartBSTR() { str = NULL; }
+ SmartBSTR() = default;
SmartBSTR(const SmartBSTR& src) = delete;
SmartBSTR& operator=(const SmartBSTR& src) = delete;
operator BSTR() const { return str; }
@@ -79,7 +82,7 @@ public:
~SmartBSTR() throw() { ::SysFreeString(str); }
private:
- BSTR str;
+ BSTR str = nullptr;
};
struct VSInstanceInfo
@@ -129,7 +132,7 @@ private:
SmartCOMPtr<ISetupConfiguration2> setupConfig2;
SmartCOMPtr<ISetupHelper> setupHelper;
// used to indicate failure in Initialize(), so we don't have to call again
- bool initializationFailure;
+ bool initializationFailure = false;
// indicated if COM initialization is successful
HRESULT comInitialized;
// current best instance of VS selected
diff --git a/Source/cmVersionConfig.h.in b/Source/cmVersionConfig.h.in
index 06251f3..5d52950 100644
--- a/Source/cmVersionConfig.h.in
+++ b/Source/cmVersionConfig.h.in
@@ -1,5 +1,7 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
#define CMake_VERSION_MAJOR @CMake_VERSION_MAJOR@
#define CMake_VERSION_MINOR @CMake_VERSION_MINOR@
#define CMake_VERSION_PATCH @CMake_VERSION_PATCH@
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 8882c45..1f45ce3 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -80,10 +80,10 @@ struct cmVisualStudio10TargetGenerator::Elem
bool HasContent = false;
std::string Tag;
- Elem(std::ostream& s, const std::string& tag)
+ Elem(std::ostream& s, std::string tag)
: S(s)
, Indent(0)
- , Tag(tag)
+ , Tag(std::move(tag))
{
this->StartElement();
}
@@ -200,7 +200,7 @@ struct cmVisualStudio10TargetGenerator::OptionsHelper
}
};
-static std::string cmVS10EscapeComment(std::string comment)
+static std::string cmVS10EscapeComment(std::string const& comment)
{
// MSBuild takes the CDATA of a <Message></Message> element and just
// does "echo $CDATA" with no escapes. We must encode the string.
@@ -275,8 +275,8 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator(
this->Makefile->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
this->NsightTegra = gg->IsNsightTegra();
this->Android = gg->TargetsAndroid();
- for (int i = 0; i < 4; ++i) {
- this->NsightTegraVersion[i] = 0;
+ for (unsigned int& version : this->NsightTegraVersion) {
+ version = 0;
}
sscanf(gg->GetNsightTegraVersion().c_str(), "%u.%u.%u.%u",
&this->NsightTegraVersion[0], &this->NsightTegraVersion[1],
@@ -293,9 +293,7 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator(
this->ClassifyAllConfigSources();
}
-cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
-{
-}
+cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator() = default;
std::string cmVisualStudio10TargetGenerator::CalcCondition(
const std::string& config) const
@@ -358,7 +356,8 @@ void cmVisualStudio10TargetGenerator::Generate()
this->GeneratorTarget->CheckCxxModuleStatus(config);
}
- if (this->GeneratorTarget->HaveCxx20ModuleSources()) {
+ if (this->GeneratorTarget->HaveCxx20ModuleSources() &&
+ !this->GlobalGenerator->SupportsCxxModuleDyndep()) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat("The \"", this->GeneratorTarget->GetName(),
@@ -406,6 +405,9 @@ void cmVisualStudio10TargetGenerator::Generate()
if (!this->ComputeCudaLinkOptions()) {
return;
}
+ if (!this->ComputeMarmasmOptions()) {
+ return;
+ }
if (!this->ComputeMasmOptions()) {
return;
}
@@ -423,7 +425,7 @@ void cmVisualStudio10TargetGenerator::Generate()
cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
this->Name, ProjectFileExtension);
cmGeneratedFileStream BuildFileStream(path);
- const std::string PathToProjectFile = path;
+ const std::string& PathToProjectFile = path;
BuildFileStream.SetCopyIfDifferent(true);
// Write the encoding header into the file
@@ -453,7 +455,7 @@ void cmVisualStudio10TargetGenerator::Generate()
void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
cmGeneratedFileStream& BuildFileStream)
{
- BuildFileStream << "<?xml version=\"1.0\" encoding=\""
+ BuildFileStream << R"(<?xml version="1.0" encoding=")"
<< this->GlobalGenerator->Encoding() << "\"?>";
{
Elem e0(BuildFileStream, "Project");
@@ -725,13 +727,18 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
: customDir +
this->GlobalGenerator
->GetPlatformToolsetCudaVSIntegrationSubdirString() +
- "extras\\visual_studio_integration\\MSBuildExtensions\\";
+ R"(extras\visual_studio_integration\MSBuildExtensions\)";
Elem(e1, "Import")
.Attribute("Project",
std::move(cudaPath) + "CUDA " +
this->GlobalGenerator->GetPlatformToolsetCuda() +
".props");
}
+ if (this->GlobalGenerator->IsMarmasmEnabled()) {
+ Elem(e1, "Import")
+ .Attribute("Project",
+ "$(VCTargetsPath)\\BuildCustomizations\\marmasm.props");
+ }
if (this->GlobalGenerator->IsMasmEnabled()) {
Elem(e1, "Import")
.Attribute("Project",
@@ -823,13 +830,18 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
: customDir +
this->GlobalGenerator
->GetPlatformToolsetCudaVSIntegrationSubdirString() +
- "extras\\visual_studio_integration\\MSBuildExtensions\\";
+ R"(extras\visual_studio_integration\MSBuildExtensions\)";
Elem(e1, "Import")
.Attribute("Project",
std::move(cudaPath) + "CUDA " +
this->GlobalGenerator->GetPlatformToolsetCuda() +
".targets");
}
+ if (this->GlobalGenerator->IsMarmasmEnabled()) {
+ Elem(e1, "Import")
+ .Attribute("Project",
+ "$(VCTargetsPath)\\BuildCustomizations\\marmasm.targets");
+ }
if (this->GlobalGenerator->IsMasmEnabled()) {
Elem(e1, "Import")
.Attribute("Project",
@@ -979,6 +991,8 @@ void cmVisualStudio10TargetGenerator::WriteSdkStyleProjectFile(
this->WriteDotNetDocumentationFile(e0);
this->WriteAllSources(e0);
+ this->WriteEmbeddedResourceGroup(e0);
+ this->WriteXamlFilesGroup(e0);
this->WriteDotNetReferences(e0);
this->WritePackageReferences(e0);
this->WriteProjectReferences(e0);
@@ -1020,8 +1034,9 @@ void cmVisualStudio10TargetGenerator::WriteCommonPropertyGroupGlobals(Elem& e1)
std::vector<std::string> keys = this->GeneratorTarget->GetPropertyKeys();
for (std::string const& keyIt : keys) {
static const cm::string_view prefix = "VS_GLOBAL_";
- if (!cmHasPrefix(keyIt, prefix))
+ if (!cmHasPrefix(keyIt, prefix)) {
continue;
+ }
cm::string_view globalKey = cm::string_view(keyIt).substr(prefix.length());
// Skip invalid or separately-handled properties.
if (globalKey.empty() || globalKey == "PROJECT_TYPES" ||
@@ -1029,8 +1044,9 @@ void cmVisualStudio10TargetGenerator::WriteCommonPropertyGroupGlobals(Elem& e1)
continue;
}
cmValue value = this->GeneratorTarget->GetProperty(keyIt);
- if (!value)
+ if (!value) {
continue;
+ }
e1.Element(globalKey, *value);
}
}
@@ -1043,14 +1059,11 @@ bool cmVisualStudio10TargetGenerator::HasCustomCommands() const
return true;
}
- for (cmGeneratorTarget::AllConfigSource const& si :
- this->GeneratorTarget->GetAllConfigSources()) {
- if (si.Source->GetCustomCommand()) {
- return true;
- }
- }
-
- return false;
+ auto const& config_sources = this->GeneratorTarget->GetAllConfigSources();
+ return std::any_of(config_sources.begin(), config_sources.end(),
+ [](cmGeneratorTarget::AllConfigSource const& si) {
+ return si.Source->GetCustomCommand();
+ });
}
void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0)
@@ -1220,7 +1233,7 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
e2.Attribute("Include", obj);
if (this->ProjectType != VsProjectType::csproj) {
- std::string hFileName = obj.substr(0, obj.find_last_of(".")) + ".h";
+ std::string hFileName = obj.substr(0, obj.find_last_of('.')) + ".h";
e2.Element("DependentUpon", hFileName);
for (std::string const& c : this->Configurations) {
@@ -1912,7 +1925,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
char magic[] = { char(0xEF), char(0xBB), char(0xBF) };
fout.write(magic, 3);
- fout << "<?xml version=\"1.0\" encoding=\""
+ fout << R"(<?xml version="1.0" encoding=")"
<< this->GlobalGenerator->Encoding() << "\"?>";
{
Elem e0(fout, "Project");
@@ -2068,7 +2081,7 @@ void cmVisualStudio10TargetGenerator::WriteHeaderSource(
e2.Element("FileType", "CppForm");
} else if (this->IsXamlHeader(fileName)) {
e2.Element("DependentUpon",
- fileName.substr(0, fileName.find_last_of(".")));
+ fileName.substr(0, fileName.find_last_of('.')));
}
this->FinishWritingSource(e2, toolSettings);
}
@@ -2077,7 +2090,7 @@ void cmVisualStudio10TargetGenerator::ParseSettingsProperty(
const std::string& settingsPropertyValue, ConfigToSettings& toolSettings)
{
if (!settingsPropertyValue.empty()) {
- cmGeneratorExpression ge;
+ cmGeneratorExpression ge(*this->LocalGenerator->GetCMakeInstance());
std::unique_ptr<cmCompiledGeneratorExpression> cge =
ge.Parse(settingsPropertyValue);
@@ -2104,7 +2117,7 @@ void cmVisualStudio10TargetGenerator::ParseSettingsProperty(
bool cmVisualStudio10TargetGenerator::PropertyIsSameInAllConfigs(
const ConfigToSettings& toolSettings, const std::string& propName)
{
- std::string firstPropValue = "";
+ std::string firstPropValue;
for (const auto& configToSettings : toolSettings) {
const std::unordered_map<std::string, std::string>& settings =
configToSettings.second;
@@ -2177,7 +2190,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(
}
// Figure out if there's any additional flags to use
if (cmValue saf = sf->GetProperty("VS_SHADER_FLAGS")) {
- cmGeneratorExpression ge;
+ cmGeneratorExpression ge(*this->LocalGenerator->GetCMakeInstance());
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*saf);
for (const std::string& config : this->Configurations) {
@@ -2190,7 +2203,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(
}
// Figure out if debug information should be generated
if (cmValue sed = sf->GetProperty("VS_SHADER_ENABLE_DEBUG")) {
- cmGeneratorExpression ge;
+ cmGeneratorExpression ge(*this->LocalGenerator->GetCMakeInstance());
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*sed);
for (const std::string& config : this->Configurations) {
@@ -2204,7 +2217,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(
}
// Figure out if optimizations should be disabled
if (cmValue sdo = sf->GetProperty("VS_SHADER_DISABLE_OPTIMIZATIONS")) {
- cmGeneratorExpression ge;
+ cmGeneratorExpression ge(*this->LocalGenerator->GetCMakeInstance());
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*sdo);
for (const std::string& config : this->Configurations) {
@@ -2318,26 +2331,23 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(
this->FinishWritingSource(e2, toolSettings);
if (!deployContent.empty()) {
- cmGeneratorExpression ge;
+ cmGeneratorExpression ge(*this->LocalGenerator->GetCMakeInstance());
std::unique_ptr<cmCompiledGeneratorExpression> cge =
ge.Parse(deployContent);
// Deployment location cannot be set on a configuration basis
if (!deployLocation.empty()) {
e2.Element("Link", deployLocation + "\\%(FileName)%(Extension)");
}
- for (size_t i = 0; i != this->Configurations.size(); ++i) {
- if (cge->Evaluate(this->LocalGenerator, this->Configurations[i]) ==
- "1") {
+ for (auto& config : this->Configurations) {
+ if (cge->Evaluate(this->LocalGenerator, config) == "1") {
e2.WritePlatformConfigTag("DeploymentContent",
"'$(Configuration)|$(Platform)'=='" +
- this->Configurations[i] + "|" +
- this->Platform + "'",
+ config + "|" + this->Platform + "'",
"true");
} else {
e2.WritePlatformConfigTag("ExcludedFromBuild",
"'$(Configuration)|$(Platform)'=='" +
- this->Configurations[i] + "|" +
- this->Platform + "'",
+ config + "|" + this->Platform + "'",
"true");
}
}
@@ -2388,8 +2398,9 @@ void cmVisualStudio10TargetGenerator::WriteSource(Elem& e2,
// added with the plain filename without any path. This means the file will
// show up at root-level of the csproj (where CMakeLists.txt etc. are).
std::string link = this->GetCSharpSourceLink(sf);
- if (link.empty())
+ if (link.empty()) {
link = cmsys::SystemTools::GetFilenameName(sf->GetFullPath());
+ }
e2.Element("Link", link);
}
@@ -2485,6 +2496,9 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
const std::string& lang = si.Source->GetLanguage();
if (lang == "C" || lang == "CXX") {
tool = "ClCompile";
+ } else if (lang == "ASM_MARMASM" &&
+ this->GlobalGenerator->IsMarmasmEnabled()) {
+ tool = "MARMASM";
} else if (lang == "ASM_MASM" &&
this->GlobalGenerator->IsMasmEnabled()) {
tool = "MASM";
@@ -2519,7 +2533,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
Elem e2(e1, tool);
bool isCSharp = (si.Source->GetLanguage() == "CSharp");
- if (isCSharp && exclude_configs.size() > 0) {
+ if (isCSharp && !exclude_configs.empty()) {
std::stringstream conditions;
bool firstConditionSet{ false };
for (const auto& ci : include_configs) {
@@ -2661,7 +2675,7 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
? "C"
: this->GlobalGenerator->GetLanguageFromExtension(ext.c_str());
std::string lang = this->LocalGenerator->GetSourceFileLanguage(sf);
- const char* compileAs = 0;
+ const char* compileAs = nullptr;
if (lang != extLang) {
if (lang == "CXX") {
// force a C++ file type
@@ -2699,6 +2713,8 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
}
for (std::string const& config : this->Configurations) {
+ this->GeneratorTarget->NeedCxxModuleSupport(lang, config);
+
std::string configUpper = cmSystemTools::UpperCase(config);
std::string configDefines = defines;
std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper);
@@ -2711,6 +2727,31 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
configDefines += *ccdefs;
}
+ bool const shouldScanForModules = lang == "CXX"_s &&
+ this->GeneratorTarget->NeedDyndepForSource(lang, config, source);
+ auto const* fs =
+ this->GeneratorTarget->GetFileSetForSource(config, source);
+ const char* compileAsPerConfig = compileAs;
+ if (fs &&
+ (fs->GetType() == "CXX_MODULES"_s ||
+ fs->GetType() == "CXX_MODULE_HEADER_UNITS"_s)) {
+ if (lang == "CXX"_s) {
+ if (fs->GetType() == "CXX_MODULES"_s) {
+ compileAsPerConfig = "CompileAsCppModule";
+ } else {
+ compileAsPerConfig = "CompileAsHeaderUnit";
+ }
+ } else {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(
+ "Target \"", this->GeneratorTarget->Target->GetName(),
+ "\" contains the source\n ", source->GetFullPath(),
+ "\nin a file set of type \"", fs->GetType(),
+ R"(" but the source is not classified as a "CXX" source.)"));
+ }
+ }
+
// We have pch state in the following situation:
// 1. We have SKIP_PRECOMPILE_HEADERS == true
// 2. We are creating the pre-compiled header
@@ -2733,13 +2774,16 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
// if we have flags or defines for this config then
// use them
if (!flags.empty() || !options.empty() || !configDefines.empty() ||
- !includes.empty() || compileAs || noWinRT || !options.empty() ||
- needsPCHFlags) {
+ !includes.empty() || compileAsPerConfig || noWinRT ||
+ !options.empty() || needsPCHFlags) {
cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
cmIDEFlagTable const* flagtable = nullptr;
const std::string& srclang = source->GetLanguage();
if (srclang == "C" || srclang == "CXX") {
flagtable = gg->GetClFlagTable();
+ } else if (srclang == "ASM_MARMASM" &&
+ this->GlobalGenerator->IsMarmasmEnabled()) {
+ flagtable = gg->GetMarmasmFlagTable();
} else if (srclang == "ASM_MASM" &&
this->GlobalGenerator->IsMasmEnabled()) {
flagtable = gg->GetMasmFlagTable();
@@ -2756,8 +2800,13 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
cmVS10GeneratorOptions clOptions(
this->LocalGenerator, cmVisualStudioGeneratorOptions::Compiler,
flagtable, this);
- if (compileAs) {
- clOptions.AddFlag("CompileAs", compileAs);
+ if (compileAsPerConfig) {
+ clOptions.AddFlag("CompileAs", compileAsPerConfig);
+ }
+ if (shouldScanForModules) {
+ clOptions.AddFlag("ScanSourceforModuleDependencies", "true");
+ } else {
+ clOptions.AddFlag("ScanSourceforModuleDependencies", "false");
}
if (noWinRT) {
clOptions.AddFlag("CompileAsWinRT", "false");
@@ -2842,10 +2891,9 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
if (this->IsXamlSource(source->GetFullPath())) {
const std::string& fileName = source->GetFullPath();
e2.Element("DependentUpon",
- fileName.substr(0, fileName.find_last_of(".")));
+ fileName.substr(0, fileName.find_last_of('.')));
}
if (this->ProjectType == VsProjectType::csproj) {
- std::string f = source->GetFullPath();
using CsPropMap = std::map<std::string, std::string>;
CsPropMap sourceFileTags;
this->GetCSharpSourceProperties(&sf, sourceFileTags);
@@ -2886,7 +2934,7 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions(
if (ttype >= cmStateEnums::UTILITY) {
e1.WritePlatformConfigTag(
- "IntDir", cond, "$(Platform)\\$(Configuration)\\$(ProjectName)\\");
+ "IntDir", cond, R"($(Platform)\$(Configuration)\$(ProjectName)\)");
} else {
std::string intermediateDir = cmStrCat(
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget), '/',
@@ -3053,12 +3101,9 @@ std::vector<std::string> cmVisualStudio10TargetGenerator::GetIncludes(
bool cmVisualStudio10TargetGenerator::ComputeClOptions()
{
- for (std::string const& c : this->Configurations) {
- if (!this->ComputeClOptions(c)) {
- return false;
- }
- }
- return true;
+ return std::all_of(
+ this->Configurations.begin(), this->Configurations.end(),
+ [this](std::string const& c) { return this->ComputeClOptions(c); });
}
bool cmVisualStudio10TargetGenerator::ComputeClOptions(
@@ -3274,6 +3319,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
this->GeneratorTarget->GetLanguages(languages, configName);
if (languages.count("C")) {
std::string flagsC;
+ this->LocalGenerator->AddLanguageFlags(
+ flagsC, this->GeneratorTarget, cmBuildStep::Compile, "C", configName);
this->LocalGenerator->AddCompileOptions(flagsC, this->GeneratorTarget,
"C", configName);
Options optC(this->LocalGenerator, Options::Compiler,
@@ -3316,9 +3363,12 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
}
}
- if (this->ProjectType != VsProjectType::csproj && clOptions.IsManaged()) {
+ if (this->ProjectType != VsProjectType::csproj &&
+ (clOptions.IsManaged() || clOptions.HasFlag("CLRSupport"))) {
this->Managed = true;
- std::string managedType = clOptions.GetFlag("CompileAsManaged");
+ std::string managedType = clOptions.HasFlag("CompileAsManaged")
+ ? clOptions.GetFlag("CompileAsManaged")
+ : "Mixed";
if (managedType == "Safe" || managedType == "Pure") {
// force empty calling convention if safe clr is used
clOptions.AddFlag("CallingConvention", "");
@@ -3411,7 +3461,7 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
// add AdditionalUsingDirectories
if (this->AdditionalUsingDirectories.count(configName) > 0) {
std::string dirs;
- for (auto u : this->AdditionalUsingDirectories[configName]) {
+ for (auto const& u : this->AdditionalUsingDirectories[configName]) {
if (!dirs.empty()) {
dirs.append(";");
}
@@ -3424,12 +3474,9 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
bool cmVisualStudio10TargetGenerator::ComputeRcOptions()
{
- for (std::string const& c : this->Configurations) {
- if (!this->ComputeRcOptions(c)) {
- return false;
- }
- }
- return true;
+ return std::all_of(
+ this->Configurations.begin(), this->Configurations.end(),
+ [this](std::string const& c) { return this->ComputeRcOptions(c); });
}
bool cmVisualStudio10TargetGenerator::ComputeRcOptions(
@@ -3478,13 +3525,12 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions()
if (!this->GlobalGenerator->IsCudaEnabled()) {
return true;
}
- for (std::string const& c : this->Configurations) {
- if (this->GeneratorTarget->IsLanguageUsed("CUDA", c) &&
- !this->ComputeCudaOptions(c)) {
- return false;
- }
- }
- return true;
+ return std::all_of(this->Configurations.begin(), this->Configurations.end(),
+ [this](std::string const& c) {
+ return !this->GeneratorTarget->IsLanguageUsed("CUDA",
+ c) ||
+ this->ComputeCudaOptions(c);
+ });
}
bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
@@ -3570,7 +3616,7 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
// limitation by creating the directory and passing the flag ourselves.
pdb = this->ConvertPath(pdb, true);
ConvertToWindowsSlash(pdb);
- std::string const clFd = "-Xcompiler=\"-Fd\\\"" + pdb + "\\\"\"";
+ std::string const clFd = R"(-Xcompiler="-Fd\")" + pdb + R"(\"")";
cudaOptions.AppendFlagString("AdditionalOptions", clFd);
}
}
@@ -3654,12 +3700,9 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions()
if (!this->GlobalGenerator->IsCudaEnabled()) {
return true;
}
- for (std::string const& c : this->Configurations) {
- if (!this->ComputeCudaLinkOptions(c)) {
- return false;
- }
- }
- return true;
+ return std::all_of(
+ this->Configurations.begin(), this->Configurations.end(),
+ [this](std::string const& c) { return this->ComputeCudaLinkOptions(c); });
}
bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions(
@@ -3748,17 +3791,64 @@ void cmVisualStudio10TargetGenerator::WriteCudaLinkOptions(
cudaLinkOptions.OutputFlagMap();
}
+bool cmVisualStudio10TargetGenerator::ComputeMarmasmOptions()
+{
+ if (!this->GlobalGenerator->IsMarmasmEnabled()) {
+ return true;
+ }
+ return std::all_of(
+ this->Configurations.begin(), this->Configurations.end(),
+ [this](std::string const& c) { return this->ComputeMarmasmOptions(c); });
+}
+
+bool cmVisualStudio10TargetGenerator::ComputeMarmasmOptions(
+ std::string const& configName)
+{
+ cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
+ auto pOptions = cm::make_unique<Options>(
+ this->LocalGenerator, Options::MarmasmCompiler, gg->GetMarmasmFlagTable());
+ Options& marmasmOptions = *pOptions;
+
+ std::string flags;
+ this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
+ cmBuildStep::Compile, "ASM_MARMASM",
+ configName);
+
+ marmasmOptions.Parse(flags);
+
+ // Get includes for this target
+ marmasmOptions.AddIncludes(this->GetIncludes(configName, "ASM_MARMASM"));
+
+ this->MarmasmOptions[configName] = std::move(pOptions);
+ return true;
+}
+
+void cmVisualStudio10TargetGenerator::WriteMarmasmOptions(
+ Elem& e1, std::string const& configName)
+{
+ if (!this->MSTools || !this->GlobalGenerator->IsMarmasmEnabled()) {
+ return;
+ }
+ Elem e2(e1, "MARMASM");
+
+ // Preprocessor definitions and includes are shared with clOptions.
+ OptionsHelper clOptions(*(this->ClOptions[configName]), e2);
+ clOptions.OutputPreprocessorDefinitions("ASM_MARMASM");
+
+ OptionsHelper marmasmOptions(*(this->MarmasmOptions[configName]), e2);
+ marmasmOptions.OutputAdditionalIncludeDirectories("ASM_MARMASM");
+ marmasmOptions.PrependInheritedString("AdditionalOptions");
+ marmasmOptions.OutputFlagMap();
+}
+
bool cmVisualStudio10TargetGenerator::ComputeMasmOptions()
{
if (!this->GlobalGenerator->IsMasmEnabled()) {
return true;
}
- for (std::string const& c : this->Configurations) {
- if (!this->ComputeMasmOptions(c)) {
- return false;
- }
- }
- return true;
+ return std::all_of(
+ this->Configurations.begin(), this->Configurations.end(),
+ [this](std::string const& c) { return this->ComputeMasmOptions(c); });
}
bool cmVisualStudio10TargetGenerator::ComputeMasmOptions(
@@ -3810,12 +3900,9 @@ bool cmVisualStudio10TargetGenerator::ComputeNasmOptions()
if (!this->GlobalGenerator->IsNasmEnabled()) {
return true;
}
- for (std::string const& c : this->Configurations) {
- if (!this->ComputeNasmOptions(c)) {
- return false;
- }
- }
- return true;
+ return std::all_of(
+ this->Configurations.begin(), this->Configurations.end(),
+ [this](std::string const& c) { return this->ComputeNasmOptions(c); });
}
bool cmVisualStudio10TargetGenerator::ComputeNasmOptions(
@@ -4452,6 +4539,7 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups(Elem& e0)
// output rc compile flags <ResourceCompile></ResourceCompile>
this->WriteRCOptions(e1, c);
this->WriteCudaOptions(e1, c);
+ this->WriteMarmasmOptions(e1, c);
this->WriteMasmOptions(e1, c);
this->WriteNasmOptions(e1, c);
}
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 17dcecd..166cdf7 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -132,6 +132,9 @@ private:
bool ComputeCudaLinkOptions(std::string const& config);
void WriteCudaLinkOptions(Elem& e1, std::string const& config);
+ bool ComputeMarmasmOptions();
+ bool ComputeMarmasmOptions(std::string const& config);
+ void WriteMarmasmOptions(Elem& e1, std::string const& config);
bool ComputeMasmOptions();
bool ComputeMasmOptions(std::string const& config);
void WriteMasmOptions(Elem& e1, std::string const& config);
@@ -200,7 +203,6 @@ private:
void WriteStdOutEncodingUtf8(Elem& e1);
void UpdateCache();
-private:
friend class cmVS10GeneratorOptions;
using Options = cmVS10GeneratorOptions;
using OptionsMap = std::map<std::string, std::unique_ptr<Options>>;
@@ -208,6 +210,7 @@ private:
OptionsMap RcOptions;
OptionsMap CudaOptions;
OptionsMap CudaLinkOptions;
+ OptionsMap MarmasmOptions;
OptionsMap MasmOptions;
OptionsMap NasmOptions;
OptionsMap LinkOptions;
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index e6f5ece..6e98874 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -51,9 +51,9 @@ cmVisualStudioGeneratorOptions::cmVisualStudioGeneratorOptions(
void cmVisualStudioGeneratorOptions::AddTable(cmVS7FlagTable const* table)
{
if (table) {
- for (int i = 0; i < FlagTableCount; ++i) {
- if (!this->FlagTable[i]) {
- this->FlagTable[i] = table;
+ for (auto& flag : this->FlagTable) {
+ if (!flag) {
+ flag = table;
break;
}
}
@@ -62,8 +62,8 @@ void cmVisualStudioGeneratorOptions::AddTable(cmVS7FlagTable const* table)
void cmVisualStudioGeneratorOptions::ClearTables()
{
- for (int i = 0; i < FlagTableCount; ++i) {
- this->FlagTable[i] = nullptr;
+ for (auto& flag : this->FlagTable) {
+ flag = nullptr;
}
}
@@ -115,8 +115,7 @@ bool cmVisualStudioGeneratorOptions::IsDebug() const
if (this->CurrentTool != CSharpCompiler) {
return this->FlagMap.find("DebugInformationFormat") != this->FlagMap.end();
}
- std::map<std::string, FlagValue>::const_iterator i =
- this->FlagMap.find("DebugType");
+ auto i = this->FlagMap.find("DebugType");
if (i != this->FlagMap.end()) {
if (i->second.size() == 1) {
return i->second[0] != "none";
@@ -138,22 +137,14 @@ bool cmVisualStudioGeneratorOptions::IsManaged() const
bool cmVisualStudioGeneratorOptions::UsingUnicode() const
{
// Look for a _UNICODE definition.
- for (std::string const& di : this->Defines) {
- if (di == "_UNICODE") {
- return true;
- }
- }
- return false;
+ return std::any_of(this->Defines.begin(), this->Defines.end(),
+ [](std::string const& di) { return di == "_UNICODE"; });
}
bool cmVisualStudioGeneratorOptions::UsingSBCS() const
{
// Look for a _SBCS definition.
- for (std::string const& di : this->Defines) {
- if (di == "_SBCS") {
- return true;
- }
- }
- return false;
+ return std::any_of(this->Defines.begin(), this->Defines.end(),
+ [](std::string const& di) { return di == "_SBCS"; });
}
void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration()
@@ -267,8 +258,7 @@ void cmVisualStudioGeneratorOptions::ParseFinish()
}
if (this->CurrentTool == CudaCompiler) {
- std::map<std::string, FlagValue>::iterator i =
- this->FlagMap.find("CudaRuntime");
+ auto i = this->FlagMap.find("CudaRuntime");
if (i != this->FlagMap.end() && i->second.size() == 1) {
std::string& cudaRuntime = i->second[0];
if (cudaRuntime == "static") {
@@ -285,7 +275,7 @@ void cmVisualStudioGeneratorOptions::ParseFinish()
void cmVisualStudioGeneratorOptions::PrependInheritedString(
std::string const& key)
{
- std::map<std::string, FlagValue>::iterator i = this->FlagMap.find(key);
+ auto i = this->FlagMap.find(key);
if (i == this->FlagMap.end() || i->second.size() != 1) {
return;
}
@@ -295,7 +285,7 @@ void cmVisualStudioGeneratorOptions::PrependInheritedString(
void cmVisualStudioGeneratorOptions::Reparse(std::string const& key)
{
- std::map<std::string, FlagValue>::iterator i = this->FlagMap.find(key);
+ auto i = this->FlagMap.find(key);
if (i == this->FlagMap.end() || i->second.size() != 1) {
return;
}
@@ -339,7 +329,7 @@ cmIDEOptions::FlagValue cmVisualStudioGeneratorOptions::TakeFlag(
std::string const& key)
{
FlagValue value;
- std::map<std::string, FlagValue>::iterator i = this->FlagMap.find(key);
+ auto i = this->FlagMap.find(key);
if (i != this->FlagMap.end()) {
value = i->second;
this->FlagMap.erase(i);
@@ -373,8 +363,7 @@ void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions(
if (this->Version != cmGlobalVisualStudioGenerator::VSVersion::VS9) {
oss << "%(" << tag << ")";
}
- std::vector<std::string>::const_iterator de =
- cmRemoveDuplicates(this->Defines);
+ auto de = cmRemoveDuplicates(this->Defines);
for (std::string const& di : cmMakeRange(this->Defines.cbegin(), de)) {
// Escape the definition for the compiler.
std::string define;
diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h
index ed4ee1d..20e2d22 100644
--- a/Source/cmVisualStudioGeneratorOptions.h
+++ b/Source/cmVisualStudioGeneratorOptions.h
@@ -24,6 +24,7 @@ public:
Compiler,
ResourceCompiler,
CudaCompiler,
+ MarmasmCompiler,
MasmCompiler,
NasmCompiler,
Linker,
diff --git a/Source/cmVisualStudioSlnData.cxx b/Source/cmVisualStudioSlnData.cxx
index 2a6dfc4..4b6754e 100644
--- a/Source/cmVisualStudioSlnData.cxx
+++ b/Source/cmVisualStudioSlnData.cxx
@@ -20,33 +20,34 @@ std::string cmSlnProjectEntry::GetProjectConfiguration(
return projectConfigurationMap[solutionConfiguration];
}
-const cm::optional<cmSlnProjectEntry> cmSlnData::GetProjectByGUID(
+cm::optional<cmSlnProjectEntry> cmSlnData::GetProjectByGUID(
const std::string& projectGUID) const
{
- ProjectStorage::const_iterator it(ProjectsByGUID.find(projectGUID));
- if (it != ProjectsByGUID.end())
+ auto it(ProjectsByGUID.find(projectGUID));
+ if (it != ProjectsByGUID.end()) {
return it->second;
- else
- return cm::nullopt;
+ }
+ return cm::nullopt;
}
-const cm::optional<cmSlnProjectEntry> cmSlnData::GetProjectByName(
+cm::optional<cmSlnProjectEntry> cmSlnData::GetProjectByName(
const std::string& projectName) const
{
- ProjectStringIndex::const_iterator it(ProjectNameIndex.find(projectName));
- if (it != ProjectNameIndex.end())
+ auto it(ProjectNameIndex.find(projectName));
+ if (it != ProjectNameIndex.end()) {
return it->second->second;
- else
- return cm::nullopt;
+ }
+ return cm::nullopt;
}
std::vector<cmSlnProjectEntry> cmSlnData::GetProjects() const
{
- ProjectStringIndex::const_iterator it(this->ProjectNameIndex.begin()),
- itEnd(this->ProjectNameIndex.end());
+ auto it(this->ProjectNameIndex.begin());
+ auto itEnd(this->ProjectNameIndex.end());
std::vector<cmSlnProjectEntry> result;
- for (; it != itEnd; ++it)
+ for (; it != itEnd; ++it) {
result.push_back(it->second->second);
+ }
return result;
}
@@ -54,9 +55,10 @@ cmSlnProjectEntry* cmSlnData::AddProject(
const std::string& projectGUID, const std::string& projectName,
const std::string& projectRelativePath)
{
- ProjectStorage::iterator it(ProjectsByGUID.find(projectGUID));
- if (it != ProjectsByGUID.end())
- return NULL;
+ auto it(ProjectsByGUID.find(projectGUID));
+ if (it != ProjectsByGUID.end()) {
+ return nullptr;
+ }
it = ProjectsByGUID
.insert(ProjectStorage::value_type(
projectGUID,
@@ -72,17 +74,20 @@ std::string cmSlnData::GetConfigurationTarget(
{
std::string solutionTarget = solutionConfiguration + "|" + platformName;
cm::optional<cmSlnProjectEntry> project = GetProjectByName(projectName);
- if (!project)
+ if (!project) {
return platformName;
+ }
std::string projectTarget = project->GetProjectConfiguration(solutionTarget);
- if (projectTarget.empty())
+ if (projectTarget.empty()) {
return platformName;
+ }
std::vector<std::string> targetElements =
cmSystemTools::SplitString(projectTarget, '|');
- if (targetElements.size() != 2)
+ if (targetElements.size() != 2) {
return platformName;
+ }
return targetElements[1];
}
diff --git a/Source/cmVisualStudioSlnData.h b/Source/cmVisualStudioSlnData.h
index 100dd9b..5f03895 100644
--- a/Source/cmVisualStudioSlnData.h
+++ b/Source/cmVisualStudioSlnData.h
@@ -13,12 +13,12 @@
class cmSlnProjectEntry
{
public:
- cmSlnProjectEntry() {}
- cmSlnProjectEntry(const std::string& guid, const std::string& name,
- const std::string& relativePath)
- : Guid(guid)
- , Name(name)
- , RelativePath(relativePath)
+ cmSlnProjectEntry() = default;
+ cmSlnProjectEntry(std::string guid, std::string name,
+ std::string relativePath)
+ : Guid(std::move(guid))
+ , Name(std::move(name))
+ , RelativePath(std::move(relativePath))
{
}
@@ -56,10 +56,10 @@ public:
minimumVisualStudioVersion = version;
}
- const cm::optional<cmSlnProjectEntry> GetProjectByGUID(
+ cm::optional<cmSlnProjectEntry> GetProjectByGUID(
const std::string& projectGUID) const;
- const cm::optional<cmSlnProjectEntry> GetProjectByName(
+ cm::optional<cmSlnProjectEntry> GetProjectByName(
const std::string& projectName) const;
std::vector<cmSlnProjectEntry> GetProjects() const;
diff --git a/Source/cmVisualStudioSlnParser.cxx b/Source/cmVisualStudioSlnParser.cxx
index feab895..71c758e 100644
--- a/Source/cmVisualStudioSlnParser.cxx
+++ b/Source/cmVisualStudioSlnParser.cxx
@@ -80,19 +80,19 @@ bool cmVisualStudioSlnParser::ParsedLine::IsKeyValuePair() const
std::string cmVisualStudioSlnParser::ParsedLine::GetArgVerbatim() const
{
- if (this->Arg.second)
+ if (this->Arg.second) {
return Quote + this->Arg.first + Quote;
- else
- return this->Arg.first;
+ }
+ return this->Arg.first;
}
const std::string& cmVisualStudioSlnParser::ParsedLine::GetValue(
size_t idxValue) const
{
- if (idxValue < this->Values.size())
+ if (idxValue < this->Values.size()) {
return this->Values[idxValue].first;
- else
- return BadString;
+ }
+ return BadString;
}
std::string cmVisualStudioSlnParser::ParsedLine::GetValueVerbatim(
@@ -100,12 +100,12 @@ std::string cmVisualStudioSlnParser::ParsedLine::GetValueVerbatim(
{
if (idxValue < this->Values.size()) {
const StringData& data = this->Values[idxValue];
- if (data.second)
+ if (data.second) {
return Quote + data.first + Quote;
- else
- return data.first;
- } else
- return BadString;
+ }
+ return data.first;
+ }
+ return BadString;
}
class cmVisualStudioSlnParser::State
@@ -140,17 +140,17 @@ private:
std::stack<FileState> Stack;
std::string EndIgnoreTag;
DataGroupSet RequestedData;
- size_t CurrentLine;
+ size_t CurrentLine = 0;
void IgnoreUntilTag(const std::string& endTag);
};
cmVisualStudioSlnParser::State::State(DataGroupSet requestedData)
: RequestedData(requestedData)
- , CurrentLine(0)
{
- if (this->RequestedData.test(DataGroupProjectDependenciesBit))
+ if (this->RequestedData.test(DataGroupProjectDependenciesBit)) {
this->RequestedData.set(DataGroupProjectsBit);
+ }
this->Stack.push(FileStateStart);
}
@@ -206,7 +206,7 @@ bool cmVisualStudioSlnParser::State::Process(
this->Stack.push(FileStateTopLevel);
break;
case FileStateTopLevel:
- if (line.GetTag().compare("Project") == 0) {
+ if (line.GetTag() == "Project") {
if (line.GetValueCount() != 3) {
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
return false;
@@ -218,14 +218,15 @@ bool cmVisualStudioSlnParser::State::Process(
return false;
}
this->Stack.push(FileStateProject);
- } else
+ } else {
this->IgnoreUntilTag("EndProject");
- } else if (line.GetTag().compare("Global") == 0) {
+ }
+ } else if (line.GetTag() == "Global") {
this->Stack.push(FileStateGlobal);
- } else if (line.GetTag().compare("VisualStudioVersion") == 0) {
+ } else if (line.GetTag() == "VisualStudioVersion") {
output.SetVisualStudioVersion(line.GetValue(0));
- } else if (line.GetTag().compare("MinimumVisualStudioVersion") == 0) {
+ } else if (line.GetTag() == "MinimumVisualStudioVersion") {
output.SetMinimumVisualStudioVersion(line.GetValue(0));
} else {
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
@@ -233,69 +234,75 @@ bool cmVisualStudioSlnParser::State::Process(
}
break;
case FileStateProject:
- if (line.GetTag().compare("EndProject") == 0)
+ if (line.GetTag() == "EndProject") {
this->Stack.pop();
- else if (line.GetTag().compare("ProjectSection") == 0) {
- if (line.GetArg().compare("ProjectDependencies") == 0 &&
- line.GetValue(0).compare("postProject") == 0) {
- if (this->RequestedData.test(DataGroupProjectDependenciesBit))
+ } else if (line.GetTag() == "ProjectSection") {
+ if (line.GetArg() == "ProjectDependencies" &&
+ line.GetValue(0) == "postProject") {
+ if (this->RequestedData.test(DataGroupProjectDependenciesBit)) {
this->Stack.push(FileStateProjectDependencies);
- else
+ } else {
this->IgnoreUntilTag("EndProjectSection");
- } else
+ }
+ } else {
this->IgnoreUntilTag("EndProjectSection");
+ }
} else {
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
return false;
}
break;
case FileStateProjectDependencies:
- if (line.GetTag().compare("EndProjectSection") == 0)
+ if (line.GetTag() == "EndProjectSection") {
this->Stack.pop();
- else if (line.IsKeyValuePair())
+ } else if (line.IsKeyValuePair()) {
// implement dependency storing here, once needed
;
- else {
+ } else {
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
return false;
}
break;
case FileStateGlobal:
- if (line.GetTag().compare("EndGlobal") == 0)
+ if (line.GetTag() == "EndGlobal") {
this->Stack.pop();
- else if (line.GetTag().compare("GlobalSection") == 0) {
- if (line.GetArg().compare("SolutionConfigurationPlatforms") == 0 &&
- line.GetValue(0).compare("preSolution") == 0) {
- if (this->RequestedData.test(DataGroupSolutionConfigurationsBit))
+ } else if (line.GetTag() == "GlobalSection") {
+ if (line.GetArg() == "SolutionConfigurationPlatforms" &&
+ line.GetValue(0) == "preSolution") {
+ if (this->RequestedData.test(DataGroupSolutionConfigurationsBit)) {
this->Stack.push(FileStateSolutionConfigurations);
- else
+ } else {
this->IgnoreUntilTag("EndGlobalSection");
- } else if (line.GetArg().compare("ProjectConfigurationPlatforms") ==
- 0 &&
- line.GetValue(0).compare("postSolution") == 0) {
- if (this->RequestedData.test(DataGroupProjectConfigurationsBit))
+ }
+ } else if (line.GetArg() == "ProjectConfigurationPlatforms" &&
+ line.GetValue(0) == "postSolution") {
+ if (this->RequestedData.test(DataGroupProjectConfigurationsBit)) {
this->Stack.push(FileStateProjectConfigurations);
- else
+ } else {
this->IgnoreUntilTag("EndGlobalSection");
- } else if (line.GetArg().compare("NestedProjects") == 0 &&
- line.GetValue(0).compare("preSolution") == 0) {
- if (this->RequestedData.test(DataGroupSolutionFiltersBit))
+ }
+ } else if (line.GetArg() == "NestedProjects" &&
+ line.GetValue(0) == "preSolution") {
+ if (this->RequestedData.test(DataGroupSolutionFiltersBit)) {
this->Stack.push(FileStateSolutionFilters);
- else
+ } else {
this->IgnoreUntilTag("EndGlobalSection");
- } else if (this->RequestedData.test(DataGroupGenericGlobalSectionsBit))
+ }
+ } else if (this->RequestedData.test(
+ DataGroupGenericGlobalSectionsBit)) {
this->Stack.push(FileStateGlobalSection);
- else
+ } else {
this->IgnoreUntilTag("EndGlobalSection");
+ }
} else {
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
return false;
}
break;
case FileStateSolutionConfigurations:
- if (line.GetTag().compare("EndGlobalSection") == 0)
+ if (line.GetTag() == "EndGlobalSection") {
this->Stack.pop();
- else if (line.IsKeyValuePair()) {
+ } else if (line.IsKeyValuePair()) {
output.AddConfiguration(line.GetValue(0));
} else {
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
@@ -303,9 +310,9 @@ bool cmVisualStudioSlnParser::State::Process(
}
break;
case FileStateProjectConfigurations:
- if (line.GetTag().compare("EndGlobalSection") == 0)
+ if (line.GetTag() == "EndGlobalSection") {
this->Stack.pop();
- else if (line.IsKeyValuePair()) {
+ } else if (line.IsKeyValuePair()) {
std::vector<std::string> tagElements =
cmSystemTools::SplitString(line.GetTag(), '.');
if (tagElements.size() != 3 && tagElements.size() != 4) {
@@ -324,7 +331,7 @@ bool cmVisualStudioSlnParser::State::Process(
return false;
}
- if (activeBuild.compare("ActiveCfg") == 0) {
+ if (activeBuild == "ActiveCfg") {
projectEntry->AddProjectConfiguration(solutionConfiguration,
line.GetValue(0));
}
@@ -334,23 +341,23 @@ bool cmVisualStudioSlnParser::State::Process(
}
break;
case FileStateSolutionFilters:
- if (line.GetTag().compare("EndGlobalSection") == 0)
+ if (line.GetTag() == "EndGlobalSection") {
this->Stack.pop();
- else if (line.IsKeyValuePair())
+ } else if (line.IsKeyValuePair()) {
// implement filter storing here, once needed
;
- else {
+ } else {
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
return false;
}
break;
case FileStateGlobalSection:
- if (line.GetTag().compare("EndGlobalSection") == 0)
+ if (line.GetTag() == "EndGlobalSection") {
this->Stack.pop();
- else if (line.IsKeyValuePair())
+ } else if (line.IsKeyValuePair()) {
// implement section storing here, once needed
;
- else {
+ } else {
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
return false;
}
@@ -385,11 +392,7 @@ void cmVisualStudioSlnParser::State::IgnoreUntilTag(const std::string& endTag)
this->EndIgnoreTag = endTag;
}
-cmVisualStudioSlnParser::ResultData::ResultData()
- : Result(ResultOK)
- , ResultLine(0)
-{
-}
+cmVisualStudioSlnParser::ResultData::ResultData() = default;
void cmVisualStudioSlnParser::ResultData::Clear()
{
@@ -487,34 +490,41 @@ bool cmVisualStudioSlnParser::ParseImpl(std::istream& input, cmSlnData& output,
{
std::string line;
// Does the .sln start with a Byte Order Mark?
- if (!this->ParseBOM(input, line, state))
+ if (!this->ParseBOM(input, line, state)) {
return false;
+ }
do {
line = cmTrimWhitespace(line);
- if (line.empty())
+ if (line.empty()) {
continue;
+ }
ParsedLine parsedLine;
switch (state.NextLineFormat()) {
case LineMultiValueTag:
- if (!this->ParseMultiValueTag(line, parsedLine, state))
+ if (!this->ParseMultiValueTag(line, parsedLine, state)) {
return false;
+ }
break;
case LineSingleValueTag:
- if (!this->ParseSingleValueTag(line, parsedLine, state))
+ if (!this->ParseSingleValueTag(line, parsedLine, state)) {
return false;
+ }
break;
case LineKeyValuePair:
- if (!this->ParseKeyValuePair(line, parsedLine, state))
+ if (!this->ParseKeyValuePair(line, parsedLine, state)) {
return false;
+ }
break;
case LineVerbatim:
parsedLine.CopyVerbatim(line);
break;
}
- if (parsedLine.IsComment())
+ if (parsedLine.IsComment()) {
continue;
- if (!state.Process(parsedLine, output, this->LastResult))
+ }
+ if (!state.Process(parsedLine, output, this->LastResult)) {
return false;
+ }
} while (state.ReadLine(input, line));
return state.Finished(this->LastResult);
}
@@ -533,8 +543,9 @@ bool cmVisualStudioSlnParser::ParseBOM(std::istream& input, std::string& line,
this->LastResult.SetError(ResultErrorReadingInput, 1);
return false;
}
- if (!this->LastResult.HadBOM)
+ if (!this->LastResult.HadBOM) {
line = bom + line; // it wasn't a BOM, prepend it to first line
+ }
return true;
}
@@ -544,9 +555,10 @@ bool cmVisualStudioSlnParser::ParseMultiValueTag(const std::string& line,
{
size_t idxEqualSign = line.find('=');
auto fullTag = cm::string_view(line).substr(0, idxEqualSign);
- if (!this->ParseTag(fullTag, parsedLine, state))
+ if (!this->ParseTag(fullTag, parsedLine, state)) {
return false;
- if (idxEqualSign != line.npos) {
+ }
+ if (idxEqualSign != std::string::npos) {
size_t idxFieldStart = idxEqualSign + 1;
if (idxFieldStart < line.size()) {
size_t idxParsing = idxFieldStart;
@@ -554,24 +566,27 @@ bool cmVisualStudioSlnParser::ParseMultiValueTag(const std::string& line,
for (;;) {
idxParsing = line.find_first_of(",\"", idxParsing);
bool fieldOver = false;
- if (idxParsing == line.npos) {
+ if (idxParsing == std::string::npos) {
fieldOver = true;
if (inQuotes) {
this->LastResult.SetError(ResultErrorInputStructure,
state.GetCurrentLine());
return false;
}
- } else if (line[idxParsing] == ',' && !inQuotes)
+ } else if (line[idxParsing] == ',' && !inQuotes) {
fieldOver = true;
- else if (line[idxParsing] == '"')
+ } else if (line[idxParsing] == '"') {
inQuotes = !inQuotes;
+ }
if (fieldOver) {
if (!this->ParseValue(
line.substr(idxFieldStart, idxParsing - idxFieldStart),
- parsedLine))
+ parsedLine)) {
return false;
- if (idxParsing == line.npos)
+ }
+ if (idxParsing == std::string::npos) {
break; // end of last field
+ }
idxFieldStart = idxParsing + 1;
}
++idxParsing;
@@ -587,11 +602,13 @@ bool cmVisualStudioSlnParser::ParseSingleValueTag(const std::string& line,
{
size_t idxEqualSign = line.find('=');
auto fullTag = cm::string_view(line).substr(0, idxEqualSign);
- if (!this->ParseTag(fullTag, parsedLine, state))
+ if (!this->ParseTag(fullTag, parsedLine, state)) {
return false;
- if (idxEqualSign != line.npos) {
- if (!this->ParseValue(line.substr(idxEqualSign + 1), parsedLine))
+ }
+ if (idxEqualSign != std::string::npos) {
+ if (!this->ParseValue(line.substr(idxEqualSign + 1), parsedLine)) {
return false;
+ }
}
return true;
}
@@ -601,7 +618,7 @@ bool cmVisualStudioSlnParser::ParseKeyValuePair(const std::string& line,
State& /*state*/)
{
size_t idxEqualSign = line.find('=');
- if (idxEqualSign == line.npos) {
+ if (idxEqualSign == std::string::npos) {
parsedLine.CopyVerbatim(line);
return true;
}
@@ -636,8 +653,9 @@ bool cmVisualStudioSlnParser::ParseTag(cm::string_view fullTag,
return false;
}
parsedLine.SetQuotedArg(arg.substr(1, arg.size() - 2));
- } else
+ } else {
parsedLine.SetArg(arg);
+ }
return true;
}
@@ -645,11 +663,12 @@ bool cmVisualStudioSlnParser::ParseValue(const std::string& value,
ParsedLine& parsedLine)
{
const std::string& trimmed = cmTrimWhitespace(value);
- if (trimmed.empty())
+ if (trimmed.empty()) {
parsedLine.AddValue(trimmed);
- else if (trimmed.front() == '"' && trimmed.back() == '"')
+ } else if (trimmed.front() == '"' && trimmed.back() == '"') {
parsedLine.AddQuotedValue(trimmed.substr(1, trimmed.size() - 2));
- else
+ } else {
parsedLine.AddValue(trimmed);
+ }
return true;
}
diff --git a/Source/cmVisualStudioSlnParser.h b/Source/cmVisualStudioSlnParser.h
index 60be598..0cac140 100644
--- a/Source/cmVisualStudioSlnParser.h
+++ b/Source/cmVisualStudioSlnParser.h
@@ -73,8 +73,8 @@ protected:
struct ResultData
{
- ParseResult Result;
- size_t ResultLine;
+ ParseResult Result = ResultOK;
+ size_t ResultLine = 0;
bool HadBOM;
ResultData();
diff --git a/Source/cmVisualStudioWCEPlatformParser.cxx b/Source/cmVisualStudioWCEPlatformParser.cxx
index 2f71cf5..d8d0da9 100644
--- a/Source/cmVisualStudioWCEPlatformParser.cxx
+++ b/Source/cmVisualStudioWCEPlatformParser.cxx
@@ -16,9 +16,9 @@ int cmVisualStudioWCEPlatformParser::ParseVersion(const char* version)
const std::string vckey = registryBase + "\\Setup\\VC;ProductDir";
const std::string vskey = registryBase + "\\Setup\\VS;ProductDir";
- if (!cmSystemTools::ReadRegistryValue(vckey.c_str(), this->VcInstallDir,
+ if (!cmSystemTools::ReadRegistryValue(vckey, this->VcInstallDir,
cmSystemTools::KeyWOW64_32) ||
- !cmSystemTools::ReadRegistryValue(vskey.c_str(), this->VsInstallDir,
+ !cmSystemTools::ReadRegistryValue(vskey, this->VsInstallDir,
cmSystemTools::KeyWOW64_32)) {
return 0;
}
@@ -44,13 +44,12 @@ std::string cmVisualStudioWCEPlatformParser::GetOSVersion() const
const char* cmVisualStudioWCEPlatformParser::GetArchitectureFamily() const
{
- std::map<std::string, std::string>::const_iterator it =
- this->Macros.find("ARCHFAM");
+ auto it = this->Macros.find("ARCHFAM");
if (it != this->Macros.end()) {
return it->second.c_str();
}
- return 0;
+ return nullptr;
}
void cmVisualStudioWCEPlatformParser::StartElement(const std::string& name,
diff --git a/Source/cmVisualStudioWCEPlatformParser.h b/Source/cmVisualStudioWCEPlatformParser.h
index 2fff91c..895a90d 100644
--- a/Source/cmVisualStudioWCEPlatformParser.h
+++ b/Source/cmVisualStudioWCEPlatformParser.h
@@ -16,9 +16,8 @@
class cmVisualStudioWCEPlatformParser : public cmXMLParser
{
public:
- cmVisualStudioWCEPlatformParser(const char* name = NULL)
+ cmVisualStudioWCEPlatformParser(const char* name = nullptr)
: RequiredName(name)
- , FoundRequiredName(false)
{
}
@@ -42,9 +41,9 @@ public:
}
protected:
- virtual void StartElement(const std::string& name, const char** attributes);
- void EndElement(const std::string& name);
- void CharacterDataHandler(const char* data, int length);
+ void StartElement(const std::string& name, const char** attributes) override;
+ void EndElement(const std::string& name) override;
+ void CharacterDataHandler(const char* data, int length) override;
private:
std::string FixPaths(const std::string& paths) const;
@@ -61,7 +60,7 @@ private:
std::vector<std::string> AvailablePlatforms;
const char* RequiredName;
- bool FoundRequiredName;
+ bool FoundRequiredName = false;
std::string VcInstallDir;
std::string VsInstallDir;
};
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 013a87b..0d947a5 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -40,7 +40,6 @@
#include "cmCommands.h"
#include "cmDocumentation.h"
#include "cmDocumentationEntry.h"
-#include "cmDocumentationFormatter.h"
#include "cmDuration.h"
#include "cmExternalMakefileProjectGenerator.h"
#include "cmFileTimeCache.h"
@@ -71,6 +70,7 @@
# include <cm3p/curl/curl.h>
# include <cm3p/json/writer.h>
+# include "cmConfigureLog.h"
# include "cmFileAPI.h"
# include "cmGraphVizWriter.h"
# include "cmVariableWatch.h"
@@ -150,21 +150,136 @@ auto IgnoreAndTrueLambda = [](std::string const&, cmake*) -> bool {
using CommandArgument =
cmCommandLineArgument<bool(std::string const& value, cmake* state)>;
-} // namespace
-
-static bool cmakeCheckStampFile(const std::string& stampName);
-static bool cmakeCheckStampList(const std::string& stampList);
-
#ifndef CMAKE_BOOTSTRAP
-static void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/,
- void* ctx, const char* /*unused*/,
- const cmMakefile* /*unused*/)
+void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/,
+ void* ctx, const char* /*unused*/,
+ const cmMakefile* /*unused*/)
{
cmake* cm = reinterpret_cast<cmake*>(ctx);
cm->MarkCliAsUsed(variable);
}
#endif
+bool cmakeCheckStampFile(const std::string& stampName)
+{
+ // The stamp file does not exist. Use the stamp dependencies to
+ // determine whether it is really out of date. This works in
+ // conjunction with cmLocalVisualStudio7Generator to avoid
+ // repeatedly re-running CMake when the user rebuilds the entire
+ // solution.
+ std::string stampDepends = cmStrCat(stampName, ".depend");
+#if defined(_WIN32) || defined(__CYGWIN__)
+ cmsys::ifstream fin(stampDepends.c_str(), std::ios::in | std::ios::binary);
+#else
+ cmsys::ifstream fin(stampDepends.c_str());
+#endif
+ if (!fin) {
+ // The stamp dependencies file cannot be read. Just assume the
+ // build system is really out of date.
+ std::cout << "CMake is re-running because " << stampName
+ << " dependency file is missing.\n";
+ return false;
+ }
+
+ // Compare the stamp dependencies against the dependency file itself.
+ {
+ cmFileTimeCache ftc;
+ std::string dep;
+ while (cmSystemTools::GetLineFromStream(fin, dep)) {
+ int result;
+ if (!dep.empty() && dep[0] != '#' &&
+ (!ftc.Compare(stampDepends, dep, &result) || result < 0)) {
+ // The stamp depends file is older than this dependency. The
+ // build system is really out of date.
+ /* clang-format off */
+ std::cout << "CMake is re-running because " << stampName
+ << " is out-of-date.\n"
+ " the file '" << dep << "'\n"
+ " is newer than '" << stampDepends << "'\n"
+ " result='" << result << "'\n";
+ /* clang-format on */
+ return false;
+ }
+ }
+ }
+
+ // The build system is up to date. The stamp file has been removed
+ // by the VS IDE due to a "rebuild" request. Restore it atomically.
+ std::ostringstream stampTempStream;
+ stampTempStream << stampName << ".tmp" << cmSystemTools::RandomSeed();
+ std::string stampTemp = stampTempStream.str();
+ {
+ // TODO: Teach cmGeneratedFileStream to use a random temp file (with
+ // multiple tries in unlikely case of conflict) and use that here.
+ cmsys::ofstream stamp(stampTemp.c_str());
+ stamp << "# CMake generation timestamp file for this directory.\n";
+ }
+ std::string err;
+ if (cmSystemTools::RenameFile(stampTemp, stampName,
+ cmSystemTools::Replace::Yes, &err) ==
+ cmSystemTools::RenameResult::Success) {
+ // CMake does not need to re-run because the stamp file is up-to-date.
+ return true;
+ }
+ cmSystemTools::RemoveFile(stampTemp);
+ cmSystemTools::Error(
+ cmStrCat("Cannot restore timestamp \"", stampName, "\": ", err));
+ return false;
+}
+
+bool cmakeCheckStampList(const std::string& stampList)
+{
+ // If the stamp list does not exist CMake must rerun to generate it.
+ if (!cmSystemTools::FileExists(stampList)) {
+ std::cout << "CMake is re-running because generate.stamp.list "
+ "is missing.\n";
+ return false;
+ }
+ cmsys::ifstream fin(stampList.c_str());
+ if (!fin) {
+ std::cout << "CMake is re-running because generate.stamp.list "
+ "could not be read.\n";
+ return false;
+ }
+
+ // Check each stamp.
+ std::string stampName;
+ while (cmSystemTools::GetLineFromStream(fin, stampName)) {
+ if (!cmakeCheckStampFile(stampName)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace
+
+cmDocumentationEntry cmake::CMAKE_STANDARD_OPTIONS_TABLE[18] = {
+ { "-S <path-to-source>", "Explicitly specify a source directory." },
+ { "-B <path-to-build>", "Explicitly specify a build directory." },
+ { "-C <initial-cache>", "Pre-load a script to populate the cache." },
+ { "-D <var>[:<type>]=<value>", "Create or update a cmake cache entry." },
+ { "-U <globbing_expr>", "Remove matching entries from CMake cache." },
+ { "-G <generator-name>", "Specify a build system generator." },
+ { "-T <toolset-name>", "Specify toolset name if supported by generator." },
+ { "-A <platform-name>", "Specify platform name if supported by generator." },
+ { "--toolchain <file>", "Specify toolchain file [CMAKE_TOOLCHAIN_FILE]." },
+ { "--install-prefix <directory>",
+ "Specify install directory [CMAKE_INSTALL_PREFIX]." },
+ { "-Wdev", "Enable developer warnings." },
+ { "-Wno-dev", "Suppress developer warnings." },
+ { "-Werror=dev", "Make developer warnings errors." },
+ { "-Wno-error=dev", "Make developer warnings not errors." },
+ { "-Wdeprecated", "Enable deprecation warnings." },
+ { "-Wno-deprecated", "Suppress deprecation warnings." },
+ { "-Werror=deprecated",
+ "Make deprecated macro and function warnings "
+ "errors." },
+ { "-Wno-error=deprecated",
+ "Make deprecated macro and function warnings "
+ "not errors." }
+};
+
cmake::cmake(Role role, cmState::Mode mode, cmState::ProjectKind projectKind)
: CMakeWorkingDirectory(cmSystemTools::GetCurrentWorkingDirectory())
, FileTimeCache(cm::make_unique<cmFileTimeCache>())
@@ -196,7 +311,7 @@ cmake::cmake(Role role, cmState::Mode mode, cmState::ProjectKind projectKind)
this->AddProjectCommands();
}
- if (mode == cmState::Project) {
+ if (mode == cmState::Project || mode == cmState::Help) {
this->LoadEnvironmentPresets();
}
@@ -1008,7 +1123,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
std::cout << "Running with debug output on for the 'find' commands "
"for package(s)";
for (auto const& v : find_pkgs) {
- std::cout << " " << v;
+ std::cout << ' ' << v;
state->SetDebugFindOutputPkgs(v);
}
std::cout << ".\n";
@@ -1021,7 +1136,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
std::vector<std::string> find_vars(cmTokenize(value, ","));
std::cout << "Running with debug output on for the variable(s)";
for (auto const& v : find_vars) {
- std::cout << " " << v;
+ std::cout << ' ' << v;
state->SetDebugFindOutputVars(v);
}
std::cout << ".\n";
@@ -1082,7 +1197,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
[](std::string const&, cmake* state) -> bool {
std::cout
<< "Not searching for unused variables given on the "
- << "command line.\n";
+ "command line.\n";
state->SetWarnUnusedCli(false);
return true;
} },
@@ -1090,7 +1205,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
"--check-system-vars", CommandArgument::Values::Zero,
[](std::string const&, cmake* state) -> bool {
std::cout << "Also check system files when warning about unused and "
- << "uninitialized variables.\n";
+ "uninitialized variables.\n";
state->SetCheckSystemVars(true);
return true;
} },
@@ -1098,7 +1213,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
"--compile-no-warning-as-error", CommandArgument::Values::Zero,
[](std::string const&, cmake* state) -> bool {
std::cout << "Ignoring COMPILE_WARNING_AS_ERROR target property and "
- << "CMAKE_COMPILE_WARNING_AS_ERROR variable.\n";
+ "CMAKE_COMPILE_WARNING_AS_ERROR variable.\n";
state->SetIgnoreWarningAsError(true);
return true;
} }
@@ -1497,7 +1612,7 @@ void cmake::SetTraceFile(const std::string& file)
cmSystemTools::Error(ss.str());
return;
}
- std::cout << "Trace will be written to " << file << "\n";
+ std::cout << "Trace will be written to " << file << '\n';
}
void cmake::PrintTraceFormatVersion()
@@ -1542,6 +1657,16 @@ void cmake::PrintTraceFormatVersion()
}
}
+void cmake::SetTraceRedirect(cmake* other)
+{
+ this->Trace = other->Trace;
+ this->TraceExpand = other->TraceExpand;
+ this->TraceFormatVar = other->TraceFormatVar;
+ this->TraceOnlyThisSources = other->TraceOnlyThisSources;
+
+ this->TraceRedirect = other;
+}
+
bool cmake::SetDirectoriesFromFile(const std::string& arg)
{
// Check if the argument refers to a CMakeCache.txt or
@@ -2010,12 +2135,10 @@ int cmake::HandleDeleteCacheVariables(const std::string& var)
}
std::vector<SaveCacheEntry> saved;
std::ostringstream warning;
- /* clang-format off */
warning
<< "You have changed variables that require your cache to be deleted.\n"
- << "Configure will be re-run and you may have to reset some variables.\n"
- << "The following variables have changed:\n";
- /* clang-format on */
+ "Configure will be re-run and you may have to reset some variables.\n"
+ "The following variables have changed:\n";
for (auto i = argsSplit.begin(); i != argsSplit.end(); ++i) {
SaveCacheEntry save;
save.key = *i;
@@ -2023,9 +2146,9 @@ int cmake::HandleDeleteCacheVariables(const std::string& var)
i++;
if (i != argsSplit.end()) {
save.value = *i;
- warning << *i << "\n";
+ warning << *i << '\n';
} else {
- warning << "\n";
+ warning << '\n';
i -= 1;
}
cmValue existingValue = this->State->GetCacheEntryValue(save.key);
@@ -2060,6 +2183,10 @@ int cmake::HandleDeleteCacheVariables(const std::string& var)
int cmake::Configure()
{
+#if !defined(CMAKE_BOOTSTRAP)
+ auto profilingRAII = this->CreateProfilingEntry("project", "configure");
+#endif
+
DiagLevel diagLevel;
if (this->DiagLevels.count("deprecated") == 1) {
@@ -2297,10 +2424,22 @@ int cmake::ActualConfigure()
#if !defined(CMAKE_BOOTSTRAP)
this->FileAPI = cm::make_unique<cmFileAPI>(this);
this->FileAPI->ReadQueries();
+
+ if (!this->GetIsInTryCompile()) {
+ this->TruncateOutputLog("CMakeConfigureLog.yaml");
+ this->ConfigureLog = cm::make_unique<cmConfigureLog>(
+ cmStrCat(this->GetHomeOutputDirectory(), "/CMakeFiles"_s),
+ this->FileAPI->GetConfigureLogVersions());
+ }
#endif
// actually do the configure
this->GlobalGenerator->Configure();
+
+#if !defined(CMAKE_BOOTSTRAP)
+ this->ConfigureLog.reset();
+#endif
+
// Before saving the cache
// if the project did not define one of the entries below, add them now
// so users can edit the values in the cache:
@@ -2423,7 +2562,7 @@ void cmake::CreateDefaultGlobalGenerator()
auto gen = this->EvaluateDefaultGlobalGenerator();
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
// This print could be unified for all platforms
- std::cout << "-- Building for: " << gen->GetName() << "\n";
+ std::cout << "-- Building for: " << gen->GetName() << '\n';
#endif
this->SetGlobalGenerator(std::move(gen));
}
@@ -2572,12 +2711,17 @@ int cmake::Generate()
if (!this->GlobalGenerator) {
return -1;
}
+
+#if !defined(CMAKE_BOOTSTRAP)
+ auto profilingRAII = this->CreateProfilingEntry("project", "generate");
+#endif
+
if (!this->GlobalGenerator->Compute()) {
return -1;
}
this->GlobalGenerator->Generate();
if (!this->GraphVizFile.empty()) {
- std::cout << "Generate graphviz: " << this->GraphVizFile << std::endl;
+ std::cout << "Generate graphviz: " << this->GraphVizFile << '\n';
this->GenerateGraphViz(this->GraphVizFile);
}
if (this->WarnUnusedCli) {
@@ -2818,17 +2962,15 @@ void cmake::AppendGlobalGeneratorsDocumentation(
std::vector<cmDocumentationEntry>& v)
{
const auto defaultGenerator = this->EvaluateDefaultGlobalGenerator();
- const std::string defaultName = defaultGenerator->GetName();
- bool foundDefaultOne = false;
+ const auto defaultName = defaultGenerator->GetName();
+ auto foundDefaultOne = false;
for (const auto& g : this->Generators) {
- cmDocumentationEntry e;
- g->GetDocumentation(e);
- if (!foundDefaultOne && cmHasPrefix(e.Name, defaultName)) {
- e.CustomNamePrefix = '*';
+ v.emplace_back(g->GetDocumentation());
+ if (!foundDefaultOne && cmHasPrefix(v.back().Name, defaultName)) {
+ v.back().CustomNamePrefix = '*';
foundDefaultOne = true;
}
- v.push_back(std::move(e));
}
}
@@ -2841,21 +2983,14 @@ void cmake::AppendExtraGeneratorsDocumentation(
// Aliases:
for (std::string const& a : eg->Aliases) {
- cmDocumentationEntry e;
- e.Name = a;
- e.Brief = doc;
- v.push_back(std::move(e));
+ v.emplace_back(cmDocumentationEntry{ a, doc });
}
// Full names:
- const std::vector<std::string> generators =
- eg->GetSupportedGlobalGenerators();
- for (std::string const& g : generators) {
- cmDocumentationEntry e;
- e.Name =
- cmExternalMakefileProjectGenerator::CreateFullGeneratorName(g, name);
- e.Brief = doc;
- v.push_back(std::move(e));
+ for (std::string const& g : eg->GetSupportedGlobalGenerators()) {
+ v.emplace_back(cmDocumentationEntry{
+ cmExternalMakefileProjectGenerator::CreateFullGeneratorName(g, name),
+ doc });
}
}
}
@@ -2874,7 +3009,7 @@ void cmake::PrintGeneratorList()
cmDocumentation doc;
auto generators = this->GetGeneratorsDocumentation();
doc.AppendSection("Generators", generators);
- std::cerr << "\n";
+ std::cerr << '\n';
doc.PrintDocumentation(cmDocumentation::ListGenerators, std::cerr);
#endif
}
@@ -2926,7 +3061,7 @@ int cmake::CheckBuildSystem()
if (verbose) {
std::ostringstream msg;
msg << "Re-run cmake missing file: " << this->CheckBuildSystemArgument
- << "\n";
+ << '\n';
cmSystemTools::Stdout(msg.str());
}
return 1;
@@ -2946,7 +3081,7 @@ int cmake::CheckBuildSystem()
if (verbose) {
std::ostringstream msg;
msg << "Re-run cmake error reading : " << this->CheckBuildSystemArgument
- << "\n";
+ << '\n';
cmSystemTools::Stdout(msg.str());
}
// There was an error reading the file. Just rerun.
@@ -2977,9 +3112,8 @@ int cmake::CheckBuildSystem()
for (std::string const& p : products) {
if (!(cmSystemTools::FileExists(p) || cmSystemTools::FileIsSymlink(p))) {
if (verbose) {
- std::ostringstream msg;
- msg << "Re-run cmake, missing byproduct: " << p << "\n";
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(
+ cmStrCat("Re-run cmake, missing byproduct: ", p, '\n'));
}
return 1;
}
@@ -3044,7 +3178,7 @@ int cmake::CheckBuildSystem()
if (verbose) {
std::ostringstream msg;
msg << "Re-run cmake file: " << out_oldest
- << " older than: " << dep_newest << "\n";
+ << " older than: " << dep_newest << '\n';
cmSystemTools::Stdout(msg.str());
}
return 1;
@@ -3220,7 +3354,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
// permissions are questionable or some other process has deleted the
// directory
std::cerr << "Failed to change to directory " << destPath << " : "
- << std::strerror(workdir.GetLastResult()) << std::endl;
+ << std::strerror(workdir.GetLastResult()) << '\n';
return 1;
}
std::vector<std::string> args2;
@@ -3257,96 +3391,6 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
return 0;
}
-static bool cmakeCheckStampFile(const std::string& stampName)
-{
- // The stamp file does not exist. Use the stamp dependencies to
- // determine whether it is really out of date. This works in
- // conjunction with cmLocalVisualStudio7Generator to avoid
- // repeatedly re-running CMake when the user rebuilds the entire
- // solution.
- std::string stampDepends = cmStrCat(stampName, ".depend");
-#if defined(_WIN32) || defined(__CYGWIN__)
- cmsys::ifstream fin(stampDepends.c_str(), std::ios::in | std::ios::binary);
-#else
- cmsys::ifstream fin(stampDepends.c_str());
-#endif
- if (!fin) {
- // The stamp dependencies file cannot be read. Just assume the
- // build system is really out of date.
- std::cout << "CMake is re-running because " << stampName
- << " dependency file is missing.\n";
- return false;
- }
-
- // Compare the stamp dependencies against the dependency file itself.
- {
- cmFileTimeCache ftc;
- std::string dep;
- while (cmSystemTools::GetLineFromStream(fin, dep)) {
- int result;
- if (!dep.empty() && dep[0] != '#' &&
- (!ftc.Compare(stampDepends, dep, &result) || result < 0)) {
- // The stamp depends file is older than this dependency. The
- // build system is really out of date.
- std::cout << "CMake is re-running because " << stampName
- << " is out-of-date.\n";
- std::cout << " the file '" << dep << "'\n";
- std::cout << " is newer than '" << stampDepends << "'\n";
- std::cout << " result='" << result << "'\n";
- return false;
- }
- }
- }
-
- // The build system is up to date. The stamp file has been removed
- // by the VS IDE due to a "rebuild" request. Restore it atomically.
- std::ostringstream stampTempStream;
- stampTempStream << stampName << ".tmp" << cmSystemTools::RandomSeed();
- std::string stampTemp = stampTempStream.str();
- {
- // TODO: Teach cmGeneratedFileStream to use a random temp file (with
- // multiple tries in unlikely case of conflict) and use that here.
- cmsys::ofstream stamp(stampTemp.c_str());
- stamp << "# CMake generation timestamp file for this directory.\n";
- }
- std::string err;
- if (cmSystemTools::RenameFile(stampTemp, stampName,
- cmSystemTools::Replace::Yes, &err) ==
- cmSystemTools::RenameResult::Success) {
- // CMake does not need to re-run because the stamp file is up-to-date.
- return true;
- }
- cmSystemTools::RemoveFile(stampTemp);
- cmSystemTools::Error(
- cmStrCat("Cannot restore timestamp \"", stampName, "\": ", err));
- return false;
-}
-
-static bool cmakeCheckStampList(const std::string& stampList)
-{
- // If the stamp list does not exist CMake must rerun to generate it.
- if (!cmSystemTools::FileExists(stampList)) {
- std::cout << "CMake is re-running because generate.stamp.list "
- << "is missing.\n";
- return false;
- }
- cmsys::ifstream fin(stampList.c_str());
- if (!fin) {
- std::cout << "CMake is re-running because generate.stamp.list "
- << "could not be read.\n";
- return false;
- }
-
- // Check each stamp.
- std::string stampName;
- while (cmSystemTools::GetLineFromStream(fin, stampName)) {
- if (!cmakeCheckStampFile(stampName)) {
- return false;
- }
- }
- return true;
-}
-
void cmake::IssueMessage(MessageType t, std::string const& text,
cmListFileBacktrace const& backtrace) const
{
diff --git a/Source/cmake.h b/Source/cmake.h
index 3183577..10db87d 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -18,6 +18,7 @@
#include <cm/string_view>
#include <cmext/string_view>
+#include "cmDocumentationEntry.h"
#include "cmGeneratedFileStream.h"
#include "cmInstalledFile.h"
#include "cmListFileCache.h"
@@ -33,21 +34,19 @@
# include <cm3p/json/value.h>
# include "cmCMakePresetsGraph.h"
+# include "cmMakefileProfilingData.h"
#endif
+class cmConfigureLog;
class cmExternalMakefileProjectGeneratorFactory;
class cmFileAPI;
class cmFileTimeCache;
class cmGlobalGenerator;
class cmGlobalGeneratorFactory;
class cmMakefile;
-#if !defined(CMAKE_BOOTSTRAP)
-class cmMakefileProfilingData;
-#endif
class cmMessenger;
class cmVariableWatch;
struct cmBuildOptions;
-struct cmDocumentationEntry;
/** \brief Represents a cmake invocation.
*
@@ -513,10 +512,23 @@ public:
{
return this->TraceOnlyThisSources;
}
- cmGeneratedFileStream& GetTraceFile() { return this->TraceFile; }
+ cmGeneratedFileStream& GetTraceFile()
+ {
+ if (this->TraceRedirect) {
+ return this->TraceRedirect->GetTraceFile();
+ }
+ return this->TraceFile;
+ }
void SetTraceFile(std::string const& file);
void PrintTraceFormatVersion();
+#ifndef CMAKE_BOOTSTRAP
+ cmConfigureLog* GetConfigureLog() const { return this->ConfigureLog.get(); }
+#endif
+
+ //! Use trace from another ::cmake instance.
+ void SetTraceRedirect(cmake* other);
+
bool GetWarnUninitialized() const { return this->WarnUninitialized; }
void SetWarnUninitialized(bool b) { this->WarnUninitialized = b; }
bool GetWarnUnusedCli() const { return this->WarnUnusedCli; }
@@ -630,6 +642,24 @@ public:
#if !defined(CMAKE_BOOTSTRAP)
cmMakefileProfilingData& GetProfilingOutput();
bool IsProfilingEnabled() const;
+
+ cm::optional<cmMakefileProfilingData::RAII> CreateProfilingEntry(
+ const std::string& category, const std::string& name)
+ {
+ return this->CreateProfilingEntry(
+ category, name, []() -> cm::nullopt_t { return cm::nullopt; });
+ }
+
+ template <typename ArgsFunc>
+ cm::optional<cmMakefileProfilingData::RAII> CreateProfilingEntry(
+ const std::string& category, const std::string& name, ArgsFunc&& argsFunc)
+ {
+ if (this->IsProfilingEnabled()) {
+ return cm::make_optional<cmMakefileProfilingData::RAII>(
+ this->GetProfilingOutput(), category, name, argsFunc());
+ }
+ return cm::nullopt;
+ }
#endif
protected:
@@ -688,6 +718,10 @@ private:
bool TraceExpand = false;
TraceFormat TraceFormatVar = TRACE_HUMAN;
cmGeneratedFileStream TraceFile;
+ cmake* TraceRedirect = nullptr;
+#ifndef CMAKE_BOOTSTRAP
+ std::unique_ptr<cmConfigureLog> ConfigureLog;
+#endif
bool WarnUninitialized = false;
bool WarnUnusedCli = true;
bool CheckSystemVars = false;
@@ -767,37 +801,10 @@ private:
#if !defined(CMAKE_BOOTSTRAP)
std::unique_ptr<cmMakefileProfilingData> ProfilingOutput;
#endif
-};
-#define CMAKE_STANDARD_OPTIONS_TABLE \
- { "-S <path-to-source>", "Explicitly specify a source directory." }, \
- { "-B <path-to-build>", "Explicitly specify a build directory." }, \
- { "-C <initial-cache>", "Pre-load a script to populate the cache." }, \
- { "-D <var>[:<type>]=<value>", "Create or update a cmake cache entry." }, \
- { "-U <globbing_expr>", "Remove matching entries from CMake cache." }, \
- { "-G <generator-name>", "Specify a build system generator." }, \
- { "-T <toolset-name>", \
- "Specify toolset name if supported by generator." }, \
- { "-A <platform-name>", \
- "Specify platform name if supported by generator." }, \
- { "--toolchain <file>", \
- "Specify toolchain file [CMAKE_TOOLCHAIN_FILE]." }, \
- { "--install-prefix <directory>", \
- "Specify install directory [CMAKE_INSTALL_PREFIX]." }, \
- { "-Wdev", "Enable developer warnings." }, \
- { "-Wno-dev", "Suppress developer warnings." }, \
- { "-Werror=dev", "Make developer warnings errors." }, \
- { "-Wno-error=dev", "Make developer warnings not errors." }, \
- { "-Wdeprecated", "Enable deprecation warnings." }, \
- { "-Wno-deprecated", "Suppress deprecation warnings." }, \
- { "-Werror=deprecated", \
- "Make deprecated macro and function warnings " \
- "errors." }, \
- { \
- "-Wno-error=deprecated", \
- "Make deprecated macro and function warnings " \
- "not errors." \
- }
+public:
+ static cmDocumentationEntry CMAKE_STANDARD_OPTIONS_TABLE[18];
+};
#define FOR_EACH_C90_FEATURE(F) F(c_function_prototypes)
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 723932e..1e02412 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -24,7 +24,7 @@
#include "cmBuildOptions.h"
#include "cmCommandLineArgument.h"
#include "cmConsoleBuf.h"
-#include "cmDocumentationEntry.h" // IWYU pragma: keep
+#include "cmDocumentationEntry.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageMetadata.h"
@@ -46,30 +46,28 @@
namespace {
#ifndef CMAKE_BOOTSTRAP
-const char* cmDocumentationName[][2] = {
- { nullptr, " cmake - Cross-Platform Makefile Generator." },
- { nullptr, nullptr }
+const cmDocumentationEntry cmDocumentationName = {
+ {},
+ " cmake - Cross-Platform Makefile Generator."
};
-const char* cmDocumentationUsage[][2] = {
- { nullptr,
+const cmDocumentationEntry cmDocumentationUsage[2] = {
+ { {},
" cmake [options] <path-to-source>\n"
" cmake [options] <path-to-existing-build>\n"
" cmake [options] -S <path-to-source> -B <path-to-build>" },
- { nullptr,
+ { {},
"Specify a source directory to (re-)generate a build system for "
"it in the current working directory. Specify an existing build "
- "directory to re-generate its build system." },
- { nullptr, nullptr }
+ "directory to re-generate its build system." }
};
-const char* cmDocumentationUsageNote[][2] = {
- { nullptr, "Run 'cmake --help' for more information." },
- { nullptr, nullptr }
+const cmDocumentationEntry cmDocumentationUsageNote = {
+ {},
+ "Run 'cmake --help' for more information."
};
-const char* cmDocumentationOptions[][2] = {
- CMAKE_STANDARD_OPTIONS_TABLE,
+const cmDocumentationEntry cmDocumentationOptions[31] = {
{ "--preset <preset>,--preset=<preset>", "Specify a configure preset." },
{ "--list-presets[=<type>]", "List available presets." },
{ "-E", "CMake command mode." },
@@ -113,15 +111,12 @@ const char* cmDocumentationOptions[][2] = {
{ "--compile-no-warning-as-error",
"Ignore COMPILE_WARNING_AS_ERROR property and "
"CMAKE_COMPILE_WARNING_AS_ERROR variable." },
-# if !defined(CMAKE_BOOTSTRAP)
{ "--profiling-format=<fmt>",
"Output data for profiling CMake scripts. Supported formats: "
"google-trace" },
{ "--profiling-output=<file>",
"Select an output path for the profiling data enabled through "
- "--profiling-format." },
-# endif
- { nullptr, nullptr }
+ "--profiling-format." }
};
#endif
@@ -208,7 +203,7 @@ int do_cmake(int ac, char const* const* av)
doc.addCMakeStandardDocSections();
if (doc.CheckOptions(ac, av, "--")) {
// Construct and print requested documentation.
- cmake hcm(cmake::RoleInternal, cmState::Unknown);
+ cmake hcm(cmake::RoleInternal, cmState::Help);
hcm.SetHomeDirectory("");
hcm.SetHomeOutputDirectory("");
hcm.AddCMakePaths();
@@ -228,8 +223,9 @@ int do_cmake(int ac, char const* const* av)
}
doc.AppendSection("Generators", generators);
doc.PrependSection("Options", cmDocumentationOptions);
+ doc.PrependSection("Options", cmake::CMAKE_STANDARD_OPTIONS_TABLE);
- return doc.PrintRequestedDocumentation(std::cout) ? 0 : 1;
+ return !doc.PrintRequestedDocumentation(std::cout);
}
#else
if (ac == 1) {
@@ -315,6 +311,11 @@ int do_cmake(int ac, char const* const* av)
}
return 1; // failed to parse
}
+ // Only in script mode do we stop parsing instead
+ // of preferring the last mode flag provided
+ if (arg == "--" && workingMode == cmake::SCRIPT_MODE) {
+ break;
+ }
}
if (!matched) {
parsedArgs.emplace_back(av[i]);
@@ -522,25 +523,8 @@ int do_build(int ac, char const* const* av)
if (ac >= 3) {
std::vector<std::string> inputArgs;
- bool hasPreset = false;
- for (int i = 2; i < ac; ++i) {
- if (strcmp(av[i], "--list-presets") == 0 ||
- cmHasLiteralPrefix(av[i], "--preset=") ||
- strcmp(av[i], "--preset") == 0) {
- hasPreset = true;
- break;
- }
- }
-
- if (hasPreset) {
- inputArgs.reserve(ac - 2);
- cm::append(inputArgs, av + 2, av + ac);
- } else {
- dir = cmSystemTools::CollapseFullPath(av[2]);
-
- inputArgs.reserve(ac - 3);
- cm::append(inputArgs, av + 3, av + ac);
- }
+ inputArgs.reserve(ac - 2);
+ cm::append(inputArgs, av + 2, av + ac);
decltype(inputArgs.size()) i = 0;
for (; i < inputArgs.size() && !nativeOptionsPassed; ++i) {
@@ -555,6 +539,11 @@ int do_build(int ac, char const* const* av)
break;
}
}
+ if (!matched && i == 0) {
+ dir = cmSystemTools::CollapseFullPath(arg);
+ matched = true;
+ parsed = true;
+ }
if (!(matched && parsed)) {
dir.clear();
if (!matched) {
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 67394f9..4303f96 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -2,11 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmcmd.h"
+#include <functional>
+
+#include <cm/optional>
#include <cmext/algorithm>
#include <cm3p/uv.h>
#include <fcntl.h>
+#include "cmCommandLineArgument.h"
#include "cmConsoleBuf.h"
#include "cmDuration.h"
#include "cmGlobalGenerator.h"
@@ -363,6 +367,12 @@ int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
std::vector<std::string> tidy_cmd = cmExpandedList(runCmd, true);
tidy_cmd.push_back(sourceFile);
+ for (auto const& arg : tidy_cmd) {
+ if (cmHasLiteralPrefix(arg, "--export-fixes=")) {
+ cmSystemTools::RemoveFile(arg.substr(cmStrLen("--export-fixes=")));
+ }
+ }
+
// clang-tidy supports working out the compile commands from a
// compile_commands.json file in a directory given by a "-p" option, or by
// passing the compiler command line arguments after --. When the latter
@@ -640,20 +650,59 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
if (args.size() > 1) {
// Copy file
if (args[1] == "copy" && args.size() > 3) {
+ using CommandArgument =
+ cmCommandLineArgument<bool(const std::string& value)>;
+
+ cm::optional<std::string> targetArg;
+ std::vector<CommandArgument> argParsers{
+ { "-t", CommandArgument::Values::One,
+ CommandArgument::setToValue(targetArg) },
+ };
+
+ std::vector<std::string> files;
+ for (decltype(args.size()) i = 2; i < args.size(); i++) {
+ const std::string& arg = args[i];
+ bool matched = false;
+ for (auto const& m : argParsers) {
+ if (m.matches(arg)) {
+ matched = true;
+ if (m.parse(arg, i, args)) {
+ break;
+ }
+ return 1; // failed to parse
+ }
+ }
+ if (!matched) {
+ files.push_back(arg);
+ }
+ }
+
// If multiple source files specified,
// then destination must be directory
- if ((args.size() > 4) &&
- (!cmSystemTools::FileIsDirectory(args.back()))) {
- std::cerr << "Error: Target (for copy command) \"" << args.back()
+ if (files.size() > 2 && !targetArg) {
+ targetArg = files.back();
+ files.pop_back();
+ }
+ if (targetArg && (!cmSystemTools::FileIsDirectory(*targetArg))) {
+ std::cerr << "Error: Target (for copy command) \"" << *targetArg
<< "\" is not a directory.\n";
return 1;
}
+ if (!targetArg) {
+ if (files.size() < 2) {
+ std::cerr
+ << "Error: No files or target specified (for copy command).\n";
+ return 1;
+ }
+ targetArg = files.back();
+ files.pop_back();
+ }
// If error occurs we want to continue copying next files.
bool return_value = false;
- for (auto const& arg : cmMakeRange(args).advance(2).retreat(1)) {
- if (!cmsys::SystemTools::CopyFileAlways(arg, args.back())) {
- std::cerr << "Error copying file \"" << arg << "\" to \""
- << args.back() << "\".\n";
+ for (auto const& file : files) {
+ if (!cmsys::SystemTools::CopyFileAlways(file, *targetArg)) {
+ std::cerr << "Error copying file \"" << file << "\" to \""
+ << *targetArg << "\".\n";
return_value = true;
}
}
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index 363f473..fa38a65 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -11,21 +11,21 @@
#include "cmCTest.h"
#include "cmConsoleBuf.h"
#include "cmDocumentation.h"
+#include "cmDocumentationEntry.h"
#include "cmSystemTools.h"
#include "CTest/cmCTestLaunch.h"
#include "CTest/cmCTestScriptHandler.h"
-static const char* cmDocumentationName[][2] = {
- { nullptr, " ctest - Testing driver provided by CMake." },
- { nullptr, nullptr }
+namespace {
+const cmDocumentationEntry cmDocumentationName = {
+ {},
+ " ctest - Testing driver provided by CMake."
};
-static const char* cmDocumentationUsage[][2] = { { nullptr,
- " ctest [options]" },
- { nullptr, nullptr } };
+const cmDocumentationEntry cmDocumentationUsage = { {}, " ctest [options]" };
-static const char* cmDocumentationOptions[][2] = {
+const cmDocumentationEntry cmDocumentationOptions[74] = {
{ "--preset <preset>, --preset=<preset>",
"Read arguments from a test preset." },
{ "--list-presets", "List available test presets." },
@@ -155,9 +155,9 @@ static const char* cmDocumentationOptions[][2] = {
{ "--no-compress-output", "Do not compress test output when submitting." },
{ "--print-labels", "Print all available test labels." },
{ "--no-tests=<[error|ignore]>",
- "Regard no tests found either as 'error' or 'ignore' it." },
- { nullptr, nullptr }
+ "Regard no tests found either as 'error' or 'ignore' it." }
};
+} // anonymous namespace
// this is a test driver program for cmCTest.
int main(int argc, char const* const* argv)
@@ -186,8 +186,7 @@ int main(int argc, char const* const* argv)
if (cmSystemTools::GetCurrentWorkingDirectory().empty()) {
cmCTestLog(&inst, ERROR_MESSAGE,
- "Current working directory cannot be established."
- << std::endl);
+ "Current working directory cannot be established.\n");
return 1;
}
@@ -199,10 +198,9 @@ int main(int argc, char const* const* argv)
cmSystemTools::FileExists("DartTestfile.txt"))) {
if (argc == 1) {
cmCTestLog(&inst, ERROR_MESSAGE,
- "*********************************"
- << std::endl
- << "No test configuration file found!" << std::endl
- << "*********************************" << std::endl);
+ "*********************************\n"
+ "No test configuration file found!\n"
+ "*********************************\n");
}
cmDocumentation doc;
doc.addCTestStandardDocSections();
@@ -216,7 +214,7 @@ int main(int argc, char const* const* argv)
doc.SetSection("Name", cmDocumentationName);
doc.SetSection("Usage", cmDocumentationUsage);
doc.PrependSection("Options", cmDocumentationOptions);
- return doc.PrintRequestedDocumentation(std::cout) ? 0 : 1;
+ return !doc.PrintRequestedDocumentation(std::cout);
}
}
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index 45a9e6f..b25b258 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -2011,6 +2011,14 @@ static int kwsysProcessGetTimeoutTime(kwsysProcess* cp,
return 0;
}
+#if defined(__clang__) && defined(__has_warning)
+# if __has_warning("-Wshorten-64-to-32")
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wshorten-64-to-32"
+# define KWSYSPE_CLANG_DIAG_WSHORTEN
+# endif
+#endif
+
/* Get the length of time before the given timeout time arrives.
Returns 1 if the time has already arrived, and 0 otherwise. */
static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
@@ -2061,6 +2069,11 @@ static kwsysProcessTime kwsysProcessTimeGetCurrent(void)
return current;
}
+#if defined(KWSYSPE_CLANG_DIAG_WSHORTEN)
+# undef KWSYSPE_CLANG_DIAG_WSHORTEN
+# pragma clang diagnostic pop
+#endif
+
static double kwsysProcessTimeToDouble(kwsysProcessTime t)
{
return (double)t.tv_sec + (double)(t.tv_usec) * 0.000001;
diff --git a/Source/kwsys/Status.hxx.in b/Source/kwsys/Status.hxx.in
index 16efaef..7cef029 100644
--- a/Source/kwsys/Status.hxx.in
+++ b/Source/kwsys/Status.hxx.in
@@ -7,6 +7,16 @@
#include <string>
+/*
+ * Detect a symbol collision with the name of this class. X11 headers use
+ * `#define Status int` instead of using `typedef` which poisons any other
+ * usage of this name.
+ */
+#if defined(Status) && defined(_X11_XLIB_H_)
+# error \
+ "Status.hxx must be included *before* any X11 headers to avoid a collision with the `Status` define that is made in its API."
+#endif
+
namespace @KWSYS_NAMESPACE@ {
/** \class Status
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index e6cc48f..20e2edb 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -482,7 +482,7 @@ protected:
unsigned int); // For windows
// For Linux and Cygwin, /proc/cpuinfo formats are slightly different
- bool RetreiveInformationFromCpuInfoFile();
+ bool RetrieveInformationFromCpuInfoFile();
std::string ExtractValueFromCpuInfoFile(std::string buffer, const char* word,
size_t init = 0);
@@ -1520,7 +1520,7 @@ void SystemInformationImplementation::RunCPUCheck()
#elif defined(__hpux)
this->QueryHPUXProcessor();
#elif defined(__linux) || defined(__CYGWIN__)
- this->RetreiveInformationFromCpuInfoFile();
+ this->RetrieveInformationFromCpuInfoFile();
#else
this->QueryProcessor();
#endif
@@ -3435,7 +3435,7 @@ std::string SystemInformationImplementation::ExtractValueFromCpuInfoFile(
}
/** Query for the cpu status */
-bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
+bool SystemInformationImplementation::RetrieveInformationFromCpuInfoFile()
{
this->NumberOfLogicalCPU = 0;
this->NumberOfPhysicalCPU = 0;
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index a20901c..a3ab51a 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -36,6 +36,7 @@
#ifdef _WIN32
# include <cwchar>
+# include <unordered_map>
#endif
// Work-around CMake dependency scanning limitation. This must
@@ -506,16 +507,39 @@ public:
};
#ifdef _WIN32
-struct SystemToolsPathCaseCmp
+# if defined(_WIN64)
+static constexpr size_t FNV_OFFSET_BASIS = 14695981039346656037ULL;
+static constexpr size_t FNV_PRIME = 1099511628211ULL;
+# else
+static constexpr size_t FNV_OFFSET_BASIS = 2166136261U;
+static constexpr size_t FNV_PRIME = 16777619U;
+# endif
+
+// Case insensitive Fnv1a hash
+struct SystemToolsPathCaseHash
+{
+ size_t operator()(std::string const& path) const
+ {
+ size_t hash = FNV_OFFSET_BASIS;
+ for (auto c : path) {
+ hash ^= static_cast<size_t>(std::tolower(c));
+ hash *= FNV_PRIME;
+ }
+
+ return hash;
+ }
+};
+
+struct SystemToolsPathCaseEqual
{
bool operator()(std::string const& l, std::string const& r) const
{
# ifdef _MSC_VER
- return _stricmp(l.c_str(), r.c_str()) < 0;
+ return _stricmp(l.c_str(), r.c_str()) == 0;
# elif defined(__GNUC__)
- return strcasecmp(l.c_str(), r.c_str()) < 0;
+ return strcasecmp(l.c_str(), r.c_str()) == 0;
# else
- return SystemTools::Strucmp(l.c_str(), r.c_str()) < 0;
+ return SystemTools::Strucmp(l.c_str(), r.c_str()) == 0;
# endif
}
};
@@ -540,8 +564,12 @@ public:
bool const cache);
static std::string GetActualCaseForPathCached(std::string const& path);
static const char* GetEnvBuffered(const char* key);
- std::map<std::string, std::string, SystemToolsPathCaseCmp> FindFileMap;
- std::map<std::string, std::string, SystemToolsPathCaseCmp> PathCaseMap;
+ std::unordered_map<std::string, std::string, SystemToolsPathCaseHash,
+ SystemToolsPathCaseEqual>
+ FindFileMap;
+ std::unordered_map<std::string, std::string, SystemToolsPathCaseHash,
+ SystemToolsPathCaseEqual>
+ PathCaseMap;
std::map<std::string, std::string> EnvMap;
#endif
#ifdef __CYGWIN__
@@ -2262,8 +2290,8 @@ static std::string FileInDir(const std::string& source, const std::string& dir)
return new_destination + '/' + SystemTools::GetFilenameName(source);
}
-Status SystemTools::CopyFileIfDifferent(std::string const& source,
- std::string const& destination)
+SystemTools::CopyStatus SystemTools::CopyFileIfDifferent(
+ std::string const& source, std::string const& destination)
{
// special check for a destination that is a directory
// FilesDiffer does not handle file to directory compare
@@ -2280,7 +2308,7 @@ Status SystemTools::CopyFileIfDifferent(std::string const& source,
}
}
// at this point the files must be the same so return true
- return Status::Success();
+ return CopyStatus{ Status::Success(), CopyStatus::NoPath };
}
#define KWSYS_ST_BUFFER 4096
@@ -2406,13 +2434,13 @@ bool SystemTools::TextFilesDiffer(const std::string& path1,
return false;
}
-Status SystemTools::CopyFileContentBlockwise(std::string const& source,
- std::string const& destination)
+SystemTools::CopyStatus SystemTools::CopyFileContentBlockwise(
+ std::string const& source, std::string const& destination)
{
// Open files
kwsys::ifstream fin(source.c_str(), std::ios::in | std::ios::binary);
if (!fin) {
- return Status::POSIX_errno();
+ return CopyStatus{ Status::POSIX_errno(), CopyStatus::SourcePath };
}
// try and remove the destination file so that read only destination files
@@ -2424,7 +2452,7 @@ Status SystemTools::CopyFileContentBlockwise(std::string const& source,
kwsys::ofstream fout(destination.c_str(),
std::ios::out | std::ios::trunc | std::ios::binary);
if (!fout) {
- return Status::POSIX_errno();
+ return CopyStatus{ Status::POSIX_errno(), CopyStatus::DestPath };
}
// This copy loop is very sensitive on certain platforms with
@@ -2453,10 +2481,10 @@ Status SystemTools::CopyFileContentBlockwise(std::string const& source,
fout.close();
if (!fout) {
- return Status::POSIX_errno();
+ return CopyStatus{ Status::POSIX_errno(), CopyStatus::DestPath };
}
- return Status::Success();
+ return CopyStatus{ Status::Success(), CopyStatus::NoPath };
}
/**
@@ -2471,13 +2499,13 @@ Status SystemTools::CopyFileContentBlockwise(std::string const& source,
* - The underlying filesystem does not support file cloning
* - An unspecified error occurred
*/
-Status SystemTools::CloneFileContent(std::string const& source,
- std::string const& destination)
+SystemTools::CopyStatus SystemTools::CloneFileContent(
+ std::string const& source, std::string const& destination)
{
#if defined(__linux) && defined(FICLONE)
int in = open(source.c_str(), O_RDONLY);
if (in < 0) {
- return Status::POSIX_errno();
+ return CopyStatus{ Status::POSIX_errno(), CopyStatus::SourcePath };
}
SystemTools::RemoveFile(destination);
@@ -2485,14 +2513,14 @@ Status SystemTools::CloneFileContent(std::string const& source,
int out =
open(destination.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (out < 0) {
- Status status = Status::POSIX_errno();
+ CopyStatus status{ Status::POSIX_errno(), CopyStatus::DestPath };
close(in);
return status;
}
- Status status = Status::Success();
+ CopyStatus status{ Status::Success(), CopyStatus::NoPath };
if (ioctl(out, FICLONE, in) < 0) {
- status = Status::POSIX_errno();
+ status = CopyStatus{ Status::POSIX_errno(), CopyStatus::NoPath };
}
close(in);
close(out);
@@ -2504,40 +2532,41 @@ Status SystemTools::CloneFileContent(std::string const& source,
// be updated by `copy_file_if_different` and `copy_file`.
if (copyfile(source.c_str(), destination.c_str(), nullptr,
COPYFILE_METADATA | COPYFILE_CLONE) < 0) {
- return Status::POSIX_errno();
+ return CopyStatus{ Status::POSIX_errno(), CopyStatus::NoPath };
}
# if KWSYS_CXX_HAS_UTIMENSAT
// utimensat is only available on newer Unixes and macOS 10.13+
if (utimensat(AT_FDCWD, destination.c_str(), nullptr, 0) < 0) {
- return Status::POSIX_errno();
+ return CopyStatus{ Status::POSIX_errno(), CopyStatus::DestPath };
}
# else
// fall back to utimes
if (utimes(destination.c_str(), nullptr) < 0) {
- return Status::POSIX_errno();
+ return CopyStatus{ Status::POSIX_errno(), CopyStatus::DestPath };
}
# endif
- return Status::Success();
+ return CopyStatus{ Status::Success(), CopyStatus::NoPath };
#else
(void)source;
(void)destination;
- return Status::POSIX(ENOSYS);
+ return CopyStatus{ Status::POSIX(ENOSYS), CopyStatus::NoPath };
#endif
}
/**
* Copy a file named by "source" to the file named by "destination".
*/
-Status SystemTools::CopyFileAlways(std::string const& source,
- std::string const& destination)
+SystemTools::CopyStatus SystemTools::CopyFileAlways(
+ std::string const& source, std::string const& destination)
{
- Status status;
+ CopyStatus status;
mode_t perm = 0;
Status perms = SystemTools::GetPermissions(source, perm);
std::string real_destination = destination;
if (SystemTools::FileIsDirectory(source)) {
- status = SystemTools::MakeDirectory(destination);
+ status = CopyStatus{ SystemTools::MakeDirectory(destination),
+ CopyStatus::DestPath };
if (!status.IsSuccess()) {
return status;
}
@@ -2562,7 +2591,8 @@ Status SystemTools::CopyFileAlways(std::string const& source,
// Create destination directory
if (!destination_dir.empty()) {
- status = SystemTools::MakeDirectory(destination_dir);
+ status = CopyStatus{ SystemTools::MakeDirectory(destination_dir),
+ CopyStatus::DestPath };
if (!status.IsSuccess()) {
return status;
}
@@ -2578,13 +2608,15 @@ Status SystemTools::CopyFileAlways(std::string const& source,
}
}
if (perms) {
- status = SystemTools::SetPermissions(real_destination, perm);
+ status = CopyStatus{ SystemTools::SetPermissions(real_destination, perm),
+ CopyStatus::DestPath };
}
return status;
}
-Status SystemTools::CopyAFile(std::string const& source,
- std::string const& destination, bool always)
+SystemTools::CopyStatus SystemTools::CopyAFile(std::string const& source,
+ std::string const& destination,
+ bool always)
{
if (always) {
return SystemTools::CopyFileAlways(source, destination);
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index acce015..56b65fd 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -566,11 +566,34 @@ public:
const mode_t* mode = nullptr);
/**
+ * Represent the result of a file copy operation.
+ * This is the result 'Status' and, if the operation failed,
+ * an indication of whether the error occurred on the source
+ * or destination path.
+ */
+ struct CopyStatus : public Status
+ {
+ enum WhichPath
+ {
+ NoPath,
+ SourcePath,
+ DestPath,
+ };
+ CopyStatus() = default;
+ CopyStatus(Status s, WhichPath p)
+ : Status(s)
+ , Path(p)
+ {
+ }
+ WhichPath Path = NoPath;
+ };
+
+ /**
* Copy the source file to the destination file only
* if the two files differ.
*/
- static Status CopyFileIfDifferent(std::string const& source,
- std::string const& destination);
+ static CopyStatus CopyFileIfDifferent(std::string const& source,
+ std::string const& destination);
/**
* Compare the contents of two files. Return true if different
@@ -588,13 +611,13 @@ public:
/**
* Blockwise copy source to destination file
*/
- static Status CopyFileContentBlockwise(std::string const& source,
- std::string const& destination);
+ static CopyStatus CopyFileContentBlockwise(std::string const& source,
+ std::string const& destination);
/**
* Clone the source file to the destination file
*/
- static Status CloneFileContent(std::string const& source,
- std::string const& destination);
+ static CopyStatus CloneFileContent(std::string const& source,
+ std::string const& destination);
/**
* Return true if the two files are the same file
@@ -604,16 +627,17 @@ public:
/**
* Copy a file.
*/
- static Status CopyFileAlways(std::string const& source,
- std::string const& destination);
+ static CopyStatus CopyFileAlways(std::string const& source,
+ std::string const& destination);
/**
* Copy a file. If the "always" argument is true the file is always
* copied. If it is false, the file is copied only if it is new or
* has changed.
*/
- static Status CopyAFile(std::string const& source,
- std::string const& destination, bool always = true);
+ static CopyStatus CopyAFile(std::string const& source,
+ std::string const& destination,
+ bool always = true);
/**
* Copy content directory to another directory with all files and